linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [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