* [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages
@ 2025-11-24 22:54 Joshua Hahn
2025-11-24 22:54 ` [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free} Joshua Hahn
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Joshua Hahn @ 2025-11-24 22:54 UTC (permalink / raw)
To: Andrew Morton
Cc: Vlastimil Babka, Jonathan Corbet, Mike Rapoport, linux-doc,
linux-kernel, linux-mm, kernel-team
Use-after-free and double-free bugs can be very difficult to track down.
The kernel is good at tracking these and preventing bad pages from being
used/created through simple checks gated behind "check_pages_enabled".
Currently, the only ways to enable this flag is by building with
CONFIG_DEBUG_VM, or as a side effect of other checks such as
init_on_{alloc, free}, page_poisoning, or debug_pagealloc among others.
These solutions are powerful, but may often be too coarse in balancing
the performance vs. safety that a user may want, particularly in
latency-sensitive production environments.
Introduce a new boot parameter "check_pages", which enables page checking
with no other side effects. It takes kstrbool-able inputs as an argument
(i.e. 0/1, true/false, on/off, ...). This patch is backwards-compatible;
setting CONFIG_DEBUG_VM still enables page checking.
Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
---
v1 --> v2:
- Changed check_pages from a build config into a boot config, as suggested
by Vlastimil.
- Introduced the second patch, which decouples page checking from
init_on_page_alloc and init_on_page_free.
---
Documentation/admin-guide/kernel-parameters.txt | 8 ++++++++
mm/mm_init.c | 11 ++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 6c42061ca20e..0ba9561440a7 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -669,6 +669,14 @@
nokmem -- Disable kernel memory accounting.
nobpf -- Disable BPF memory accounting.
+ check_pages= [MM,EARLY] Enable sanity checking of pages after
+ allocations / before freeing. This adds checks to catch
+ double-frees, use-after-frees, and other sources of
+ page corruption by inspecting page internals (flags,
+ mapcount/refcount, memcg_data, etc.).
+ Format: { "0" | "1" }
+ Default: 0 (1 if CONFIG_DEBUG_VM is set)
+
checkreqprot= [SELINUX] Set initial checkreqprot flag value.
Format: { "0" | "1" }
See security/selinux/Kconfig help text.
diff --git a/mm/mm_init.c b/mm/mm_init.c
index c6812b4dbb2e..01d46efc42b4 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2525,6 +2525,14 @@ early_param("init_on_free", early_init_on_free);
DEFINE_STATIC_KEY_MAYBE(CONFIG_DEBUG_VM, check_pages_enabled);
+static bool _check_pages_enabled_early __initdata;
+
+static int __init early_check_pages(char *buf)
+{
+ return kstrtobool(buf, &_check_pages_enabled_early);
+}
+early_param("check_pages", early_check_pages);
+
/*
* Enable static keys related to various memory debugging and hardening options.
* Some override others, and depend on early params that are evaluated in the
@@ -2591,7 +2599,8 @@ static void __init mem_debugging_and_hardening_init(void)
* of struct pages being allocated or freed. With CONFIG_DEBUG_VM it's
* enabled already.
*/
- if (!IS_ENABLED(CONFIG_DEBUG_VM) && want_check_pages)
+ if (!IS_ENABLED(CONFIG_DEBUG_VM) && (_check_pages_enabled_early ||
+ want_check_pages))
static_branch_enable(&check_pages_enabled);
}
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free}
2025-11-24 22:54 [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages Joshua Hahn
@ 2025-11-24 22:54 ` Joshua Hahn
2025-11-25 1:18 ` SeongJae Park
2025-11-25 8:45 ` Michal Hocko
2025-11-25 1:10 ` [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages SeongJae Park
` (2 subsequent siblings)
3 siblings, 2 replies; 11+ messages in thread
From: Joshua Hahn @ 2025-11-24 22:54 UTC (permalink / raw)
To: Andrew Morton
Cc: Vlastimil Babka, Mike Rapoport, linux-kernel, linux-mm, kernel-team
init_on_alloc and init_on_free protect the kernel by initializing
allocated and freed pages to 0 on allocation time / deletion.
Commit 700d2e9a36b93601270c1e15550acde2521386c5 ("mm, page_alloc: reduce
page alloc/free sanity checks") removed page checking from hot pcp
drain and refill paths, and instead coupled it with CONFIG_DEBUG_VM,
debug_pagealloc, page poisoning, and init_on_{alloc, free}.
As the commit suggests, the first three turn the kernel into a debug
kernel, while the last hardens the kernel against leaking sensitive memory.
While enabling page checking is relatively low-cost and tying it
together with page initialization is not unreasonable, it does feel like
a bit of a side-effect, rather than an obvious consequence.
With page checking now pulled out as a boot time parameter that can be
set independently, let's decouple page checking and init_on_alloc and
init_on_free.
As a direct side effect, systems that have init_on_alloc or init_on_free
will no longer have page checking enabled by default; they will either
have to pass the check_pages boot parameter, build the kernel with
CONFIG_DEBUG_VM, or enable debug_pagealloc / page poisoning.
Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
---
mm/mm_init.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 01d46efc42b4..59636d2c0178 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2566,19 +2566,15 @@ static void __init mem_debugging_and_hardening_init(void)
_init_on_free_enabled_early = false;
}
- if (_init_on_alloc_enabled_early) {
- want_check_pages = true;
+ if (_init_on_alloc_enabled_early)
static_branch_enable(&init_on_alloc);
- } else {
+ else
static_branch_disable(&init_on_alloc);
- }
- if (_init_on_free_enabled_early) {
- want_check_pages = true;
+ if (_init_on_free_enabled_early)
static_branch_enable(&init_on_free);
- } else {
+ else
static_branch_disable(&init_on_free);
- }
if (IS_ENABLED(CONFIG_KMSAN) &&
(_init_on_alloc_enabled_early || _init_on_free_enabled_early))
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages
2025-11-24 22:54 [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages Joshua Hahn
2025-11-24 22:54 ` [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free} Joshua Hahn
@ 2025-11-25 1:10 ` SeongJae Park
2025-11-25 8:44 ` Michal Hocko
2025-11-25 10:23 ` Mike Rapoport
3 siblings, 0 replies; 11+ messages in thread
From: SeongJae Park @ 2025-11-25 1:10 UTC (permalink / raw)
To: Joshua Hahn
Cc: SeongJae Park, Andrew Morton, Vlastimil Babka, Jonathan Corbet,
Mike Rapoport, linux-doc, linux-kernel, linux-mm, kernel-team
On Mon, 24 Nov 2025 14:54:06 -0800 Joshua Hahn <joshua.hahnjy@gmail.com> wrote:
> Use-after-free and double-free bugs can be very difficult to track down.
> The kernel is good at tracking these and preventing bad pages from being
> used/created through simple checks gated behind "check_pages_enabled".
>
> Currently, the only ways to enable this flag is by building with
> CONFIG_DEBUG_VM, or as a side effect of other checks such as
> init_on_{alloc, free}, page_poisoning, or debug_pagealloc among others.
> These solutions are powerful, but may often be too coarse in balancing
> the performance vs. safety that a user may want, particularly in
> latency-sensitive production environments.
>
> Introduce a new boot parameter "check_pages", which enables page checking
> with no other side effects. It takes kstrbool-able inputs as an argument
> (i.e. 0/1, true/false, on/off, ...). This patch is backwards-compatible;
> setting CONFIG_DEBUG_VM still enables page checking.
>
> Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Acked-by: SeongJae Park <sj@kernel.org>
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free}
2025-11-24 22:54 ` [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free} Joshua Hahn
@ 2025-11-25 1:18 ` SeongJae Park
2025-11-25 18:59 ` Joshua Hahn
2025-11-25 8:45 ` Michal Hocko
1 sibling, 1 reply; 11+ messages in thread
From: SeongJae Park @ 2025-11-25 1:18 UTC (permalink / raw)
To: Joshua Hahn
Cc: SeongJae Park, Andrew Morton, Vlastimil Babka, Mike Rapoport,
linux-kernel, linux-mm, kernel-team
On Mon, 24 Nov 2025 14:54:07 -0800 Joshua Hahn <joshua.hahnjy@gmail.com> wrote:
> init_on_alloc and init_on_free protect the kernel by initializing
> allocated and freed pages to 0 on allocation time / deletion.
> Commit 700d2e9a36b93601270c1e15550acde2521386c5 ("mm, page_alloc: reduce
I think 12 digits for commit hash id is enough.
> page alloc/free sanity checks") removed page checking from hot pcp
> drain and refill paths, and instead coupled it with CONFIG_DEBUG_VM,
> debug_pagealloc, page poisoning, and init_on_{alloc, free}.
>
> As the commit suggests, the first three turn the kernel into a debug
> kernel, while the last hardens the kernel against leaking sensitive memory.
> While enabling page checking is relatively low-cost and tying it
> together with page initialization is not unreasonable, it does feel like
> a bit of a side-effect, rather than an obvious consequence.
>
> With page checking now pulled out as a boot time parameter that can be
> set independently, let's decouple page checking and init_on_alloc and
> init_on_free.
>
> As a direct side effect, systems that have init_on_alloc or init_on_free
> will no longer have page checking enabled by default; they will either
> have to pass the check_pages boot parameter, build the kernel with
> CONFIG_DEBUG_VM, or enable debug_pagealloc / page poisoning.
>
> Suggested-by: Vlastimil Babka <vbabka@suse.cz>
> Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Acked-by: SeongJae Park <sj@kernel.org>
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages
2025-11-24 22:54 [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages Joshua Hahn
2025-11-24 22:54 ` [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free} Joshua Hahn
2025-11-25 1:10 ` [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages SeongJae Park
@ 2025-11-25 8:44 ` Michal Hocko
2025-11-25 10:23 ` Mike Rapoport
3 siblings, 0 replies; 11+ messages in thread
From: Michal Hocko @ 2025-11-25 8:44 UTC (permalink / raw)
To: Joshua Hahn
Cc: Andrew Morton, Vlastimil Babka, Jonathan Corbet, Mike Rapoport,
linux-doc, linux-kernel, linux-mm, kernel-team
On Mon 24-11-25 14:54:06, Joshua Hahn wrote:
> Use-after-free and double-free bugs can be very difficult to track down.
> The kernel is good at tracking these and preventing bad pages from being
> used/created through simple checks gated behind "check_pages_enabled".
>
> Currently, the only ways to enable this flag is by building with
> CONFIG_DEBUG_VM, or as a side effect of other checks such as
> init_on_{alloc, free}, page_poisoning, or debug_pagealloc among others.
> These solutions are powerful, but may often be too coarse in balancing
> the performance vs. safety that a user may want, particularly in
> latency-sensitive production environments.
>
> Introduce a new boot parameter "check_pages", which enables page checking
> with no other side effects. It takes kstrbool-able inputs as an argument
> (i.e. 0/1, true/false, on/off, ...). This patch is backwards-compatible;
> setting CONFIG_DEBUG_VM still enables page checking.
Arguing with performance without any performance numbers is not really
convincing but the change makes some sense to me even without that.
DEBUG_VM is just everything-in-one-bag thing which is not suitable for
production use and bad_page checks might still be valuable for such a
use.
> Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> v1 --> v2:
> - Changed check_pages from a build config into a boot config, as suggested
> by Vlastimil.
> - Introduced the second patch, which decouples page checking from
> init_on_page_alloc and init_on_page_free.
> ---
>
> Documentation/admin-guide/kernel-parameters.txt | 8 ++++++++
> mm/mm_init.c | 11 ++++++++++-
> 2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 6c42061ca20e..0ba9561440a7 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -669,6 +669,14 @@
> nokmem -- Disable kernel memory accounting.
> nobpf -- Disable BPF memory accounting.
>
> + check_pages= [MM,EARLY] Enable sanity checking of pages after
> + allocations / before freeing. This adds checks to catch
> + double-frees, use-after-frees, and other sources of
> + page corruption by inspecting page internals (flags,
> + mapcount/refcount, memcg_data, etc.).
> + Format: { "0" | "1" }
> + Default: 0 (1 if CONFIG_DEBUG_VM is set)
> +
> checkreqprot= [SELINUX] Set initial checkreqprot flag value.
> Format: { "0" | "1" }
> See security/selinux/Kconfig help text.
> diff --git a/mm/mm_init.c b/mm/mm_init.c
> index c6812b4dbb2e..01d46efc42b4 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -2525,6 +2525,14 @@ early_param("init_on_free", early_init_on_free);
>
> DEFINE_STATIC_KEY_MAYBE(CONFIG_DEBUG_VM, check_pages_enabled);
>
> +static bool _check_pages_enabled_early __initdata;
> +
> +static int __init early_check_pages(char *buf)
> +{
> + return kstrtobool(buf, &_check_pages_enabled_early);
> +}
> +early_param("check_pages", early_check_pages);
> +
> /*
> * Enable static keys related to various memory debugging and hardening options.
> * Some override others, and depend on early params that are evaluated in the
> @@ -2591,7 +2599,8 @@ static void __init mem_debugging_and_hardening_init(void)
> * of struct pages being allocated or freed. With CONFIG_DEBUG_VM it's
> * enabled already.
> */
> - if (!IS_ENABLED(CONFIG_DEBUG_VM) && want_check_pages)
> + if (!IS_ENABLED(CONFIG_DEBUG_VM) && (_check_pages_enabled_early ||
> + want_check_pages))
> static_branch_enable(&check_pages_enabled);
> }
>
> --
> 2.47.3
--
Michal Hocko
SUSE Labs
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free}
2025-11-24 22:54 ` [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free} Joshua Hahn
2025-11-25 1:18 ` SeongJae Park
@ 2025-11-25 8:45 ` Michal Hocko
2025-11-25 18:06 ` Vlastimil Babka
1 sibling, 1 reply; 11+ messages in thread
From: Michal Hocko @ 2025-11-25 8:45 UTC (permalink / raw)
To: Joshua Hahn
Cc: Andrew Morton, Vlastimil Babka, Mike Rapoport, linux-kernel,
linux-mm, kernel-team
On Mon 24-11-25 14:54:07, Joshua Hahn wrote:
> init_on_alloc and init_on_free protect the kernel by initializing
> allocated and freed pages to 0 on allocation time / deletion.
> Commit 700d2e9a36b93601270c1e15550acde2521386c5 ("mm, page_alloc: reduce
> page alloc/free sanity checks") removed page checking from hot pcp
> drain and refill paths, and instead coupled it with CONFIG_DEBUG_VM,
> debug_pagealloc, page poisoning, and init_on_{alloc, free}.
>
> As the commit suggests, the first three turn the kernel into a debug
> kernel, while the last hardens the kernel against leaking sensitive memory.
> While enabling page checking is relatively low-cost and tying it
> together with page initialization is not unreasonable, it does feel like
> a bit of a side-effect, rather than an obvious consequence.
>
> With page checking now pulled out as a boot time parameter that can be
> set independently, let's decouple page checking and init_on_alloc and
> init_on_free.
>
> As a direct side effect, systems that have init_on_alloc or init_on_free
> will no longer have page checking enabled by default; they will either
> have to pass the check_pages boot parameter, build the kernel with
> CONFIG_DEBUG_VM, or enable debug_pagealloc / page poisoning.
How come this will not break existing users? What is an actual upside to
get for the risk involved?
--
Michal Hocko
SUSE Labs
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages
2025-11-24 22:54 [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages Joshua Hahn
` (2 preceding siblings ...)
2025-11-25 8:44 ` Michal Hocko
@ 2025-11-25 10:23 ` Mike Rapoport
2025-11-25 18:44 ` Joshua Hahn
3 siblings, 1 reply; 11+ messages in thread
From: Mike Rapoport @ 2025-11-25 10:23 UTC (permalink / raw)
To: Joshua Hahn
Cc: Andrew Morton, Vlastimil Babka, Jonathan Corbet, linux-doc,
linux-kernel, linux-mm, kernel-team
On Mon, Nov 24, 2025 at 02:54:06PM -0800, Joshua Hahn wrote:
> Use-after-free and double-free bugs can be very difficult to track down.
> The kernel is good at tracking these and preventing bad pages from being
> used/created through simple checks gated behind "check_pages_enabled".
>
> Currently, the only ways to enable this flag is by building with
> CONFIG_DEBUG_VM, or as a side effect of other checks such as
> init_on_{alloc, free}, page_poisoning, or debug_pagealloc among others.
> These solutions are powerful, but may often be too coarse in balancing
> the performance vs. safety that a user may want, particularly in
> latency-sensitive production environments.
>
> Introduce a new boot parameter "check_pages", which enables page checking
> with no other side effects. It takes kstrbool-able inputs as an argument
> (i.e. 0/1, true/false, on/off, ...). This patch is backwards-compatible;
> setting CONFIG_DEBUG_VM still enables page checking.
>
> Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
> ---
> v1 --> v2:
> - Changed check_pages from a build config into a boot config, as suggested
> by Vlastimil.
> - Introduced the second patch, which decouples page checking from
> init_on_page_alloc and init_on_page_free.
> ---
>
> Documentation/admin-guide/kernel-parameters.txt | 8 ++++++++
> mm/mm_init.c | 11 ++++++++++-
> 2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 6c42061ca20e..0ba9561440a7 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -669,6 +669,14 @@
> nokmem -- Disable kernel memory accounting.
> nobpf -- Disable BPF memory accounting.
>
> + check_pages= [MM,EARLY] Enable sanity checking of pages after
> + allocations / before freeing. This adds checks to catch
> + double-frees, use-after-frees, and other sources of
> + page corruption by inspecting page internals (flags,
> + mapcount/refcount, memcg_data, etc.).
> + Format: { "0" | "1" }
> + Default: 0 (1 if CONFIG_DEBUG_VM is set)
> +
> checkreqprot= [SELINUX] Set initial checkreqprot flag value.
> Format: { "0" | "1" }
> See security/selinux/Kconfig help text.
> diff --git a/mm/mm_init.c b/mm/mm_init.c
> index c6812b4dbb2e..01d46efc42b4 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -2525,6 +2525,14 @@ early_param("init_on_free", early_init_on_free);
>
> DEFINE_STATIC_KEY_MAYBE(CONFIG_DEBUG_VM, check_pages_enabled);
>
> +static bool _check_pages_enabled_early __initdata;
No need in the leading underscore.
> +
> +static int __init early_check_pages(char *buf)
> +{
> + return kstrtobool(buf, &_check_pages_enabled_early);
> +}
> +early_param("check_pages", early_check_pages);
> +
> /*
> * Enable static keys related to various memory debugging and hardening options.
> * Some override others, and depend on early params that are evaluated in the
> @@ -2591,7 +2599,8 @@ static void __init mem_debugging_and_hardening_init(void)
> * of struct pages being allocated or freed. With CONFIG_DEBUG_VM it's
> * enabled already.
> */
> - if (!IS_ENABLED(CONFIG_DEBUG_VM) && want_check_pages)
> + if (!IS_ENABLED(CONFIG_DEBUG_VM) && (_check_pages_enabled_early ||
> + want_check_pages))
You can initialize want_check_pages to check_pages_enabled_early, would be
clearer IMO.
> static_branch_enable(&check_pages_enabled);
> }
>
> --
> 2.47.3
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free}
2025-11-25 8:45 ` Michal Hocko
@ 2025-11-25 18:06 ` Vlastimil Babka
2025-11-25 18:58 ` Joshua Hahn
0 siblings, 1 reply; 11+ messages in thread
From: Vlastimil Babka @ 2025-11-25 18:06 UTC (permalink / raw)
To: Michal Hocko, Joshua Hahn, Kees Cook, Gustavo A. R. Silva,
linux-hardening
Cc: Andrew Morton, Mike Rapoport, linux-kernel, linux-mm, kernel-team
On 11/25/25 09:45, Michal Hocko wrote:
> On Mon 24-11-25 14:54:07, Joshua Hahn wrote:
>> init_on_alloc and init_on_free protect the kernel by initializing
>> allocated and freed pages to 0 on allocation time / deletion.
>> Commit 700d2e9a36b93601270c1e15550acde2521386c5 ("mm, page_alloc: reduce
>> page alloc/free sanity checks") removed page checking from hot pcp
>> drain and refill paths, and instead coupled it with CONFIG_DEBUG_VM,
>> debug_pagealloc, page poisoning, and init_on_{alloc, free}.
>>
>> As the commit suggests, the first three turn the kernel into a debug
>> kernel, while the last hardens the kernel against leaking sensitive memory.
>> While enabling page checking is relatively low-cost and tying it
>> together with page initialization is not unreasonable, it does feel like
>> a bit of a side-effect, rather than an obvious consequence.
>>
>> With page checking now pulled out as a boot time parameter that can be
>> set independently, let's decouple page checking and init_on_alloc and
>> init_on_free.
>>
>> As a direct side effect, systems that have init_on_alloc or init_on_free
>> will no longer have page checking enabled by default; they will either
>> have to pass the check_pages boot parameter, build the kernel with
>> CONFIG_DEBUG_VM, or enable debug_pagealloc / page poisoning.
>
> How come this will not break existing users? What is an actual upside to
> get for the risk involved?
+Cc hardening people for input if they are fine with the decoupling and if
docs for hardening recommendations or something similar needs updating
The upside is mainly reducing the side effects i.e. being more explicit than
implicit. In practice I'd however assume people running init_on_alloc/free
and paying the cost also want to do page flags checking anyway. The more
important patch here is 1/2.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages
2025-11-25 10:23 ` Mike Rapoport
@ 2025-11-25 18:44 ` Joshua Hahn
0 siblings, 0 replies; 11+ messages in thread
From: Joshua Hahn @ 2025-11-25 18:44 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, Vlastimil Babka, Jonathan Corbet, linux-doc,
linux-kernel, linux-mm, kernel-team
On Tue, 25 Nov 2025 12:23:14 +0200 Mike Rapoport <rppt@kernel.org> wrote:
> On Mon, Nov 24, 2025 at 02:54:06PM -0800, Joshua Hahn wrote:
> > Use-after-free and double-free bugs can be very difficult to track down.
> > The kernel is good at tracking these and preventing bad pages from being
> > used/created through simple checks gated behind "check_pages_enabled".
> >
> > Currently, the only ways to enable this flag is by building with
> > CONFIG_DEBUG_VM, or as a side effect of other checks such as
> > init_on_{alloc, free}, page_poisoning, or debug_pagealloc among others.
> > These solutions are powerful, but may often be too coarse in balancing
> > the performance vs. safety that a user may want, particularly in
> > latency-sensitive production environments.
> >
> > Introduce a new boot parameter "check_pages", which enables page checking
> > with no other side effects. It takes kstrbool-able inputs as an argument
> > (i.e. 0/1, true/false, on/off, ...). This patch is backwards-compatible;
> > setting CONFIG_DEBUG_VM still enables page checking.
> >
> > Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
...
Hello Mike, thank you for your review!
> > +static bool _check_pages_enabled_early __initdata;
>
> No need in the leading underscore.
Gotcha, no preference here on my end at all, so I'm happy to drop the leading
underscore. I was just modeling the variable after _init_on_alloc_enabled_early
and _init_on_free_enabled_early, but it seems like those are the only ones
that do have this leading underscore anyways.
> > +
> > +static int __init early_check_pages(char *buf)
> > +{
> > + return kstrtobool(buf, &_check_pages_enabled_early);
> > +}
> > +early_param("check_pages", early_check_pages);
> > +
> > /*
> > * Enable static keys related to various memory debugging and hardening options.
> > * Some override others, and depend on early params that are evaluated in the
> > @@ -2591,7 +2599,8 @@ static void __init mem_debugging_and_hardening_init(void)
> > * of struct pages being allocated or freed. With CONFIG_DEBUG_VM it's
> > * enabled already.
> > */
> > - if (!IS_ENABLED(CONFIG_DEBUG_VM) && want_check_pages)
> > + if (!IS_ENABLED(CONFIG_DEBUG_VM) && (_check_pages_enabled_early ||
> > + want_check_pages))
>
> You can initialize want_check_pages to check_pages_enabled_early, would be
> clearer IMO.
Yup, totally makes sense as well. I'll include this change in v3.
Thank you for all your feedback, I hope you have a great day!
Joshua
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free}
2025-11-25 18:06 ` Vlastimil Babka
@ 2025-11-25 18:58 ` Joshua Hahn
0 siblings, 0 replies; 11+ messages in thread
From: Joshua Hahn @ 2025-11-25 18:58 UTC (permalink / raw)
To: Vlastimil Babka
Cc: Michal Hocko, Kees Cook, Gustavo A. R. Silva, linux-hardening,
Andrew Morton, Mike Rapoport, linux-kernel, linux-mm,
kernel-team
On Tue, 25 Nov 2025 19:06:53 +0100 Vlastimil Babka <vbabka@suse.cz> wrote:
> On 11/25/25 09:45, Michal Hocko wrote:
> > On Mon 24-11-25 14:54:07, Joshua Hahn wrote:
> >> init_on_alloc and init_on_free protect the kernel by initializing
> >> allocated and freed pages to 0 on allocation time / deletion.
> >> Commit 700d2e9a36b93601270c1e15550acde2521386c5 ("mm, page_alloc: reduce
> >> page alloc/free sanity checks") removed page checking from hot pcp
> >> drain and refill paths, and instead coupled it with CONFIG_DEBUG_VM,
> >> debug_pagealloc, page poisoning, and init_on_{alloc, free}.
> >>
> >> As the commit suggests, the first three turn the kernel into a debug
> >> kernel, while the last hardens the kernel against leaking sensitive memory.
> >> While enabling page checking is relatively low-cost and tying it
> >> together with page initialization is not unreasonable, it does feel like
> >> a bit of a side-effect, rather than an obvious consequence.
> >>
> >> With page checking now pulled out as a boot time parameter that can be
> >> set independently, let's decouple page checking and init_on_alloc and
> >> init_on_free.
> >>
> >> As a direct side effect, systems that have init_on_alloc or init_on_free
> >> will no longer have page checking enabled by default; they will either
> >> have to pass the check_pages boot parameter, build the kernel with
> >> CONFIG_DEBUG_VM, or enable debug_pagealloc / page poisoning.
> >
> > How come this will not break existing users? What is an actual upside to
> > get for the risk involved?
Hello Michal, Vlastimil
> +Cc hardening people for input if they are fine with the decoupling and if
> docs for hardening recommendations or something similar needs updating
Thank you!
> The upside is mainly reducing the side effects i.e. being more explicit than
> implicit. In practice I'd however assume people running init_on_alloc/free
> and paying the cost also want to do page flags checking anyway. The more
> important patch here is 1/2.
I agree with all of this. Maybe an alternate approach is not to decouple
the flags, but to make their relationship more explicit in Documentation.
Currently, userspace doesn't have much visibility into this relationship, so
an additional line in Documentation/admin-guide/kernel-parameters could
achieve the same desired outcome.
I'll also let the hardning folks comment on this before sending out v3 in case
they have additional requests or ideas for this.
Thank you all for your review!
Joshua
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free}
2025-11-25 1:18 ` SeongJae Park
@ 2025-11-25 18:59 ` Joshua Hahn
0 siblings, 0 replies; 11+ messages in thread
From: Joshua Hahn @ 2025-11-25 18:59 UTC (permalink / raw)
To: SeongJae Park
Cc: Andrew Morton, Vlastimil Babka, Mike Rapoport, linux-kernel,
linux-mm, kernel-team
On Mon, 24 Nov 2025 17:18:07 -0800 SeongJae Park <sj@kernel.org> wrote:
> On Mon, 24 Nov 2025 14:54:07 -0800 Joshua Hahn <joshua.hahnjy@gmail.com> wrote:
>
> > init_on_alloc and init_on_free protect the kernel by initializing
> > allocated and freed pages to 0 on allocation time / deletion.
> > Commit 700d2e9a36b93601270c1e15550acde2521386c5 ("mm, page_alloc: reduce
Hello SJ, thank you for your review on both of these patches!!
> I think 12 digits for commit hash id is enough.
Sounds good, I'll shrink the hash id in the next version ; -)
[...snip...]
> Acked-by: SeongJae Park <sj@kernel.org>
Thanks again, I hope you have a great day!
Joshua
>
> Thanks,
> SJ
>
> [...]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-11-25 18:59 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-24 22:54 [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages Joshua Hahn
2025-11-24 22:54 ` [PATCH v2 2/2] mm/mm_init: decouple page checking and init_on_{alloc, free} Joshua Hahn
2025-11-25 1:18 ` SeongJae Park
2025-11-25 18:59 ` Joshua Hahn
2025-11-25 8:45 ` Michal Hocko
2025-11-25 18:06 ` Vlastimil Babka
2025-11-25 18:58 ` Joshua Hahn
2025-11-25 1:10 ` [PATCH v2 1/2] mm/mm_init: Introduce a boot parameter for check_pages SeongJae Park
2025-11-25 8:44 ` Michal Hocko
2025-11-25 10:23 ` Mike Rapoport
2025-11-25 18:44 ` Joshua Hahn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox