From: Armin Kuster <akuster808@gmail.com>
To: yocto@yoctoproject.org
Subject: [meta-security][PATCH 13/14] runtime qa: moderize ima test
Date: Sun, 26 May 2019 21:56:40 -0700 [thread overview]
Message-ID: <20190527045641.18884-14-akuster808@gmail.com> (raw)
In-Reply-To: <20190527045641.18884-1-akuster808@gmail.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
---
meta-integrity/lib/oeqa/runtime/__init__.py | 0
meta-integrity/lib/oeqa/runtime/cases/ima.py | 129 +++++++++++++++++++
meta-integrity/lib/oeqa/runtime/ima.py | 82 ------------
3 files changed, 129 insertions(+), 82 deletions(-)
delete mode 100644 meta-integrity/lib/oeqa/runtime/__init__.py
create mode 100644 meta-integrity/lib/oeqa/runtime/cases/ima.py
delete mode 100644 meta-integrity/lib/oeqa/runtime/ima.py
diff --git a/meta-integrity/lib/oeqa/runtime/__init__.py b/meta-integrity/lib/oeqa/runtime/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/meta-integrity/lib/oeqa/runtime/cases/ima.py b/meta-integrity/lib/oeqa/runtime/cases/ima.py
new file mode 100644
index 0000000..0c8617a
--- /dev/null
+++ b/meta-integrity/lib/oeqa/runtime/cases/ima.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+#
+# Authors: Cristina Moraru <cristina.moraru@intel.com>
+# Alexandru Cornea <alexandru.cornea@intel.com>
+
+import string
+from time import sleep
+from oeqa.runtime.case import OERuntimeTestCase
+from oeqa.core.decorator.depends import OETestDepends
+from oeqa.runtime.decorator.package import OEHasPackage
+from oeqa.core.decorator.data import skipIfNotFeature
+from oeqa.core.decorator.data import skipIfDataVar, skipIfNotDataVar
+import bb
+blacklist = ["/usr/bin/uz", "/bin/su.shadow"]
+
+class IMACheck(OERuntimeTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ locations = ["/bin", "/usr/bin"]
+ cls.binaries = []
+ for l in locations:
+ status, output = cls.tc.target.run("find %s -type f" % l)
+ cls.binaries.extend(output.split("\n"))
+
+ cls.total = len(cls.binaries)
+
+
+ @OETestDepends(['ssh.SSHTest.test_ssh'])
+ def test_ima_enabled(self):
+ ''' Test if IMA policy is loaded before systemd starts'''
+
+ ima_search = "ima: "
+ systemd_search = "systemd .* running"
+ status, output = self.target.run("dmesg | grep -n '%s'" % ima_search)
+ self.assertEqual( status, 0, "Did not find '%s' in dmesg" % ima_search)
+
+
+ @skipIfNotFeature('systemd',
+ 'Test requires systemd to be in DISTRO_FEATURES')
+ @skipIfNotDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
+ 'systemd is not the init manager for this image')
+ @OETestDepends(['ima.IMACheck.test_ima_enabled'])
+ def test_ima_before_systemd(self):
+ ''' Test if IMA policy is loaded before systemd starts'''
+ ima_search = "ima: "
+ systemd_search = "systemd .* running"
+ status, output = self.target.run("dmesg | grep -n '%s'" % ima_search)
+ self.assertEqual( status, 0, "Did not find '%s' in dmesg" % ima_search)
+ ima_id = int(output.split(":")[0])
+ status, output = self.target.run("dmesg | grep -n '%s'" % systemd_search)
+ self.assertEqual(status, 0, "Did not find '%s' in dmesg" % systemd_search)
+ init_id = int(output.split(":")[0])
+ if ima_id > init_id:
+ self.fail("IMA does not start before systemd")
+
+
+ @OETestDepends(['ima.IMACheck.test_ima_enabled'])
+ def test_ima_hash(self):
+ ''' Test if IMA stores correct file hash '''
+ filename = "/etc/filetest"
+ ima_measure_file = "/sys/kernel/security/ima/ascii_runtime_measurements"
+ status, output = self.target.run("echo test > %s" % filename)
+ self.assertEqual(status, 0, "Cannot create file %s on target" % filename)
+
+ # wait for the IMA system to update the entry
+ maximum_tries = 30
+ tries = 0
+ status, output = self.target.run("sha1sum %s" %filename)
+ sleep(2)
+ current_hash = output.split()[0]
+ ima_hash = ""
+
+ while tries < maximum_tries:
+ status, output = self.target.run("cat %s | grep %s" \
+ % (ima_measure_file, filename))
+ # get last entry, 4th field
+ if status == 0:
+ tokens = output.split("\n")[-1].split()[3]
+ ima_hash = tokens.split(":")[1]
+ if ima_hash == current_hash:
+ break
+
+ tries += 1
+ sleep(1)
+
+ # clean target
+ self.target.run("rm %s" % filename)
+ if ima_hash != current_hash:
+ self.fail("Hash stored by IMA does not match actual hash")
+
+
+ @OETestDepends(['ima.IMACheck.test_ima_enabled'])
+ def test_ima_signature(self):
+ ''' Test if IMA stores correct signature for system binaries'''
+ passed = 0
+ failed = 0
+ for b in self.binaries:
+ if b in blacklist:
+ continue
+ status, output = self.target.run("evmctl ima_verify %s" % b)
+ if status != 0:
+ failed += 1
+ else:
+ passed += 1
+
+ if failed == self.total:
+ self.fail("Signature verifications failed (%s)" % self.total)
+
+ #bb.warn("pass: %s, fail: %s, Total: %s" % (passed, failed, total))
+
+ @OETestDepends(['ima.IMACheck.test_ima_enabled'])
+ def test_ima_overwrite(self):
+ ''' Test if IMA prevents overwriting signed files '''
+ passed = 0
+ failed = 0
+ for b in self.binaries:
+ if b in blacklist:
+ continue
+ self.target.run("echo 'foo' >> %s" % b )
+ status, output = self.target.run("evmctl ima_verify %s" % b)
+
+ if status != 0:
+ failed += 1
+ else:
+ passed += 1
+
+ if failed == self.total:
+ self.fail("Overwritting verifications failed (%s)" % self.total)
diff --git a/meta-integrity/lib/oeqa/runtime/ima.py b/meta-integrity/lib/oeqa/runtime/ima.py
deleted file mode 100644
index 2e5b258..0000000
--- a/meta-integrity/lib/oeqa/runtime/ima.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-#
-# Authors: Cristina Moraru <cristina.moraru@intel.com>
-# Alexandru Cornea <alexandru.cornea@intel.com>
-
-import unittest
-import string
-from time import sleep
-from oeqa.oetest import oeRuntimeTest, skipModule
-from oeqa.utils.decorators import *
-
-@tag(TestType = 'FVT', FeatureID = 'IOTOS-617,IOTOS-619')
-class IMACheck(oeRuntimeTest):
- def test_ima_before_systemd(self):
- ''' Test if IMA policy is loaded before systemd starts'''
-
- ima_search = "IMA: policy update completed"
- systemd_search = "systemd .* running"
- status, output = self.target.run("dmesg | grep -n '%s'" %ima_search)
- self.assertEqual( status, 0, "Did not find '%s' in dmesg" %ima_search)
- ima_id = int(output.split(":")[0])
- status, output = self.target.run("dmesg | grep -n '%s'" %systemd_search)
- self.assertEqual(status, 0, "Did not find '%s' in dmesg" %systemd_search)
- init_id = int(output.split(":")[0])
- if ima_id > init_id:
- self.fail("IMA does not start before systemd")
-
- def test_ima_hash(self):
- ''' Test if IMA stores correct file hash '''
- filename = "/etc/filetest"
- ima_measure_file = "/sys/kernel/security/ima/ascii_runtime_measurements"
- status, output = self.target.run("echo test > %s" %filename)
- self.assertEqual(status, 0, "Cannot create file %s on target" %filename)
-
- # wait for the IMA system to update the entry
- maximum_tries = 30
- tries = 0
- status, output = self.target.run("sha1sum %s" %filename)
- current_hash = output.split()[0]
- ima_hash = ""
-
- while tries < maximum_tries:
- status, output = self.target.run("cat %s | grep %s" \
- %(ima_measure_file, filename))
- # get last entry, 4th field
- if status == 0:
- tokens = output.split("\n")[-1].split()[3]
- ima_hash = tokens.split(":")[1]
- if ima_hash == current_hash:
- break
-
- tries += 1
- sleep(1)
-
- # clean target
- self.target.run("rm %s" %filename)
- if ima_hash != current_hash:
- self.fail("Hash stored by IMA does not match actual hash")
-
- def test_ima_signature(self):
- ''' Test if IMA stores correct signature for system binaries'''
- locations = ["/bin", "/usr/bin"]
- binaries = []
- for l in locations:
- status, output = self.target.run("find %s -type f" %l)
- binaries.extend(output.split("\n"))
-
- for b in binaries:
- status, output = self.target.run("evmctl ima_verify %s" %b)
- if "Verification is OK" not in output:
- self.fail("IMA signature verification fails for file %s" %b)
-
- def test_ima_overwrite(self):
- ''' Test if IMA prevents overwriting signed files '''
- status, output = self.target.run("find /bin -type f")
- self.assertEqual(status, 0 , "ssh to device fail: %s" %output)
- signed_file = output.strip().split()[0]
- print("\n signed_file is %s" % signed_file)
- status, output = self.target.run(" echo 'foo' >> %s" %signed_file)
- self.assertNotEqual(status, 0 , "Signed file could be written")
- self.assertIn("Permission denied", output,
- "Did not find expected error message. Got: %s" %output)
--
2.17.1
next prev parent reply other threads:[~2019-05-27 4:56 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-27 4:56 [meta-security][PATCH 00/14] Port over meta-integrity Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 01/14] meta-integrity: port over from meta-intel-iot-security Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 02/14] layer.conf: add LAYERSERIES_COMPAT Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 03/14] README: update Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 04/14] ima-evm-utils: cleanup and update to tip Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 05/14] ima.cfg: update to 5.0 kernel Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 06/14] linux: update bbappend Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 07/14] base-files: add appending to automount securityfs Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 08/14] ima-policy-hashed: add new recipe Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 09/14] ima_policy_simple: add another sample policy Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 10/14] policy: add ima appraise all policy Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 11/14] data: remove policies Armin Kuster
2019-05-27 4:56 ` [meta-security][PATCH 12/14] initramfs: clean up to pull in packages Armin Kuster
2019-05-27 4:56 ` Armin Kuster [this message]
2019-05-27 4:56 ` [meta-security][PATCH 14/14] image: add image for testing Armin Kuster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190527045641.18884-14-akuster808@gmail.com \
--to=akuster808@gmail.com \
--cc=yocto@yoctoproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.