Skip to contentSkip to conversation

support/testing/tests/core: SSP & hardening flags

PATCH New Matt Weber 3 participants 7 messages Jul 17, 2018 – Aug 11, 2018

lore
Share & tools
lore

Matt Weber

author
#0 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

Catch the commonly used options of SSP, Relro, and fortify.

---
Changes v1 -> v2
[Ricardo
- Fix flake8 warnings
- Added missing busyfox pie assertions
- Updated the yml to include new test cases

---
 .gitlab-ci.yml                               |   6 +
 support/testing/tests/core/test_hardening.py | 112 +++++++++++++++++++
 2 files changed, 118 insertions(+)
 create mode 100644 support/testing/tests/core/test_hardening.py
.gitlab-ci.yml +6 -0
index e80491cdde..49f83918d6 100644
@@ -258,6 +258,12 @@ zynq_zybo_defconfig: *defconfig
 tests.boot.test_atf.TestATFAllwinner: *runtime_test
 tests.boot.test_atf.TestATFMarvell: *runtime_test
 tests.boot.test_atf.TestATFVexpress: *runtime_test
+tests.core.test_hardening.TestFortifyConserv: *runtime_test
+tests.core.test_hardening.TestFortifyNone: *runtime_test
+tests.core.test_hardening.TestRelro: *runtime_test
+tests.core.test_hardening.TestRelroPartial: *runtime_test
+tests.core.test_hardening.TestSspNone: *runtime_test
+tests.core.test_hardening.TestSspStrong: *runtime_test
 tests.core.test_post_scripts.TestPostScripts: *runtime_test
 tests.core.test_rootfs_overlay.TestRootfsOverlay: *runtime_test
 tests.core.test_timezone.TestGlibcAllTimezone: *runtime_test
support/testing/tests/core/test_hardening.py new file +112 -0

112 lines not on this page · raw message

Signature · 1 line
2.17.0
#1 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

Hello,

Quoted 3 lines · Matt Weber

Catch the commonly used options of SSP, Relro, and fortify.

I'm a bit confused by this patch coming alone, outside of any series. Is it just because you had only changes to this PATCH 6/6 that you didn't resent the full series ?

In general, my preference is that a full series gets resent, because it is obvious what your intention is. By just resending one patch, I wonder if you really sent that one patch, or if all patches were sent, but the previous ones were lost/not received for some reason.

Thanks!

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
#2 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

Thomas,

Quoted 10 lines · Thomas Petazzoni

Hello,

Quoted 3 lines · Matt Weber

Catch the commonly used options of SSP, Relro, and fortify.

I'm a bit confused by this patch coming alone, outside of any series. Is it just because you had only changes to this PATCH 6/6 that you didn't resent the full series ?

Understood, yeah I should have asked on IRC today before sending. I already had reviewed by on the other patches so I hesitated resending them as there wasn't change. Generally, can I add reviewed by's on patches that don't change on a sending of a new version as long as the patch didn't change?

Quoted 6 lines

In general, my preference is that a full series gets resent, because it is obvious what your intention is. By just resending one patch, I wonder if you really sent that one patch, or if all patches were sent, but the previous ones were lost/not received for some reason.

Agree, it does make it confusing. My intent was just to update this one as the rest were in a good state without resending and had review. Do you want me to resent the complete set?

Matt

#3 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

Hello,

Quoted 9 lines · Matthew Weber
Quoted 3 lines

I'm a bit confused by this patch coming alone, outside of any series. Is it just because you had only changes to this PATCH 6/6 that you didn't resent the full series ?

Understood, yeah I should have asked on IRC today before sending. I already had reviewed by on the other patches so I hesitated resending them as there wasn't change. Generally, can I add reviewed by's on patches that don't change on a sending of a new version as long as the patch didn't change?

It's not only that you "can", it's that you "should" so that just Reviewed-by are not lost.

Of course, if you make changes to the patches, you cannot keep the Reviewed-by because it may not hold anymore (except if the changes are really tiny/trivial).

Quoted 8 lines
Quoted 4 lines

In general, my preference is that a full series gets resent, because it is obvious what your intention is. By just resending one patch, I wonder if you really sent that one patch, or if all patches were sent, but the previous ones were lost/not received for some reason.

Agree, it does make it confusing. My intent was just to update this one as the rest were in a good state without resending and had review. Do you want me to resent the complete set?

No need to do that for this one. But in general, my preference goes to receiving the full series for each iteration. Yes it creates more noise/traffic on the mailing list, but it makes perfectly clear what is intended, which to me is more important.

Thanks a lot!

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
#4 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

In reply to Matt Weber

Hello,

Quoted 3 lines · Matt Weber

Catch the commonly used options of SSP, Relro, and fortify.

[with patches 1 to 5 from v1 + this patch, tested on the gitlab CI:
https://gitlab.com/RicardoMartincoski/buildroot/pipelines/25963338]

Regards,
Ricardo

#5 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

In reply to Matt Weber

Hello,

Quoted 21 lines · Matt Weber
support/testing/tests/core/test_hardening.py new file +15 -0
new file mode 100644
index 0000000000..d3eb0941d3
@@ -0,0 +1,112 @@
+import os
+import subprocess
+import json
+
+import infra.basetest
+
+HARD_DEFCONFIG = \
+    """
+    BR2_powerpc64=y
+    BR2_powerpc_e5500=y
+    BR2_TOOLCHAIN_EXTERNAL=y
+    BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
+    BR2_TOOLCHAIN_EXTERNAL_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64-e5500/tarballs/powerpc64-e5500--glibc--stable-2018.02-2.tar.bz2"
+    BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
+    BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1=y

support/testing/tests/core/test_hardening.py line 25

Quoted 10 lines
support/testing/tests/core/test_hardening.py new file +10 -0
+    BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
+    BR2_TOOLCHAIN_EXTERNAL_CXX=y
+    BR2_PACKAGE_LIGHTTPD=y
+    BR2_PACKAGE_HOST_CHECKSEC=y
+    # BR2_TARGET_ROOTFS_TAR is not set
+    """
+
+
+def checksec_run(builddir, target_file):
+    cmd = ["host/bin/checksec", "--output", "json", "--file", target_file]

I'm even more confused now. I thought checksec didn't work in a cross-compiled situation. Could you clarify ?

support/testing/tests/core/test_hardening.py line 30

Quoted 5 lines
support/testing/tests/core/test_hardening.py new file +5 -0
+    ret = subprocess.check_output(cmd,
+                                  stderr=open(os.devnull, "w"),
+                                  cwd=builddir,
+                                  env={"LANG": "C"})
+    return ret

Perhaps this function should also do the json.loads and return only out["file"] to avoid duplicating this everywhere in the below classes ?

Also, using inheritance would be better here:

class TestHardeningBase(infra.basetest.BRTest):

	config = """

... the base defconfig ...
"""

checksec_files = ["usr/sbin/lighttpd", "bin/busybox"]

def checksec_run(self, target_file):
filepath = os.path.join(self.builddir, "target", target_file)
...

class TestHardeningRelRo(TestHardeningBase):
config = TestHardeningBase.config +
"""
...
"""

	def test_run():
		for f in checksec_files:
			out = self.checksec_run(f)
			self.assertEqual(out["relro"], "full")
			self.assertEqual(out["pie"], "yes")

and ditto for the other tests.

Best regards,

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
#6 lore raw

PATCH v2 6/6 support/testing/tests/core: SSP & hardening flags

Thomas,

Quoted 31 lines · Thomas Petazzoni

Hello,

Quoted 26 lines · Matt Weber
support/testing/tests/core/test_hardening.py new file +20 -0
new file mode 100644
index 0000000000..d3eb0941d3
@@ -0,0 +1,112 @@
+import os
+import subprocess
+import json
+
+import infra.basetest
+
+HARD_DEFCONFIG = \
+    """
+    BR2_powerpc64=y
+    BR2_powerpc_e5500=y
+    BR2_TOOLCHAIN_EXTERNAL=y
+    BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
+    BR2_TOOLCHAIN_EXTERNAL_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64-e5500/tarballs/powerpc64-e5500--glibc--stable-2018.02-2.tar.bz2"
+    BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
+    BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1=y
+    BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
+    BR2_TOOLCHAIN_EXTERNAL_CXX=y
+    BR2_PACKAGE_LIGHTTPD=y
+    BR2_PACKAGE_HOST_CHECKSEC=y
+    # BR2_TARGET_ROOTFS_TAR is not set
Quoted 8 lines

support/testing/tests/core/test_hardening.py line 25

Quoted 5 lines
support/testing/tests/core/test_hardening.py new file +5 -0
+    """
+
+
+def checksec_run(builddir, target_file):
+    cmd = ["host/bin/checksec", "--output", "json", "--file", target_file]

I'm even more confused now. I thought checksec didn't work in a cross-compiled situation. Could you clarify ?

It has some limitations related to FORTIFY checking when being used in a cross compile configuration (needs to run in the actual filesystem of the executable to look at the standard libraries). I can add a note to state that limitation. Otherwise it is completely functional for use against any type of binary as it is using readelf and shell
scripting for ASLR related items. I'll address more detail in the
other patch adding the tool when we clean that up.

Quoted 29 lines

support/testing/tests/core/test_hardening.py line 30

Quoted 6 lines
support/testing/tests/core/test_hardening.py new file +5 -0
+    ret = subprocess.check_output(cmd,
+                                  stderr=open(os.devnull, "w"),
+                                  cwd=builddir,
+                                  env={"LANG": "C"})
+    return ret

Perhaps this function should also do the json.loads and return only out["file"] to avoid duplicating this everywhere in the below classes ?

Also, using inheritance would be better here:

class TestHardeningBase(infra.basetest.BRTest):

        config = """

... the base defconfig ...
"""

checksec_files = ["usr/sbin/lighttpd", "bin/busybox"]

def checksec_run(self, target_file):
filepath = os.path.join(self.builddir, "target", target_file)
...

class TestHardeningRelRo(TestHardeningBase):
config = TestHardeningBase.config +
"""
...
"""

Quoted 8 lines
        def test_run():
                for f in checksec_files:
                        out = self.checksec_run(f)
                        self.assertEqual(out["relro"], "full")
                        self.assertEqual(out["pie"], "yes")

and ditto for the other tests.

Thanks for the suggestion, I'll take a look at reworking. My python intuition isn't the best :-)

Matt