util/selinux: add setfilecon method

This is basically a re-implementation of `setfilecon(3)` minus the
translation of human readable context to raw context. Add test for
the new function.
This commit is contained in:
Christian Kellner 2022-03-18 17:18:16 +01:00 committed by Achilleas Koutsou
parent 5735357b74
commit 75df59bace
2 changed files with 46 additions and 0 deletions

View file

@ -1,5 +1,6 @@
"""SELinux utility functions"""
import errno
import os
import subprocess
@ -57,3 +58,27 @@ def getfilecon(path: str) -> str:
label = os.getxattr(path, XATTR_NAME_SELINUX,
follow_symlinks=False)
return label.decode().strip('\n\0')
def setfilecon(path: str, context: str) -> None:
"""
Set the security context associated with `path`
Like `setfilecon`(3), but does not attempt to translate
the context via `selinux_trans_to_raw_context`.
"""
try:
os.setxattr(path, XATTR_NAME_SELINUX,
context.encode(),
follow_symlinks=True)
except OSError as err:
# in case we get a not-supported error, check if
# the context we want to set is already set and
# ignore the error in that case. This follows the
# behavior of `setfilecon(3)`.
if err.errno == errno.ENOTSUP:
have = getfilecon(path)
if have == context:
return
raise

View file

@ -2,7 +2,9 @@
# Tests for the 'osbuild.util.selinux' module.
#
import errno
import io
from unittest import mock
from osbuild.util import selinux
@ -37,3 +39,22 @@ def test_selinux_config():
policy = selinux.config_get_policy(cfg)
assert policy == 'targeted'
def test_setfilecon():
with mock.patch("os.setxattr") as setxattr:
selinux.setfilecon("/path", "context")
setxattr.assert_called_once_with("/path", selinux.XATTR_NAME_SELINUX,
b"context", follow_symlinks=True)
with mock.patch("os.getxattr") as getxattr:
with mock.patch("os.setxattr") as setxattr:
def raise_error(*_args, **_kwargs):
raise OSError(errno.ENOTSUP, "Not supported")
getxattr.return_value = b"context"
setxattr.side_effect = raise_error
selinux.setfilecon("path", "context")