* [PATCH] mm: unexport globally copy_to_kernel_nofault
@ 2025-06-22 5:19 Sabyrzhan Tasbolatov
2025-06-22 13:00 ` Andrey Konovalov
0 siblings, 1 reply; 8+ messages in thread
From: Sabyrzhan Tasbolatov @ 2025-06-22 5:19 UTC (permalink / raw)
To: ryabinin.a.a, hch, elver, arnd, glider, andreyknvl
Cc: dvyukov, vincenzo.frascino, akpm, david, kasan-dev, linux-mm,
linux-kernel, snovitoll
`copy_to_kernel_nofault()` is an internal helper which should not be
visible to loadable modules – exporting it would give exploit code a
cheap oracle to probe kernel addresses. Instead, keep the helper
un-exported and compile the kunit case that exercises it only when
`mm/kasan/kasan_test.o` is linked into vmlinux.
Fixes: ca79a00bb9a8 ("kasan: migrate copy_user_test to kunit")
Suggested-by: Christoph Hellwig <hch@infradead.org>
Suggested-by: Marco Elver <elver@google.com>
Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com>
---
mm/kasan/kasan_test_c.c | 4 ++++
mm/maccess.c | 1 -
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c
index 5f922dd38ffa..094ecd27b707 100644
--- a/mm/kasan/kasan_test_c.c
+++ b/mm/kasan/kasan_test_c.c
@@ -1977,6 +1977,7 @@ static void rust_uaf(struct kunit *test)
KUNIT_EXPECT_KASAN_FAIL(test, kasan_test_rust_uaf());
}
+#ifndef MODULE
static void copy_to_kernel_nofault_oob(struct kunit *test)
{
char *ptr;
@@ -2011,6 +2012,7 @@ static void copy_to_kernel_nofault_oob(struct kunit *test)
kfree(ptr);
}
+#endif /* !MODULE */
static void copy_user_test_oob(struct kunit *test)
{
@@ -2131,7 +2133,9 @@ static struct kunit_case kasan_kunit_test_cases[] = {
KUNIT_CASE(match_all_not_assigned),
KUNIT_CASE(match_all_ptr_tag),
KUNIT_CASE(match_all_mem_tag),
+#ifndef MODULE
KUNIT_CASE(copy_to_kernel_nofault_oob),
+#endif
KUNIT_CASE(rust_uaf),
KUNIT_CASE(copy_user_test_oob),
{}
diff --git a/mm/maccess.c b/mm/maccess.c
index 831b4dd7296c..486559d68858 100644
--- a/mm/maccess.c
+++ b/mm/maccess.c
@@ -82,7 +82,6 @@ long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
pagefault_enable();
return -EFAULT;
}
-EXPORT_SYMBOL_GPL(copy_to_kernel_nofault);
long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
{
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] mm: unexport globally copy_to_kernel_nofault
2025-06-22 5:19 [PATCH] mm: unexport globally copy_to_kernel_nofault Sabyrzhan Tasbolatov
@ 2025-06-22 13:00 ` Andrey Konovalov
2025-06-22 14:11 ` [PATCH v2] " Sabyrzhan Tasbolatov
0 siblings, 1 reply; 8+ messages in thread
From: Andrey Konovalov @ 2025-06-22 13:00 UTC (permalink / raw)
To: Sabyrzhan Tasbolatov
Cc: ryabinin.a.a, hch, elver, arnd, glider, dvyukov,
vincenzo.frascino, akpm, david, kasan-dev, linux-mm,
linux-kernel
On Sun, Jun 22, 2025 at 7:19 AM Sabyrzhan Tasbolatov
<snovitoll@gmail.com> wrote:
>
> `copy_to_kernel_nofault()` is an internal helper which should not be
> visible to loadable modules – exporting it would give exploit code a
> cheap oracle to probe kernel addresses. Instead, keep the helper
> un-exported and compile the kunit case that exercises it only when
> `mm/kasan/kasan_test.o` is linked into vmlinux.
>
> Fixes: ca79a00bb9a8 ("kasan: migrate copy_user_test to kunit")
> Suggested-by: Christoph Hellwig <hch@infradead.org>
> Suggested-by: Marco Elver <elver@google.com>
> Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com>
> ---
> mm/kasan/kasan_test_c.c | 4 ++++
> mm/maccess.c | 1 -
> 2 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c
> index 5f922dd38ffa..094ecd27b707 100644
> --- a/mm/kasan/kasan_test_c.c
> +++ b/mm/kasan/kasan_test_c.c
> @@ -1977,6 +1977,7 @@ static void rust_uaf(struct kunit *test)
> KUNIT_EXPECT_KASAN_FAIL(test, kasan_test_rust_uaf());
> }
>
> +#ifndef MODULE
Would be great to have a comment here explaining the ifndef.
> static void copy_to_kernel_nofault_oob(struct kunit *test)
> {
> char *ptr;
> @@ -2011,6 +2012,7 @@ static void copy_to_kernel_nofault_oob(struct kunit *test)
>
> kfree(ptr);
> }
> +#endif /* !MODULE */
>
> static void copy_user_test_oob(struct kunit *test)
> {
> @@ -2131,7 +2133,9 @@ static struct kunit_case kasan_kunit_test_cases[] = {
> KUNIT_CASE(match_all_not_assigned),
> KUNIT_CASE(match_all_ptr_tag),
> KUNIT_CASE(match_all_mem_tag),
> +#ifndef MODULE
> KUNIT_CASE(copy_to_kernel_nofault_oob),
> +#endif
> KUNIT_CASE(rust_uaf),
> KUNIT_CASE(copy_user_test_oob),
> {}
> diff --git a/mm/maccess.c b/mm/maccess.c
> index 831b4dd7296c..486559d68858 100644
> --- a/mm/maccess.c
> +++ b/mm/maccess.c
> @@ -82,7 +82,6 @@ long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
> pagefault_enable();
> return -EFAULT;
> }
> -EXPORT_SYMBOL_GPL(copy_to_kernel_nofault);
>
> long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
> {
> --
> 2.34.1
>
Other than that:
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Thank you!
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] mm: unexport globally copy_to_kernel_nofault
2025-06-22 13:00 ` Andrey Konovalov
@ 2025-06-22 14:11 ` Sabyrzhan Tasbolatov
2025-06-22 17:44 ` Arnd Bergmann
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Sabyrzhan Tasbolatov @ 2025-06-22 14:11 UTC (permalink / raw)
To: andreyknvl
Cc: akpm, arnd, david, dvyukov, elver, glider, hch, kasan-dev,
linux-kernel, linux-mm, ryabinin.a.a, snovitoll,
vincenzo.frascino
`copy_to_kernel_nofault()` is an internal helper which should not be
visible to loadable modules – exporting it would give exploit code a
cheap oracle to probe kernel addresses. Instead, keep the helper
un-exported and compile the kunit case that exercises it only when
`mm/kasan/kasan_test.o` is linked into vmlinux.
Fixes: ca79a00bb9a8 ("kasan: migrate copy_user_test to kunit")
Suggested-by: Christoph Hellwig <hch@infradead.org>
Suggested-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com>
---
Changes v2:
- add a brief comment to `#ifndef MODULE`
---
mm/kasan/kasan_test_c.c | 8 ++++++++
mm/maccess.c | 1 -
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c
index 5f922dd38ffa..2aa12dfa427a 100644
--- a/mm/kasan/kasan_test_c.c
+++ b/mm/kasan/kasan_test_c.c
@@ -1977,6 +1977,11 @@ static void rust_uaf(struct kunit *test)
KUNIT_EXPECT_KASAN_FAIL(test, kasan_test_rust_uaf());
}
+/*
+ * copy_to_kernel_nofault() is an internal helper available when
+ * kasan_test is built-in, so it must not be visible to loadable modules.
+ */
+#ifndef MODULE
static void copy_to_kernel_nofault_oob(struct kunit *test)
{
char *ptr;
@@ -2011,6 +2016,7 @@ static void copy_to_kernel_nofault_oob(struct kunit *test)
kfree(ptr);
}
+#endif /* !MODULE */
static void copy_user_test_oob(struct kunit *test)
{
@@ -2131,7 +2137,9 @@ static struct kunit_case kasan_kunit_test_cases[] = {
KUNIT_CASE(match_all_not_assigned),
KUNIT_CASE(match_all_ptr_tag),
KUNIT_CASE(match_all_mem_tag),
+#ifndef MODULE
KUNIT_CASE(copy_to_kernel_nofault_oob),
+#endif
KUNIT_CASE(rust_uaf),
KUNIT_CASE(copy_user_test_oob),
{}
diff --git a/mm/maccess.c b/mm/maccess.c
index 831b4dd7296c..486559d68858 100644
--- a/mm/maccess.c
+++ b/mm/maccess.c
@@ -82,7 +82,6 @@ long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
pagefault_enable();
return -EFAULT;
}
-EXPORT_SYMBOL_GPL(copy_to_kernel_nofault);
long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
{
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: unexport globally copy_to_kernel_nofault
2025-06-22 14:11 ` [PATCH v2] " Sabyrzhan Tasbolatov
@ 2025-06-22 17:44 ` Arnd Bergmann
2025-06-22 18:20 ` Andrew Morton
2025-06-23 8:09 ` David Hildenbrand
2 siblings, 0 replies; 8+ messages in thread
From: Arnd Bergmann @ 2025-06-22 17:44 UTC (permalink / raw)
To: Sabyrzhan Tasbolatov, Andrey Konovalov
Cc: Andrew Morton, David Hildenbrand, Dmitry Vyukov, Marco Elver,
Alexander Potapenko, Christoph Hellwig, kasan-dev, linux-kernel,
linux-mm, Andrey Ryabinin, Vincenzo Frascino
On Sun, Jun 22, 2025, at 16:11, Sabyrzhan Tasbolatov wrote:
> `copy_to_kernel_nofault()` is an internal helper which should not be
> visible to loadable modules – exporting it would give exploit code a
> cheap oracle to probe kernel addresses. Instead, keep the helper
> un-exported and compile the kunit case that exercises it only when
> `mm/kasan/kasan_test.o` is linked into vmlinux.
>
> Fixes: ca79a00bb9a8 ("kasan: migrate copy_user_test to kunit")
> Suggested-by: Christoph Hellwig <hch@infradead.org>
> Suggested-by: Marco Elver <elver@google.com>
> Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
> Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: unexport globally copy_to_kernel_nofault
2025-06-22 14:11 ` [PATCH v2] " Sabyrzhan Tasbolatov
2025-06-22 17:44 ` Arnd Bergmann
@ 2025-06-22 18:20 ` Andrew Morton
2025-06-22 19:09 ` Sabyrzhan Tasbolatov
2025-06-23 8:09 ` David Hildenbrand
2 siblings, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2025-06-22 18:20 UTC (permalink / raw)
To: Sabyrzhan Tasbolatov
Cc: andreyknvl, arnd, david, dvyukov, elver, glider, hch, kasan-dev,
linux-kernel, linux-mm, ryabinin.a.a, vincenzo.frascino
On Sun, 22 Jun 2025 19:11:42 +0500 Sabyrzhan Tasbolatov <snovitoll@gmail.com> wrote:
> `copy_to_kernel_nofault()` is an internal helper which should not be
> visible to loadable modules – exporting it would give exploit code a
> cheap oracle to probe kernel addresses. Instead, keep the helper
> un-exported and compile the kunit case that exercises it only when
> `mm/kasan/kasan_test.o` is linked into vmlinux.
The recent 707f853d7fa3 ("module: Provide
EXPORT_SYMBOL_GPL_FOR_MODULES() helper") quietly added a thing which
might be useful here. As far as I understand it, this will permit us
to export copy_to_kernel_nofault to kasan_test_c.o and to nothing else.
"might". It depends on how "exploit code" might get hold of the
symbol. Perhaps you/we can discuss this further. Is the problem that
copy_to_kernel_nofault() is non-static? Or it the problem that
"exploit code" is itself a kernel module?
In other words, a fuller investigation of how this export presently benefits
exploiters would help us understand how much
EXPORT_SYMBOL_GPL_FOR_MODULES() will improve the situation.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: unexport globally copy_to_kernel_nofault
2025-06-22 18:20 ` Andrew Morton
@ 2025-06-22 19:09 ` Sabyrzhan Tasbolatov
2025-06-22 23:45 ` Andrey Konovalov
0 siblings, 1 reply; 8+ messages in thread
From: Sabyrzhan Tasbolatov @ 2025-06-22 19:09 UTC (permalink / raw)
To: Andrew Morton
Cc: andreyknvl, arnd, david, dvyukov, elver, glider, hch, kasan-dev,
linux-kernel, linux-mm, ryabinin.a.a, vincenzo.frascino
On Sun, Jun 22, 2025 at 11:20 PM Andrew Morton
<akpm@linux-foundation.org> wrote:
>
> On Sun, 22 Jun 2025 19:11:42 +0500 Sabyrzhan Tasbolatov <snovitoll@gmail.com> wrote:
>
> > `copy_to_kernel_nofault()` is an internal helper which should not be
> > visible to loadable modules – exporting it would give exploit code a
> > cheap oracle to probe kernel addresses. Instead, keep the helper
> > un-exported and compile the kunit case that exercises it only when
> > `mm/kasan/kasan_test.o` is linked into vmlinux.
>
> The recent 707f853d7fa3 ("module: Provide
> EXPORT_SYMBOL_GPL_FOR_MODULES() helper") quietly added a thing which
> might be useful here. As far as I understand it, this will permit us
> to export copy_to_kernel_nofault to kasan_test_c.o and to nothing else.
Thanks for letting me know about this new method.
I believe, the usage for our case is:
EXPORT_SYMBOL_GPL_FOR_MODULES(copy_to_kernel_nofault, "kasan_test");
>
> "might". It depends on how "exploit code" might get hold of the
> symbol. Perhaps you/we can discuss this further. Is the problem that
> copy_to_kernel_nofault() is non-static? Or it the problem that
> "exploit code" is itself a kernel module?
I haven't verified this, but theoretically, it's a handy
“write-anywhere-safely” ROP gadget.
Assume the attacker has already gained an arbitrary RW primitive
via a UAF/OOB bug. Instead of stitching together
prepare_kernel_cred() + commit_creds(), which is a common path
of using exported symbols to achieve privilege escalation.
This path needs two symbols and register juggling.
With exported copy_to_kernel_nofault() they can do this:
/* Pseudocode of exploit for a ROP stage running in kernel context */
struct cred *cred = leaked_pointer;
rop_call(copy_to_kernel_nofault, &cred->uid, &zero, 4)
copy_to_kernel_nofault() disables page-faults around the write,
so even if cred corupts a guard-page, the write will not crash.
>
> In other words, a fuller investigation of how this export presently benefits
> exploiters would help us understand how much
> EXPORT_SYMBOL_GPL_FOR_MODULES() will improve the situation.
>
Please let me know if I should send v3 with using
EXPORT_SYMBOL_GPL_FOR_MODULES(copy_to_kernel_nofault, "kasan_test");
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: unexport globally copy_to_kernel_nofault
2025-06-22 19:09 ` Sabyrzhan Tasbolatov
@ 2025-06-22 23:45 ` Andrey Konovalov
0 siblings, 0 replies; 8+ messages in thread
From: Andrey Konovalov @ 2025-06-22 23:45 UTC (permalink / raw)
To: Sabyrzhan Tasbolatov, Andrew Morton
Cc: arnd, david, dvyukov, elver, glider, hch, kasan-dev,
linux-kernel, linux-mm, ryabinin.a.a, vincenzo.frascino
On Sun, Jun 22, 2025 at 9:09 PM Sabyrzhan Tasbolatov
<snovitoll@gmail.com> wrote:
>
> I haven't verified this, but theoretically, it's a handy
> “write-anywhere-safely” ROP gadget.
> Assume the attacker has already gained an arbitrary RW primitive
> via a UAF/OOB bug. Instead of stitching together
> prepare_kernel_cred() + commit_creds(), which is a common path
> of using exported symbols to achieve privilege escalation.
> This path needs two symbols and register juggling.
> With exported copy_to_kernel_nofault() they can do this:
>
> /* Pseudocode of exploit for a ROP stage running in kernel context */
> struct cred *cred = leaked_pointer;
> rop_call(copy_to_kernel_nofault, &cred->uid, &zero, 4)
>
> copy_to_kernel_nofault() disables page-faults around the write,
> so even if cred corupts a guard-page, the write will not crash.
Attacker can use copy_to_kernel_nofault without it being exported as well.
So I'd say this patch is more of a clean-up of exports.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: unexport globally copy_to_kernel_nofault
2025-06-22 14:11 ` [PATCH v2] " Sabyrzhan Tasbolatov
2025-06-22 17:44 ` Arnd Bergmann
2025-06-22 18:20 ` Andrew Morton
@ 2025-06-23 8:09 ` David Hildenbrand
2 siblings, 0 replies; 8+ messages in thread
From: David Hildenbrand @ 2025-06-23 8:09 UTC (permalink / raw)
To: Sabyrzhan Tasbolatov, andreyknvl
Cc: akpm, arnd, dvyukov, elver, glider, hch, kasan-dev, linux-kernel,
linux-mm, ryabinin.a.a, vincenzo.frascino
On 22.06.25 16:11, Sabyrzhan Tasbolatov wrote:
> `copy_to_kernel_nofault()` is an internal helper which should not be
> visible to loadable modules – exporting it would give exploit code a
> cheap oracle to probe kernel addresses. Instead, keep the helper
> un-exported and compile the kunit case that exercises it only when
> `mm/kasan/kasan_test.o` is linked into vmlinux.
>
> Fixes: ca79a00bb9a8 ("kasan: migrate copy_user_test to kunit")
> Suggested-by: Christoph Hellwig <hch@infradead.org>
> Suggested-by: Marco Elver <elver@google.com>
> Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
> Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com>
> ---
Acked-by: David Hildenbrand <david@redhat.com>
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-06-23 8:09 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-22 5:19 [PATCH] mm: unexport globally copy_to_kernel_nofault Sabyrzhan Tasbolatov
2025-06-22 13:00 ` Andrey Konovalov
2025-06-22 14:11 ` [PATCH v2] " Sabyrzhan Tasbolatov
2025-06-22 17:44 ` Arnd Bergmann
2025-06-22 18:20 ` Andrew Morton
2025-06-22 19:09 ` Sabyrzhan Tasbolatov
2025-06-22 23:45 ` Andrey Konovalov
2025-06-23 8:09 ` David Hildenbrand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox