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 - 2026 Red Hat, Inc.