* [PATCH] mm/secretmem: disable under HIGHMEM
@ 2026-07-03 14:48 Brendan Jackman
2026-07-04 6:42 ` Mike Rapoport
2026-07-05 2:26 ` Andrew Morton
0 siblings, 2 replies; 5+ messages in thread
From: Brendan Jackman @ 2026-07-03 14:48 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko
Cc: linux-mm, linux-kernel, Brendan Jackman
secretmem_fault() allocates a folio with GFP_HIGHUSER and then calls
set_direct_map_valid_noflush() without checking folio_test_highmem().
This causes a warning and process crash (vibe-coded reproducer in Link
below):
Su[ 30.071284] ------------[ cut here ]------------
ccessfully allocated and mapped 2097152000 bytes at 0x3a449000
Populating memor[ 30.074614] CPA: called for zero pte. vaddr = 0 cpa->vaddr = 0
y...
[ 30.078636] WARNING: arch/x86/mm/pat/set_memory.c:1840 at __cpa_process_fault+0x34d/0x360, CPU#5: allocate_secret/570
[ 30.084789] CPU: 5 UID: 0 PID: 570 Comm: allocate_secret Not tainted 7.1.0-14063-g4edcdefd4083-dirty #10 PREEMPTLAZY
[ 30.090937] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
[ 30.097543] EIP: __cpa_process_fault+0x34d/0x360
[ 30.100514] Code: ff ff 85 c0 0f 89 7d fe ff ff e9 3d fe ff ff 8b 03 8b 00 c7 04 24 c8 ff 64 c1 89 44 24 08 8b 45 e8 89 44 24 04 e8 53 7
a 00 00 <0f> 0b c7 45 f0 f2 ff ff ff e9 fc fc ff ff 90 8d 74 26 00 55 25 00
[ 30.110829] EAX: 00000000 EBX: f64afe98 ECX: 00000000 EDX: 00000000
[ 30.114799] ESI: 00000000 EDI: f64afe98 EBP: f64afe04 ESP: f64afdcc
[ 30.118785] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 EFLAGS: 00010246
[ 30.123020] CR0: 80050033 CR2: 46c48ffc CR3: 038c8000 CR4: 00000690
[ 30.127010] Call Trace:
[ 30.129078] __change_page_attr_set_clr+0x5e7/0x870
[ 30.132275] ? console_unlock+0x99/0x130
[ 30.135069] ? irq_work_queue+0x36/0x70
[ 30.137853] ? page_address+0xd3/0xf0
[ 30.140421] set_direct_map_invalid_noflush+0x52/0x60
[ 30.143782] secretmem_fault+0x128/0x210
[ 30.146560] __do_fault+0x25/0x90
[ 30.149053] handle_mm_fault+0x6d1/0xcb0
[ 30.151759] exc_page_fault+0x135/0x3b0
[ 30.154487] ? doublefault_shim+0x150/0x150
[ 30.157416] handle_exception+0x130/0x130
[ 30.160137] EIP: 0x804d29f
[ 30.162307] Code: 89 54 08 e1 89 54 08 e5 89 54 08 e9 89 54 08 ed c3 0f b6 44 24 08 89 7c 24 0c 69 c0 01 01 01 01 8b 7c 24 04 f7 c7 0f 0
0 00 00 <89> 44 0f fc 75 0e c1 e9 02 f3 ab 8b 44 24 04 8b 7c 24 0c c3 31 d2
[ 30.172936] EAX: 5a5a5a5a EBX: 00000000 ECX: 0c800000 EDX: 3a449000
[ 30.176927] ESI: 00000000 EDI: 3a449000 EBP: bfbbae18 ESP: bfbbadac
[ 30.180897] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00010246
[ 30.185161] ? doublefault_shim+0x150/0x150
[ 30.187979] ---[ end trace 0000000000000000 ]---
Bus error (core dumped) ./allocate_secret_i686 2000M
The equivalent bug was pointed out by a local Sashiko instance on
https://lore.kernel.org/all/20260410151746.61150-3-kalyazin@amazon.com/
This hasn't been reproduced it on older kernel versions but from code
inspection the bug seems to go back to the original introduction in
commit 1507f51255c9f ("mm: introduce memfd_secret system call to create
"secret" memory areas"). If this configuration has always been broken,
dropping support is not really a regression, so do that.
Link: https://github.com/bjackman/limmat-kernel-nix/commit/7b2acba2d3a5ef01400d493a155beb1d135b6bb5
Fixes: 1507f51255c9f ("mm: introduce memfd_secret system call to create "secret" memory areas")
Signed-off-by: Brendan Jackman <jackmanb@google.com>
---
Note this was found by Sashiko but in a local instance, so I can't
provide a link to the report and I guess it's technically inaccurate to
mention sashiko-bot@kernel.org.
---
mm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/Kconfig b/mm/Kconfig
index 04fe5171bb8c8..17c3b77b21a6a 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1356,7 +1356,7 @@ config MEMFD_CREATE
config SECRETMEM
default y
bool "Enable memfd_secret() system call" if EXPERT
- depends on ARCH_HAS_SET_DIRECT_MAP
+ depends on ARCH_HAS_SET_DIRECT_MAP && !HIGHMEM
help
Enable the memfd_secret() system call with the ability to create
memory areas visible only in the context of the owning process and
---
base-commit: 0efcf9df728408cdc9f78868f1753ec0c5319f7c
change-id: 20260703-secretmem-highmem-44eb42fda318
Best regards,
--
Brendan Jackman <jackmanb@google.com>
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/secretmem: disable under HIGHMEM
2026-07-03 14:48 [PATCH] mm/secretmem: disable under HIGHMEM Brendan Jackman
@ 2026-07-04 6:42 ` Mike Rapoport
2026-07-05 2:26 ` Andrew Morton
1 sibling, 0 replies; 5+ messages in thread
From: Mike Rapoport @ 2026-07-04 6:42 UTC (permalink / raw)
To: Brendan Jackman
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, linux-mm, linux-kernel
On Fri, Jul 03, 2026 at 02:48:26PM +0000, Brendan Jackman wrote:
> secretmem_fault() allocates a folio with GFP_HIGHUSER and then calls
> set_direct_map_valid_noflush() without checking folio_test_highmem().
> This causes a warning and process crash (vibe-coded reproducer in Link
> below):
>
> Link: https://github.com/bjackman/limmat-kernel-nix/commit/7b2acba2d3a5ef01400d493a155beb1d135b6bb5
> Fixes: 1507f51255c9f ("mm: introduce memfd_secret system call to create "secret" memory areas")
> Signed-off-by: Brendan Jackman <jackmanb@google.com>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/secretmem: disable under HIGHMEM
2026-07-03 14:48 [PATCH] mm/secretmem: disable under HIGHMEM Brendan Jackman
2026-07-04 6:42 ` Mike Rapoport
@ 2026-07-05 2:26 ` Andrew Morton
2026-07-05 10:46 ` Brendan Jackman
1 sibling, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2026-07-05 2:26 UTC (permalink / raw)
To: Brendan Jackman
Cc: David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
linux-mm, linux-kernel
On Fri, 03 Jul 2026 14:48:26 +0000 Brendan Jackman <jackmanb@google.com> wrote:
> secretmem_fault() allocates a folio with GFP_HIGHUSER and then calls
> set_direct_map_valid_noflush()
set_direct_map_invalid_noflush()?
> without checking folio_test_highmem().
> This causes a warning and process crash (vibe-coded reproducer in Link
> below):
>
> Su[ 30.071284] ------------[ cut here ]------------
> ccessfully allocated and mapped 2097152000 bytes at 0x3a449000
> Populating memor[ 30.074614] CPA: called for zero pte. vaddr = 0 cpa->vaddr = 0
> y...
> [ 30.078636] WARNING: arch/x86/mm/pat/set_memory.c:1840 at __cpa_process_fault+0x34d/0x360, CPU#5: allocate_secret/570
> [ 30.084789] CPU: 5 UID: 0 PID: 570 Comm: allocate_secret Not tainted 7.1.0-14063-g4edcdefd4083-dirty #10 PREEMPTLAZY
> [ 30.090937] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
> [ 30.097543] EIP: __cpa_process_fault+0x34d/0x360
> [ 30.100514] Code: ff ff 85 c0 0f 89 7d fe ff ff e9 3d fe ff ff 8b 03 8b 00 c7 04 24 c8 ff 64 c1 89 44 24 08 8b 45 e8 89 44 24 04 e8 53 7
> a 00 00 <0f> 0b c7 45 f0 f2 ff ff ff e9 fc fc ff ff 90 8d 74 26 00 55 25 00
> [ 30.110829] EAX: 00000000 EBX: f64afe98 ECX: 00000000 EDX: 00000000
> [ 30.114799] ESI: 00000000 EDI: f64afe98 EBP: f64afe04 ESP: f64afdcc
> [ 30.118785] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 EFLAGS: 00010246
> [ 30.123020] CR0: 80050033 CR2: 46c48ffc CR3: 038c8000 CR4: 00000690
> [ 30.127010] Call Trace:
> [ 30.129078] __change_page_attr_set_clr+0x5e7/0x870
> [ 30.132275] ? console_unlock+0x99/0x130
> [ 30.135069] ? irq_work_queue+0x36/0x70
> [ 30.137853] ? page_address+0xd3/0xf0
> [ 30.140421] set_direct_map_invalid_noflush+0x52/0x60
> [ 30.143782] secretmem_fault+0x128/0x210
> [ 30.146560] __do_fault+0x25/0x90
> [ 30.149053] handle_mm_fault+0x6d1/0xcb0
> [ 30.151759] exc_page_fault+0x135/0x3b0
> [ 30.154487] ? doublefault_shim+0x150/0x150
> [ 30.157416] handle_exception+0x130/0x130
> [ 30.160137] EIP: 0x804d29f
> [ 30.162307] Code: 89 54 08 e1 89 54 08 e5 89 54 08 e9 89 54 08 ed c3 0f b6 44 24 08 89 7c 24 0c 69 c0 01 01 01 01 8b 7c 24 04 f7 c7 0f 0
> 0 00 00 <89> 44 0f fc 75 0e c1 e9 02 f3 ab 8b 44 24 04 8b 7c 24 0c c3 31 d2
> [ 30.172936] EAX: 5a5a5a5a EBX: 00000000 ECX: 0c800000 EDX: 3a449000
> [ 30.176927] ESI: 00000000 EDI: 3a449000 EBP: bfbbae18 ESP: bfbbadac
> [ 30.180897] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00010246
> [ 30.185161] ? doublefault_shim+0x150/0x150
> [ 30.187979] ---[ end trace 0000000000000000 ]---
> Bus error (core dumped) ./allocate_secret_i686 2000M
>
> The equivalent bug was pointed out by a local Sashiko instance on
> https://lore.kernel.org/all/20260410151746.61150-3-kalyazin@amazon.com/
>
> This hasn't been reproduced it on older kernel versions but from code
> inspection the bug seems to go back to the original introduction in
> commit 1507f51255c9f ("mm: introduce memfd_secret system call to create
> "secret" memory areas"). If this configuration has always been broken,
> dropping support is not really a regression, so do that.
Well OK, but the secretmem code is still wrong. The patch protects
people from hitting the bug but leaves the bug in place. Surely it would be
better to fix the bug?
Is that as simple as adding the folio_test_highmem() test? Or switching to
GFP_KERNEL? You already have a reproducer (thanks), so this doesn't
sound like a lot of work?
(Should set_direct_map_invalid_noflush() WARN if passed a highmem page,
something like that?)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/secretmem: disable under HIGHMEM
2026-07-05 2:26 ` Andrew Morton
@ 2026-07-05 10:46 ` Brendan Jackman
2026-07-05 11:34 ` Mike Rapoport
0 siblings, 1 reply; 5+ messages in thread
From: Brendan Jackman @ 2026-07-05 10:46 UTC (permalink / raw)
To: Andrew Morton, Brendan Jackman
Cc: David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
linux-mm, linux-kernel
On Sun Jul 5, 2026 at 2:26 AM UTC, Andrew Morton wrote:
> On Fri, 03 Jul 2026 14:48:26 +0000 Brendan Jackman <jackmanb@google.com> wrote:
>
>> secretmem_fault() allocates a folio with GFP_HIGHUSER and then calls
>> set_direct_map_valid_noflush()
>
> set_direct_map_invalid_noflush()?
Yup thanks.
>> without checking folio_test_highmem().
>> This causes a warning and process crash (vibe-coded reproducer in Link
>> below):
>>
>> Su[ 30.071284] ------------[ cut here ]------------
>> ccessfully allocated and mapped 2097152000 bytes at 0x3a449000
>> Populating memor[ 30.074614] CPA: called for zero pte. vaddr = 0 cpa->vaddr = 0
>> y...
>> [ 30.078636] WARNING: arch/x86/mm/pat/set_memory.c:1840 at __cpa_process_fault+0x34d/0x360, CPU#5: allocate_secret/570
>> [ 30.084789] CPU: 5 UID: 0 PID: 570 Comm: allocate_secret Not tainted 7.1.0-14063-g4edcdefd4083-dirty #10 PREEMPTLAZY
>> [ 30.090937] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
>> [ 30.097543] EIP: __cpa_process_fault+0x34d/0x360
>> [ 30.100514] Code: ff ff 85 c0 0f 89 7d fe ff ff e9 3d fe ff ff 8b 03 8b 00 c7 04 24 c8 ff 64 c1 89 44 24 08 8b 45 e8 89 44 24 04 e8 53 7
>> a 00 00 <0f> 0b c7 45 f0 f2 ff ff ff e9 fc fc ff ff 90 8d 74 26 00 55 25 00
>> [ 30.110829] EAX: 00000000 EBX: f64afe98 ECX: 00000000 EDX: 00000000
>> [ 30.114799] ESI: 00000000 EDI: f64afe98 EBP: f64afe04 ESP: f64afdcc
>> [ 30.118785] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 EFLAGS: 00010246
>> [ 30.123020] CR0: 80050033 CR2: 46c48ffc CR3: 038c8000 CR4: 00000690
>> [ 30.127010] Call Trace:
>> [ 30.129078] __change_page_attr_set_clr+0x5e7/0x870
>> [ 30.132275] ? console_unlock+0x99/0x130
>> [ 30.135069] ? irq_work_queue+0x36/0x70
>> [ 30.137853] ? page_address+0xd3/0xf0
>> [ 30.140421] set_direct_map_invalid_noflush+0x52/0x60
>> [ 30.143782] secretmem_fault+0x128/0x210
>> [ 30.146560] __do_fault+0x25/0x90
>> [ 30.149053] handle_mm_fault+0x6d1/0xcb0
>> [ 30.151759] exc_page_fault+0x135/0x3b0
>> [ 30.154487] ? doublefault_shim+0x150/0x150
>> [ 30.157416] handle_exception+0x130/0x130
>> [ 30.160137] EIP: 0x804d29f
>> [ 30.162307] Code: 89 54 08 e1 89 54 08 e5 89 54 08 e9 89 54 08 ed c3 0f b6 44 24 08 89 7c 24 0c 69 c0 01 01 01 01 8b 7c 24 04 f7 c7 0f 0
>> 0 00 00 <89> 44 0f fc 75 0e c1 e9 02 f3 ab 8b 44 24 04 8b 7c 24 0c c3 31 d2
>> [ 30.172936] EAX: 5a5a5a5a EBX: 00000000 ECX: 0c800000 EDX: 3a449000
>> [ 30.176927] ESI: 00000000 EDI: 3a449000 EBP: bfbbae18 ESP: bfbbadac
>> [ 30.180897] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00010246
>> [ 30.185161] ? doublefault_shim+0x150/0x150
>> [ 30.187979] ---[ end trace 0000000000000000 ]---
>> Bus error (core dumped) ./allocate_secret_i686 2000M
>>
>> The equivalent bug was pointed out by a local Sashiko instance on
>> https://lore.kernel.org/all/20260410151746.61150-3-kalyazin@amazon.com/
>>
>> This hasn't been reproduced it on older kernel versions but from code
>> inspection the bug seems to go back to the original introduction in
>> commit 1507f51255c9f ("mm: introduce memfd_secret system call to create
>> "secret" memory areas"). If this configuration has always been broken,
>> dropping support is not really a regression, so do that.
>
> Well OK, but the secretmem code is still wrong. The patch protects
> people from hitting the bug but leaves the bug in place. Surely it would be
> better to fix the bug?
I don't think the code is wrong if highmem is disabled. Certainly
there is an implicit coupling between the .c file and the Kconfig file,
but we could always add a BUILD_BUG_ON(IS_ENABLED(CONFIG_SECRETMEM)) to
the relevant bit of code to make it explicit.
> Is that as simple as adding the folio_test_highmem() test?
This would fix the WARN+SIGBUS but I don't think it resolves the fact
that this configuration is completely untested - there are likely other
functional bugs? But more importantly, I am not sure if secretmem
actually does its security job if kmap_local_page() isn't a NOP. I
think shipping a "security feature" that doesn't do what it says would
be really terrible. (It might work totally fine, I dunno, but it would
require some research and deep thinking that I don't really want to do
for a configuration with no users).
> Or switching to GFP_KERNEL?
... Oh, that's a nice idea though :)
Any thoughts from Mike on that? I think it might be just as good as this
patch? And then you can still use secretmem reliably on a 32bit build
as long as you have <1G RAM (or whatever the limit is).
> You already have a reproducer (thanks), so this doesn't
> sound like a lot of work?
>
> (Should set_direct_map_invalid_noflush() WARN if passed a highmem page,
> something like that?)
The message is a bit weird ("called for zero pte") and the code seems
fiddlier than it needs to be, but to me it looks like the x86 code is
handling this correctly. __cpa_addr() returns 0 and
then __cpa_process_fault() WARNs.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/secretmem: disable under HIGHMEM
2026-07-05 10:46 ` Brendan Jackman
@ 2026-07-05 11:34 ` Mike Rapoport
0 siblings, 0 replies; 5+ messages in thread
From: Mike Rapoport @ 2026-07-05 11:34 UTC (permalink / raw)
To: Brendan Jackman
Cc: Andrew Morton, Brendan Jackman, David Hildenbrand,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Suren Baghdasaryan, Michal Hocko, linux-mm, linux-kernel
On Sun, Jul 05, 2026 at 10:46:19AM +0000, Brendan Jackman wrote:
> On Sun Jul 5, 2026 at 2:26 AM UTC, Andrew Morton wrote:
> >
> > Well OK, but the secretmem code is still wrong. The patch protects
> > people from hitting the bug but leaves the bug in place. Surely it would be
> > better to fix the bug?
>
> I don't think the code is wrong if highmem is disabled. Certainly
> there is an implicit coupling between the .c file and the Kconfig file,
> but we could always add a BUILD_BUG_ON(IS_ENABLED(CONFIG_SECRETMEM)) to
> the relevant bit of code to make it explicit.
>
> > Is that as simple as adding the folio_test_highmem() test?
>
> This would fix the WARN+SIGBUS but I don't think it resolves the fact
> that this configuration is completely untested - there are likely other
> functional bugs? But more importantly, I am not sure if secretmem
> actually does its security job if kmap_local_page() isn't a NOP. I
> think shipping a "security feature" that doesn't do what it says would
> be really terrible. (It might work totally fine, I dunno, but it would
> require some research and deep thinking that I don't really want to do
> for a configuration with no users).
>
> > Or switching to GFP_KERNEL?
>
> ... Oh, that's a nice idea though :)
GFP_USER if anything :)
But still with kmap() and friends not being an NOP the promise "kernel does
not map this memory" does not hold.
I think that keeping SECRETMEM and HIGHMEM mutually exclusive is
conceptually correct.
> Any thoughts from Mike on that? I think it might be just as good as this
> patch? And then you can still use secretmem reliably on a 32bit build
> as long as you have <1G RAM (or whatever the limit is).
With <1G RAM there is no need for HIGHMEM :)
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-05 11:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-03 14:48 [PATCH] mm/secretmem: disable under HIGHMEM Brendan Jackman
2026-07-04 6:42 ` Mike Rapoport
2026-07-05 2:26 ` Andrew Morton
2026-07-05 10:46 ` Brendan Jackman
2026-07-05 11:34 ` Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox