deploy_chrome: Only set the security context when SELinux is supported.
Also run restorecon even if we're deploying the browser somewhere other
than /opt/google/chrome, but still mounting it there.
BUG=chromium:968155
TEST=deploy_chrome w/ --mount and ran security.SELinuxFilesARC
Change-Id: I8af5a45e7ac5434cddb69843b77c48b6bc8dbcb4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1753104
Commit-Queue: Ben Pastene <bpastene@chromium.org>
Tested-by: Ben Pastene <bpastene@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/cli/deploy.py b/cli/deploy.py
index 0d6cac4..f79f2a3 100644
--- a/cli/deploy.py
+++ b/cli/deploy.py
@@ -815,28 +815,6 @@
logging.notice('%s has been installed.', pkg_name)
-def _HasSELinux(device):
- """Check whether the device has SELinux-enabled.
-
- Args:
- device: A ChromiumOSDevice object.
- """
- try:
- device.CatFile('/sys/fs/selinux/enforce', max_size=None)
- return True
- except remote_access.CatFileError:
- return False
-
-
-def _IsSELinuxEnforced(device):
- """Check whether the device has SELinux-enforced.
-
- Args:
- device: A ChromiumOSDevice object
- """
- return device.CatFile('/sys/fs/selinux/enforce', max_size=None).strip() == '1'
-
-
def _RestoreSELinuxContext(device, pkgpath, root):
"""Restore SELinux context for files in a given pacakge.
@@ -849,7 +827,7 @@
pkgpath: path to tarball
root: Package installation root path.
"""
- enforced = _IsSELinuxEnforced(device)
+ enforced = device.IsSELinuxEnforced()
if enforced:
device.RunCommand(['setenforce', '0'])
pkgroot = os.path.join(device.work_dir, 'packages')
@@ -961,7 +939,7 @@
dlc_deployed = False
for pkg_path in _GetPackagesPaths(pkgs, strip, sysroot):
_Emerge(device, pkg_path, root, extra_args=emerge_args)
- if _HasSELinux(device):
+ if device.IsSELinuxAvailable():
_RestoreSELinuxContext(device, pkg_path, root)
if _DeployDLCImage(device, pkg_path):
dlc_deployed = True
@@ -1170,7 +1148,7 @@
else:
func()
- if _HasSELinux(device):
+ if device.IsSELinuxAvailable():
if sum(x.count('selinux-policy') for x in pkgs):
logging.warning(
'Deploying SELinux policy will not take effect until reboot. '
diff --git a/cli/deploy_unittest.py b/cli/deploy_unittest.py
index 93379fa..b4c9515 100644
--- a/cli/deploy_unittest.py
+++ b/cli/deploy_unittest.py
@@ -38,10 +38,17 @@
self.lsb_release = None
self.cmds = []
self.work_dir = '/testdir/'
+ self.selinux_available = False
def MountRootfsReadWrite(self):
return True
+ def IsSELinuxAvailable(self):
+ return self.selinux_available
+
+ def IsSELinuxEnforced(self):
+ return True
+
def RunCommand(self, cmd, **_kwargs):
self.cmds.append(cmd)
@@ -306,10 +313,6 @@
deploy, '_GetPackagesByCPV', side_effect=self.FakeGetPackagesByCPV)
self.emerge = self.PatchObject(deploy, '_Emerge', return_value=None)
self.unmerge = self.PatchObject(deploy, '_Unmerge', return_value=None)
- self.has_selinux = self.PatchObject(
- deploy, '_HasSELinux', return_value=False)
- self.is_selinux_enforced = self.PatchObject(
- deploy, '_IsSELinuxEnforced', return_value=True)
self.PatchObject(deploy, '_GetDLCInfo', return_value=(None, None))
def testDeployEmerge(self):
@@ -364,7 +367,7 @@
'restorecon', '-i', '-f', '-'],
['setenforce', '1']]
- self.has_selinux.return_value = True
+ self.device.device.selinux_available = True
packages = ['some/foo-1.2.3', _BINPKG, 'some/foobar-2.0']
cpvs = ['some/foo-1.2.3', 'to/bar-1.2.5', 'some/foobar-2.0']
self.package_scanner.return_value = PackageScannerFake(
diff --git a/lib/remote_access.py b/lib/remote_access.py
index 8731eda..c576f0d 100644
--- a/lib/remote_access.py
+++ b/lib/remote_access.py
@@ -756,6 +756,16 @@
capture_output=True)
return re.search(r'Speed: \d+000Mb/s', result.output)
+ def IsSELinuxAvailable(self):
+ """Check whether the device has SELinux compiled in."""
+ return self.IfFileExists('/sys/fs/selinux/enforce')
+
+ def IsSELinuxEnforced(self):
+ """Check whether the device has SELinux-enforced."""
+ if not self.IsSELinuxAvailable():
+ return False
+ return self.CatFile('/sys/fs/selinux/enforce', max_size=None).strip() == '1'
+
def RegisterCleanupCmd(self, cmd, **kwargs):
"""Register a cleanup command to be run on the device in Cleanup().
@@ -886,6 +896,7 @@
def IfFileExists(self, path, **kwargs):
"""Check if the given path exists on the device."""
+ kwargs.setdefault('error_code_ok', True)
result = self.RunCommand(['test -f %s' % path], **kwargs)
return result.returncode == 0
diff --git a/lib/remote_access_unittest.py b/lib/remote_access_unittest.py
index 74cb691..447c5d4 100644
--- a/lib/remote_access_unittest.py
+++ b/lib/remote_access_unittest.py
@@ -306,6 +306,30 @@
self.assertEqual(self.rsh_mock.call_count, 2)
+ def testSELinux(self):
+ """Tests behavior of IsSELinuxAvailable() and IsSELinuxEnforced()."""
+ with remote_access.RemoteDeviceHandler('1.1.1.1') as device:
+ self.rsh_mock.AddCmdResult(
+ partial_mock.ListRegex('test -f'), returncode=0)
+ self.rsh_mock.AddCmdResult(
+ partial_mock.ListRegex('cat /sys/fs/selinux/enforce'),
+ returncode=0, output='1')
+ self.assertEqual(device.IsSELinuxAvailable(), True)
+ self.assertEqual(device.IsSELinuxEnforced(), True)
+
+ self.rsh_mock.AddCmdResult(
+ partial_mock.ListRegex('test -f'), returncode=0)
+ self.rsh_mock.AddCmdResult(
+ partial_mock.ListRegex('cat /sys/fs/selinux/enforce'),
+ returncode=0, output='0')
+ self.assertEqual(device.IsSELinuxAvailable(), True)
+ self.assertEqual(device.IsSELinuxEnforced(), False)
+
+ self.rsh_mock.AddCmdResult(
+ partial_mock.ListRegex('test -f'), returncode=1)
+ self.assertEqual(device.IsSELinuxAvailable(), False)
+ self.assertEqual(device.IsSELinuxEnforced(), False)
+
class ScpTest(cros_test_lib.MockTempDirTestCase):
"""Tests for RemoteAccess.Scp"""
diff --git a/scripts/deploy_chrome.py b/scripts/deploy_chrome.py
index a3566a6..39aa830 100644
--- a/scripts/deploy_chrome.py
+++ b/scripts/deploy_chrome.py
@@ -276,8 +276,11 @@
compress=self._ShouldUseCompression(),
debug_level=logging.INFO,
verbose=self.options.verbose)
- # Set the security context.
- if self.options.target_dir == _CHROME_DIR:
+
+ # Set the security context on the default Chrome dir if that's where it's
+ # getting deployed, and only on SELinux supported devices.
+ if (self.device.IsSELinuxAvailable() and
+ _CHROME_DIR in (self.options.target_dir, self.options.mount_dir)):
self.device.RunCommand(['restorecon', '-R', _CHROME_DIR])
for p in self.copy_paths: