Add a bunch of tests to ensure lockdown's conversion to bitmap hasn't
regressed it.
Signed-off-by: Nikolay Borisov <nik.borisov@suse.com>
---
security/lockdown/Kconfig | 5 +++
security/lockdown/Makefile | 1 +
security/lockdown/lockdown.c | 5 ++-
security/lockdown/lockdown_test.c | 54 +++++++++++++++++++++++++++++++
4 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 security/lockdown/lockdown_test.c
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
index e84ddf484010..5fb750da1f8c 100644
--- a/security/lockdown/Kconfig
+++ b/security/lockdown/Kconfig
@@ -6,6 +6,11 @@ config SECURITY_LOCKDOWN_LSM
Build support for an LSM that enforces a coarse kernel lockdown
behaviour.
+config SECURITY_LOCKDOWN_LSM_TEST
+ tristate "Test lockdown functionality" if !KUNIT_ALL_TESTS
+ depends on SECURITY_LOCKDOWN_LSM && KUNIT
+ default KUNIT_ALL_TESTS
+
config SECURITY_LOCKDOWN_LSM_EARLY
bool "Enable lockdown LSM early in init"
depends on SECURITY_LOCKDOWN_LSM
diff --git a/security/lockdown/Makefile b/security/lockdown/Makefile
index e3634b9017e7..f35d90e39f1c 100644
--- a/security/lockdown/Makefile
+++ b/security/lockdown/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown.o
+obj-$(CONFIG_SECURITY_LOCKDOWN_LSM_TEST) += lockdown_test.o
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index 5014d18c423f..412184121279 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -25,7 +25,10 @@ static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
/*
* Put the kernel into lock-down mode.
*/
-static int lock_kernel_down(const char *where, enum lockdown_reason level)
+#if !IS_ENABLED(CONFIG_KUNIT)
+static
+#endif
+int lock_kernel_down(const char *where, enum lockdown_reason level)
{
if (level > LOCKDOWN_CONFIDENTIALITY_MAX)
diff --git a/security/lockdown/lockdown_test.c b/security/lockdown/lockdown_test.c
new file mode 100644
index 000000000000..3a3c6db5b470
--- /dev/null
+++ b/security/lockdown/lockdown_test.c
@@ -0,0 +1,54 @@
+#include <linux/security.h>
+#include <kunit/test.h>
+
+int lock_kernel_down(const char *where, enum lockdown_reason level);
+
+static void lockdown_test_invalid_level(struct kunit *test)
+{
+ KUNIT_EXPECT_EQ(test, -EINVAL, lock_kernel_down("TEST", LOCKDOWN_CONFIDENTIALITY_MAX+1));
+}
+
+static void lockdown_test_depth_locking(struct kunit *test)
+{
+ KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_INTEGRITY_MAX));
+ for (int i = 1; i < LOCKDOWN_INTEGRITY_MAX; i++)
+ KUNIT_EXPECT_EQ_MSG(test, -EPERM, security_locked_down(i), "at i=%d", i);
+
+ KUNIT_EXPECT_EQ(test, -EPERM, security_locked_down(LOCKDOWN_INTEGRITY_MAX));
+}
+
+static void lockdown_test_individual_level(struct kunit *test)
+{
+ KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_PERF));
+ KUNIT_EXPECT_EQ(test, -EPERM, security_locked_down(LOCKDOWN_PERF));
+ /* Ensure adjacent levels are untouched */
+ KUNIT_EXPECT_EQ(test, 0, security_locked_down(LOCKDOWN_TRACEFS));
+ KUNIT_EXPECT_EQ(test, 0, security_locked_down(LOCKDOWN_DBG_READ_KERNEL));
+}
+
+static void lockdown_test_no_downgrade(struct kunit *test)
+{
+ KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_CONFIDENTIALITY_MAX));
+ KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_INTEGRITY_MAX));
+ /*
+ * Ensure having locked down to a lower leve after a higher level
+ * lockdown nothing is lost
+ */
+ KUNIT_EXPECT_EQ(test, -EPERM, security_locked_down(LOCKDOWN_TRACEFS));
+}
+
+static struct kunit_case lockdown_tests[] = {
+ KUNIT_CASE(lockdown_test_invalid_level),
+ KUNIT_CASE(lockdown_test_depth_locking),
+ KUNIT_CASE(lockdown_test_individual_level),
+ KUNIT_CASE(lockdown_test_no_downgrade),
+ {}
+};
+
+static struct kunit_suite lockdown_test_suite = {
+ .name = "lockdown test",
+ .test_cases = lockdown_tests,
+};
+kunit_test_suite(lockdown_test_suite);
+
+MODULE_LICENSE("GPL");
--
2.34.1
Hi Nikolay, kernel test robot noticed the following build errors: [auto build test ERROR on linus/master] [also build test ERROR on v6.16 next-20250728] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Nikolay-Borisov/lockdown-Switch-implementation-to-using-bitmap/20250728-191807 base: linus/master patch link: https://lore.kernel.org/r/20250728111517.134116-3-nik.borisov%40suse.com patch subject: [PATCH v2 2/3] lockdown/kunit: Introduce kunit tests config: i386-randconfig-004-20250729 (https://download.01.org/0day-ci/archive/20250729/202507291419.PQ4uKtRo-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250729/202507291419.PQ4uKtRo-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202507291419.PQ4uKtRo-lkp@intel.com/ All errors (new ones prefixed by >>, old ones prefixed by <<): WARNING: modpost: missing MODULE_DESCRIPTION() in security/lockdown/lockdown_test.o >> ERROR: modpost: "lock_kernel_down" [security/lockdown/lockdown_test.ko] undefined! -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Hi Nikolay, kernel test robot noticed the following build warnings: [auto build test WARNING on linus/master] [also build test WARNING on v6.16 next-20250728] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Nikolay-Borisov/lockdown-Switch-implementation-to-using-bitmap/20250728-191807 base: linus/master patch link: https://lore.kernel.org/r/20250728111517.134116-3-nik.borisov%40suse.com patch subject: [PATCH v2 2/3] lockdown/kunit: Introduce kunit tests config: arm-randconfig-004-20250729 (https://download.01.org/0day-ci/archive/20250729/202507290540.9IANrMED-lkp@intel.com/config) compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 1b4db78d2eaa070b3f364a2d2b2b826a5439b892) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250729/202507290540.9IANrMED-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202507290540.9IANrMED-lkp@intel.com/ All warnings (new ones prefixed by >>): >> security/lockdown/lockdown.c:31:5: warning: no previous prototype for function 'lock_kernel_down' [-Wmissing-prototypes] 31 | int lock_kernel_down(const char *where, enum lockdown_reason level) | ^ security/lockdown/lockdown.c:31:1: note: declare 'static' if the function is not intended to be used outside of this translation unit 31 | int lock_kernel_down(const char *where, enum lockdown_reason level) | ^ | static 1 warning generated. vim +/lock_kernel_down +31 security/lockdown/lockdown.c 20 21 static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE, 22 LOCKDOWN_INTEGRITY_MAX, 23 LOCKDOWN_CONFIDENTIALITY_MAX}; 24 25 /* 26 * Put the kernel into lock-down mode. 27 */ 28 #if !IS_ENABLED(CONFIG_KUNIT) 29 static 30 #endif > 31 int lock_kernel_down(const char *where, enum lockdown_reason level) 32 { 33 34 if (level > LOCKDOWN_CONFIDENTIALITY_MAX) 35 return -EINVAL; 36 37 if (level == LOCKDOWN_INTEGRITY_MAX || level == LOCKDOWN_CONFIDENTIALITY_MAX) 38 bitmap_set(kernel_locked_down, 1, level); 39 else 40 bitmap_set(kernel_locked_down, level, 1); 41 42 pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", 43 where); 44 return 0; 45 } 46 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
On 29.07.25 г. 1:04 ч., kernel test robot wrote: > Hi Nikolay, > > kernel test robot noticed the following build warnings: > > [auto build test WARNING on linus/master] > [also build test WARNING on v6.16 next-20250728] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: https://github.com/intel-lab-lkp/linux/commits/Nikolay-Borisov/lockdown-Switch-implementation-to-using-bitmap/20250728-191807 > base: linus/master > patch link: https://lore.kernel.org/r/20250728111517.134116-3-nik.borisov%40suse.com > patch subject: [PATCH v2 2/3] lockdown/kunit: Introduce kunit tests > config: arm-randconfig-004-20250729 (https://download.01.org/0day-ci/archive/20250729/202507290540.9IANrMED-lkp@intel.com/config) > compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 1b4db78d2eaa070b3f364a2d2b2b826a5439b892) > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250729/202507290540.9IANrMED-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202507290540.9IANrMED-lkp@intel.com/ > > All warnings (new ones prefixed by >>): > >>> security/lockdown/lockdown.c:31:5: warning: no previous prototype for function 'lock_kernel_down' [-Wmissing-prototypes] > 31 | int lock_kernel_down(const char *where, enum lockdown_reason level) > | ^ > security/lockdown/lockdown.c:31:1: note: declare 'static' if the function is not intended to be used outside of this translation unit > 31 | int lock_kernel_down(const char *where, enum lockdown_reason level) > | ^ > | static > 1 warning generated. That's a false positive, since the function is exported only for KUNIT case, what's the correct way to make testbot ignore it ? > > > vim +/lock_kernel_down +31 security/lockdown/lockdown.c > > 20 > 21 static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE, > 22 LOCKDOWN_INTEGRITY_MAX, > 23 LOCKDOWN_CONFIDENTIALITY_MAX}; > 24 > 25 /* > 26 * Put the kernel into lock-down mode. > 27 */ > 28 #if !IS_ENABLED(CONFIG_KUNIT) > 29 static > 30 #endif > > 31 int lock_kernel_down(const char *where, enum lockdown_reason level) > 32 { > 33 > 34 if (level > LOCKDOWN_CONFIDENTIALITY_MAX) > 35 return -EINVAL; > 36 > 37 if (level == LOCKDOWN_INTEGRITY_MAX || level == LOCKDOWN_CONFIDENTIALITY_MAX) > 38 bitmap_set(kernel_locked_down, 1, level); > 39 else > 40 bitmap_set(kernel_locked_down, level, 1); > 41 > 42 pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", > 43 where); > 44 return 0; > 45 } > 46 >
On Tue, Jul 29, 2025 at 10:46:48AM +0300, Nikolay Borisov wrote: > > > On 29.07.25 г. 1:04 ч., kernel test robot wrote: > > Hi Nikolay, > > > > kernel test robot noticed the following build warnings: > > > > [auto build test WARNING on linus/master] > > [also build test WARNING on v6.16 next-20250728] > > [If your patch is applied to the wrong git tree, kindly drop us a note. > > And when submitting patch, we suggest to use '--base' as documented in > > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > > > url: https://github.com/intel-lab-lkp/linux/commits/Nikolay-Borisov/lockdown-Switch-implementation-to-using-bitmap/20250728-191807 > > base: linus/master > > patch link: https://lore.kernel.org/r/20250728111517.134116-3-nik.borisov%40suse.com > > patch subject: [PATCH v2 2/3] lockdown/kunit: Introduce kunit tests > > config: arm-randconfig-004-20250729 (https://download.01.org/0day-ci/archive/20250729/202507290540.9IANrMED-lkp@intel.com/config) > > compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 1b4db78d2eaa070b3f364a2d2b2b826a5439b892) > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250729/202507290540.9IANrMED-lkp@intel.com/reproduce) > > > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > > the same patch/commit), kindly add following tags > > | Reported-by: kernel test robot <lkp@intel.com> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202507290540.9IANrMED-lkp@intel.com/ > > > > All warnings (new ones prefixed by >>): > > > > > > security/lockdown/lockdown.c:31:5: warning: no previous prototype for function 'lock_kernel_down' [-Wmissing-prototypes] > > 31 | int lock_kernel_down(const char *where, enum lockdown_reason level) > > | ^ > > security/lockdown/lockdown.c:31:1: note: declare 'static' if the function is not intended to be used outside of this translation unit > > 31 | int lock_kernel_down(const char *where, enum lockdown_reason level) > > | ^ > > | static > > 1 warning generated. > > > That's a false positive, since the function is exported only for KUNIT case, > what's the correct way to make testbot ignore it ? thanks for the info, i will configure the bot to ignore this firstly, and later to check whether there's any pattern for more general ignore. Sorry for the noise. > > > > > > vim +/lock_kernel_down +31 security/lockdown/lockdown.c > > > > 20 > > 21 static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE, > > 22 LOCKDOWN_INTEGRITY_MAX, > > 23 LOCKDOWN_CONFIDENTIALITY_MAX}; > > 24 > > 25 /* > > 26 * Put the kernel into lock-down mode. > > 27 */ > > 28 #if !IS_ENABLED(CONFIG_KUNIT) > > 29 static > > 30 #endif > > > 31 int lock_kernel_down(const char *where, enum lockdown_reason level) > > 32 { > > 33 > > 34 if (level > LOCKDOWN_CONFIDENTIALITY_MAX) > > 35 return -EINVAL; > > 36 > > 37 if (level == LOCKDOWN_INTEGRITY_MAX || level == LOCKDOWN_CONFIDENTIALITY_MAX) > > 38 bitmap_set(kernel_locked_down, 1, level); > > 39 else > > 40 bitmap_set(kernel_locked_down, level, 1); > > 41 > > 42 pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", > > 43 where); > > 44 return 0; > > 45 } > > 46 > > >
On Mon, Jul 28, 2025 at 02:15:16PM +0300, Nikolay Borisov wrote: > Add a bunch of tests to ensure lockdown's conversion to bitmap hasn't > regressed it. > > Signed-off-by: Nikolay Borisov <nik.borisov@suse.com> Reviewed-by: Serge Hallyn <serge@hallyn.com> (And I see this answers my question to patch 1, but still a comment there would be nice :) thanks, -serge > --- > security/lockdown/Kconfig | 5 +++ > security/lockdown/Makefile | 1 + > security/lockdown/lockdown.c | 5 ++- > security/lockdown/lockdown_test.c | 54 +++++++++++++++++++++++++++++++ > 4 files changed, 64 insertions(+), 1 deletion(-) > create mode 100644 security/lockdown/lockdown_test.c > > diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig > index e84ddf484010..5fb750da1f8c 100644 > --- a/security/lockdown/Kconfig > +++ b/security/lockdown/Kconfig > @@ -6,6 +6,11 @@ config SECURITY_LOCKDOWN_LSM > Build support for an LSM that enforces a coarse kernel lockdown > behaviour. > > +config SECURITY_LOCKDOWN_LSM_TEST > + tristate "Test lockdown functionality" if !KUNIT_ALL_TESTS > + depends on SECURITY_LOCKDOWN_LSM && KUNIT > + default KUNIT_ALL_TESTS > + > config SECURITY_LOCKDOWN_LSM_EARLY > bool "Enable lockdown LSM early in init" > depends on SECURITY_LOCKDOWN_LSM > diff --git a/security/lockdown/Makefile b/security/lockdown/Makefile > index e3634b9017e7..f35d90e39f1c 100644 > --- a/security/lockdown/Makefile > +++ b/security/lockdown/Makefile > @@ -1 +1,2 @@ > obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown.o > +obj-$(CONFIG_SECURITY_LOCKDOWN_LSM_TEST) += lockdown_test.o > diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c > index 5014d18c423f..412184121279 100644 > --- a/security/lockdown/lockdown.c > +++ b/security/lockdown/lockdown.c > @@ -25,7 +25,10 @@ static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE, > /* > * Put the kernel into lock-down mode. > */ > -static int lock_kernel_down(const char *where, enum lockdown_reason level) > +#if !IS_ENABLED(CONFIG_KUNIT) > +static > +#endif > +int lock_kernel_down(const char *where, enum lockdown_reason level) > { > > if (level > LOCKDOWN_CONFIDENTIALITY_MAX) > diff --git a/security/lockdown/lockdown_test.c b/security/lockdown/lockdown_test.c > new file mode 100644 > index 000000000000..3a3c6db5b470 > --- /dev/null > +++ b/security/lockdown/lockdown_test.c > @@ -0,0 +1,54 @@ > +#include <linux/security.h> > +#include <kunit/test.h> > + > +int lock_kernel_down(const char *where, enum lockdown_reason level); > + > +static void lockdown_test_invalid_level(struct kunit *test) > +{ > + KUNIT_EXPECT_EQ(test, -EINVAL, lock_kernel_down("TEST", LOCKDOWN_CONFIDENTIALITY_MAX+1)); > +} > + > +static void lockdown_test_depth_locking(struct kunit *test) > +{ > + KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_INTEGRITY_MAX)); > + for (int i = 1; i < LOCKDOWN_INTEGRITY_MAX; i++) > + KUNIT_EXPECT_EQ_MSG(test, -EPERM, security_locked_down(i), "at i=%d", i); > + > + KUNIT_EXPECT_EQ(test, -EPERM, security_locked_down(LOCKDOWN_INTEGRITY_MAX)); > +} > + > +static void lockdown_test_individual_level(struct kunit *test) > +{ > + KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_PERF)); > + KUNIT_EXPECT_EQ(test, -EPERM, security_locked_down(LOCKDOWN_PERF)); > + /* Ensure adjacent levels are untouched */ > + KUNIT_EXPECT_EQ(test, 0, security_locked_down(LOCKDOWN_TRACEFS)); > + KUNIT_EXPECT_EQ(test, 0, security_locked_down(LOCKDOWN_DBG_READ_KERNEL)); > +} > + > +static void lockdown_test_no_downgrade(struct kunit *test) > +{ > + KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_CONFIDENTIALITY_MAX)); > + KUNIT_EXPECT_EQ(test, 0, lock_kernel_down("TEST", LOCKDOWN_INTEGRITY_MAX)); > + /* > + * Ensure having locked down to a lower leve after a higher level > + * lockdown nothing is lost > + */ > + KUNIT_EXPECT_EQ(test, -EPERM, security_locked_down(LOCKDOWN_TRACEFS)); > +} > + > +static struct kunit_case lockdown_tests[] = { > + KUNIT_CASE(lockdown_test_invalid_level), > + KUNIT_CASE(lockdown_test_depth_locking), > + KUNIT_CASE(lockdown_test_individual_level), > + KUNIT_CASE(lockdown_test_no_downgrade), > + {} > +}; > + > +static struct kunit_suite lockdown_test_suite = { > + .name = "lockdown test", > + .test_cases = lockdown_tests, > +}; > +kunit_test_suite(lockdown_test_suite); > + > +MODULE_LICENSE("GPL"); > -- > 2.34.1 >
© 2016 - 2025 Red Hat, Inc.