* [PATCH] [RFC] instrumented.h: mark instrument_write non-const
@ 2026-11-11 9:21 Arnd Bergmann
2026-11-11 9:59 ` Marco Elver
0 siblings, 1 reply; 3+ messages in thread
From: Arnd Bergmann @ 2026-11-11 9:21 UTC (permalink / raw)
To: Andrey Ryabinin, Andrew Morton, Marco Elver, Alexander Potapenko
Cc: Arnd Bergmann, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Andrey Konovalov,
Dmitry Vyukov, Vincenzo Frascino, Steffen Eiden,
Aleksei Nikiforov, Andreas Grapentin, Finn Thain, Peter Zijlstra,
Anshuman Khandual, David Hildenbrand, linux-s390, linux-kernel,
kasan-dev, linux-mm
From: Arnd Bergmann <arnd@arndb.de>
I got another instance of a -Wmaybe-uninitialized in ntfs, as this is
the only place that enables the warning:
In file included from include/asm-generic/rwonce.h:26,
from fs/ntfs3/file.c:10:
In function 'instrument_copy_from_user_before',
inlined from '_inline_copy_from_user' at include/linux/uaccess.h:184:2,
inlined from 'copy_from_user' at include/linux/uaccess.h:222:9,
inlined from 'ntfs_ioctl_fitrim' at fs/ntfs3/file.c:78:6,
inlined from 'ntfs_ioctl' at fs/ntfs3/file.c:246:10:
include/linux/kasan-checks.h:38:27: error: 'range' may be used uninitialized [-Werror=maybe-uninitialized]
38 | #define kasan_check_write __kasan_check_write
include/linux/instrumented.h:146:9: note: in expansion of macro 'kasan_check_write'
146 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~
include/linux/kasan-checks.h: In function 'ntfs_ioctl':
include/linux/kasan-checks.h:20:6: note: by argument 1 of type 'const volatile void *' to '__kasan_check_write' declared here
20 | bool __kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~~~
fs/ntfs3/file.c:66:29: note: 'range' declared here
66 | struct fstrim_range range;
| ^~~~~
The problem here is that copy_from_user() is called on an uninitialized
object, but the instrumentation passes the pointer into a function that
takes a const object. gcc deduces that any access to that object is
undefined behavior and warns about it.
The only workaround I could come up with is to remove the 'const' keyword
from these annotations, which of course is not great either, as the
functions do not actually access the data at all.
This also found incorrect 'const' annotations in
arch/s390/include/asm/fpu-insn.h, which writes to those pointers.
Any ideas?
Fixes: 33b75c1d884e ("instrumented.h: allow instrumenting both sides of copy_from_user()")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/s390/include/asm/fpu-insn.h | 8 ++++----
include/linux/instrumented.h | 10 +++++-----
include/linux/kasan-checks.h | 6 +++---
mm/kasan/shadow.c | 2 +-
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h
index aaf1faeb3dc5..7cd6e9f30485 100644
--- a/arch/s390/include/asm/fpu-insn.h
+++ b/arch/s390/include/asm/fpu-insn.h
@@ -359,7 +359,7 @@ static __always_inline void fpu_vsrlb(u8 v1, u8 v2, u8 v3)
#ifdef CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS
-static __always_inline void fpu_vst(u8 v1, const void *vxr)
+static __always_inline void fpu_vst(u8 v1, void *vxr)
{
instrument_write(vxr, sizeof(__vector128));
asm volatile("VST %[v1],%O[vxr],,%R[vxr]"
@@ -370,7 +370,7 @@ static __always_inline void fpu_vst(u8 v1, const void *vxr)
#else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
-static __always_inline void fpu_vst(u8 v1, const void *vxr)
+static __always_inline void fpu_vst(u8 v1, void *vxr)
{
instrument_write(vxr, sizeof(__vector128));
asm volatile(
@@ -385,7 +385,7 @@ static __always_inline void fpu_vst(u8 v1, const void *vxr)
#ifdef CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS
-static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
+static __always_inline void fpu_vstl(u8 v1, u32 index, void *vxr)
{
unsigned int size;
@@ -400,7 +400,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
#else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
-static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
+static __always_inline void fpu_vstl(u8 v1, u32 index, void *vxr)
{
unsigned int size;
diff --git a/include/linux/instrumented.h b/include/linux/instrumented.h
index a1b4cf81adc2..d28aa6b0aeb8 100644
--- a/include/linux/instrumented.h
+++ b/include/linux/instrumented.h
@@ -36,7 +36,7 @@ static __always_inline void instrument_read(const volatile void *v, size_t size)
* Instrument a regular write access. The instrumentation should be inserted
* before the actual write happens.
*/
-static __always_inline void instrument_write(const volatile void *v, size_t size)
+static __always_inline void instrument_write(volatile void *v, size_t size)
{
kasan_check_write(v, size);
kcsan_check_write(v, size);
@@ -50,7 +50,7 @@ static __always_inline void instrument_write(const volatile void *v, size_t size
* Instrument a regular write access. The instrumentation should be inserted
* before the actual write happens.
*/
-static __always_inline void instrument_read_write(const volatile void *v, size_t size)
+static __always_inline void instrument_read_write(volatile void *v, size_t size)
{
kasan_check_write(v, size);
kcsan_check_read_write(v, size);
@@ -92,7 +92,7 @@ static __always_inline void instrument_atomic_read(const volatile void *v, size_
* Instrument an atomic write access. The instrumentation should be inserted
* before the actual write happens.
*/
-static __always_inline void instrument_atomic_write(const volatile void *v, size_t size)
+static __always_inline void instrument_atomic_write(volatile void *v, size_t size)
{
kasan_check_write(v, size);
kcsan_check_atomic_write(v, size);
@@ -107,7 +107,7 @@ static __always_inline void instrument_atomic_write(const volatile void *v, size
* Instrument an atomic read-write access. The instrumentation should be
* inserted before the actual write happens.
*/
-static __always_inline void instrument_atomic_read_write(const volatile void *v, size_t size)
+static __always_inline void instrument_atomic_read_write(volatile void *v, size_t size)
{
kasan_check_write(v, size);
kcsan_check_atomic_read_write(v, size);
@@ -141,7 +141,7 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
* variants). The instrumentation should be inserted before the accesses.
*/
static __always_inline void
-instrument_copy_from_user_before(const void *to, const void __user *from, unsigned long n)
+instrument_copy_from_user_before(void *to, const void __user *from, unsigned long n)
{
kasan_check_write(to, n);
kcsan_check_write(to, n);
diff --git a/include/linux/kasan-checks.h b/include/linux/kasan-checks.h
index 3d6d22a25bdc..90b878b876f5 100644
--- a/include/linux/kasan-checks.h
+++ b/include/linux/kasan-checks.h
@@ -17,13 +17,13 @@
*/
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
bool __kasan_check_read(const volatile void *p, unsigned int size);
-bool __kasan_check_write(const volatile void *p, unsigned int size);
+bool __kasan_check_write(volatile void *p, unsigned int size);
#else
static inline bool __kasan_check_read(const volatile void *p, unsigned int size)
{
return true;
}
-static inline bool __kasan_check_write(const volatile void *p, unsigned int size)
+static inline bool __kasan_check_write(volatile void *p, unsigned int size)
{
return true;
}
@@ -41,7 +41,7 @@ static inline bool kasan_check_read(const volatile void *p, unsigned int size)
{
return true;
}
-static inline bool kasan_check_write(const volatile void *p, unsigned int size)
+static inline bool kasan_check_write(volatile void *p, unsigned int size)
{
return true;
}
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index d286e0a04543..591c179164af 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -32,7 +32,7 @@ bool __kasan_check_read(const volatile void *p, unsigned int size)
}
EXPORT_SYMBOL(__kasan_check_read);
-bool __kasan_check_write(const volatile void *p, unsigned int size)
+bool __kasan_check_write(volatile void *p, unsigned int size)
{
return kasan_check_range((void *)p, size, true, _RET_IP_);
}
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] [RFC] instrumented.h: mark instrument_write non-const
2026-11-11 9:21 [PATCH] [RFC] instrumented.h: mark instrument_write non-const Arnd Bergmann
@ 2026-11-11 9:59 ` Marco Elver
2026-11-11 10:23 ` Peter Zijlstra
0 siblings, 1 reply; 3+ messages in thread
From: Marco Elver @ 2026-11-11 9:59 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrey Ryabinin, Andrew Morton, Alexander Potapenko,
Arnd Bergmann, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Andrey Konovalov,
Dmitry Vyukov, Vincenzo Frascino, Steffen Eiden,
Aleksei Nikiforov, Andreas Grapentin, Finn Thain, Peter Zijlstra,
Anshuman Khandual, David Hildenbrand, linux-s390, linux-kernel,
kasan-dev, linux-mm
On Wed, 11 Nov 2026 at 10:22, Arnd Bergmann <arnd@kernel.org> wrote:
>
> From: Arnd Bergmann <arnd@arndb.de>
>
> I got another instance of a -Wmaybe-uninitialized in ntfs, as this is
> the only place that enables the warning:
>
> In file included from include/asm-generic/rwonce.h:26,
> from fs/ntfs3/file.c:10:
> In function 'instrument_copy_from_user_before',
> inlined from '_inline_copy_from_user' at include/linux/uaccess.h:184:2,
> inlined from 'copy_from_user' at include/linux/uaccess.h:222:9,
> inlined from 'ntfs_ioctl_fitrim' at fs/ntfs3/file.c:78:6,
> inlined from 'ntfs_ioctl' at fs/ntfs3/file.c:246:10:
> include/linux/kasan-checks.h:38:27: error: 'range' may be used uninitialized [-Werror=maybe-uninitialized]
> 38 | #define kasan_check_write __kasan_check_write
> include/linux/instrumented.h:146:9: note: in expansion of macro 'kasan_check_write'
> 146 | kasan_check_write(to, n);
> | ^~~~~~~~~~~~~~~~~
> include/linux/kasan-checks.h: In function 'ntfs_ioctl':
> include/linux/kasan-checks.h:20:6: note: by argument 1 of type 'const volatile void *' to '__kasan_check_write' declared here
> 20 | bool __kasan_check_write(const volatile void *p, unsigned int size);
> | ^~~~~~~~~~~~~~~~~~~
> fs/ntfs3/file.c:66:29: note: 'range' declared here
> 66 | struct fstrim_range range;
> | ^~~~~
>
> The problem here is that copy_from_user() is called on an uninitialized
> object, but the instrumentation passes the pointer into a function that
> takes a const object. gcc deduces that any access to that object is
> undefined behavior and warns about it.
>
> The only workaround I could come up with is to remove the 'const' keyword
> from these annotations, which of course is not great either, as the
> functions do not actually access the data at all.
Agree, but the code where a real 'write' happens ought to never pass
in a const-qualified variable or pointer anyway, so I think it's fine.
> This also found incorrect 'const' annotations in
> arch/s390/include/asm/fpu-insn.h, which writes to those pointers.
That looks like a bug. Maybe split it into a separate patch.
> Any ideas?
>
> Fixes: 33b75c1d884e ("instrumented.h: allow instrumenting both sides of copy_from_user()")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
If there are no warnings that appear because of this elsewhere, then:
Acked-by: Marco Elver <elver@google.com>
> ---
> arch/s390/include/asm/fpu-insn.h | 8 ++++----
> include/linux/instrumented.h | 10 +++++-----
> include/linux/kasan-checks.h | 6 +++---
> mm/kasan/shadow.c | 2 +-
> 4 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h
> index aaf1faeb3dc5..7cd6e9f30485 100644
> --- a/arch/s390/include/asm/fpu-insn.h
> +++ b/arch/s390/include/asm/fpu-insn.h
> @@ -359,7 +359,7 @@ static __always_inline void fpu_vsrlb(u8 v1, u8 v2, u8 v3)
>
> #ifdef CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS
>
> -static __always_inline void fpu_vst(u8 v1, const void *vxr)
> +static __always_inline void fpu_vst(u8 v1, void *vxr)
> {
> instrument_write(vxr, sizeof(__vector128));
> asm volatile("VST %[v1],%O[vxr],,%R[vxr]"
> @@ -370,7 +370,7 @@ static __always_inline void fpu_vst(u8 v1, const void *vxr)
>
> #else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
>
> -static __always_inline void fpu_vst(u8 v1, const void *vxr)
> +static __always_inline void fpu_vst(u8 v1, void *vxr)
> {
> instrument_write(vxr, sizeof(__vector128));
> asm volatile(
> @@ -385,7 +385,7 @@ static __always_inline void fpu_vst(u8 v1, const void *vxr)
>
> #ifdef CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS
>
> -static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
> +static __always_inline void fpu_vstl(u8 v1, u32 index, void *vxr)
> {
> unsigned int size;
>
> @@ -400,7 +400,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
>
> #else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
>
> -static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
> +static __always_inline void fpu_vstl(u8 v1, u32 index, void *vxr)
> {
> unsigned int size;
>
> diff --git a/include/linux/instrumented.h b/include/linux/instrumented.h
> index a1b4cf81adc2..d28aa6b0aeb8 100644
> --- a/include/linux/instrumented.h
> +++ b/include/linux/instrumented.h
> @@ -36,7 +36,7 @@ static __always_inline void instrument_read(const volatile void *v, size_t size)
> * Instrument a regular write access. The instrumentation should be inserted
> * before the actual write happens.
> */
> -static __always_inline void instrument_write(const volatile void *v, size_t size)
> +static __always_inline void instrument_write(volatile void *v, size_t size)
> {
> kasan_check_write(v, size);
> kcsan_check_write(v, size);
> @@ -50,7 +50,7 @@ static __always_inline void instrument_write(const volatile void *v, size_t size
> * Instrument a regular write access. The instrumentation should be inserted
> * before the actual write happens.
> */
> -static __always_inline void instrument_read_write(const volatile void *v, size_t size)
> +static __always_inline void instrument_read_write(volatile void *v, size_t size)
> {
> kasan_check_write(v, size);
> kcsan_check_read_write(v, size);
> @@ -92,7 +92,7 @@ static __always_inline void instrument_atomic_read(const volatile void *v, size_
> * Instrument an atomic write access. The instrumentation should be inserted
> * before the actual write happens.
> */
> -static __always_inline void instrument_atomic_write(const volatile void *v, size_t size)
> +static __always_inline void instrument_atomic_write(volatile void *v, size_t size)
> {
> kasan_check_write(v, size);
> kcsan_check_atomic_write(v, size);
> @@ -107,7 +107,7 @@ static __always_inline void instrument_atomic_write(const volatile void *v, size
> * Instrument an atomic read-write access. The instrumentation should be
> * inserted before the actual write happens.
> */
> -static __always_inline void instrument_atomic_read_write(const volatile void *v, size_t size)
> +static __always_inline void instrument_atomic_read_write(volatile void *v, size_t size)
> {
> kasan_check_write(v, size);
> kcsan_check_atomic_read_write(v, size);
> @@ -141,7 +141,7 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
> * variants). The instrumentation should be inserted before the accesses.
> */
> static __always_inline void
> -instrument_copy_from_user_before(const void *to, const void __user *from, unsigned long n)
> +instrument_copy_from_user_before(void *to, const void __user *from, unsigned long n)
> {
> kasan_check_write(to, n);
> kcsan_check_write(to, n);
> diff --git a/include/linux/kasan-checks.h b/include/linux/kasan-checks.h
> index 3d6d22a25bdc..90b878b876f5 100644
> --- a/include/linux/kasan-checks.h
> +++ b/include/linux/kasan-checks.h
> @@ -17,13 +17,13 @@
> */
> #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> bool __kasan_check_read(const volatile void *p, unsigned int size);
> -bool __kasan_check_write(const volatile void *p, unsigned int size);
> +bool __kasan_check_write(volatile void *p, unsigned int size);
> #else
> static inline bool __kasan_check_read(const volatile void *p, unsigned int size)
> {
> return true;
> }
> -static inline bool __kasan_check_write(const volatile void *p, unsigned int size)
> +static inline bool __kasan_check_write(volatile void *p, unsigned int size)
> {
> return true;
> }
> @@ -41,7 +41,7 @@ static inline bool kasan_check_read(const volatile void *p, unsigned int size)
> {
> return true;
> }
> -static inline bool kasan_check_write(const volatile void *p, unsigned int size)
> +static inline bool kasan_check_write(volatile void *p, unsigned int size)
> {
> return true;
> }
> diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
> index d286e0a04543..591c179164af 100644
> --- a/mm/kasan/shadow.c
> +++ b/mm/kasan/shadow.c
> @@ -32,7 +32,7 @@ bool __kasan_check_read(const volatile void *p, unsigned int size)
> }
> EXPORT_SYMBOL(__kasan_check_read);
>
> -bool __kasan_check_write(const volatile void *p, unsigned int size)
> +bool __kasan_check_write(volatile void *p, unsigned int size)
> {
> return kasan_check_range((void *)p, size, true, _RET_IP_);
> }
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] [RFC] instrumented.h: mark instrument_write non-const
2026-11-11 9:59 ` Marco Elver
@ 2026-11-11 10:23 ` Peter Zijlstra
0 siblings, 0 replies; 3+ messages in thread
From: Peter Zijlstra @ 2026-11-11 10:23 UTC (permalink / raw)
To: Marco Elver
Cc: Arnd Bergmann, Andrey Ryabinin, Andrew Morton,
Alexander Potapenko, Arnd Bergmann, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Steffen Eiden, Aleksei Nikiforov,
Andreas Grapentin, Finn Thain, Anshuman Khandual,
David Hildenbrand, linux-s390, linux-kernel, kasan-dev, linux-mm
On Wed, Nov 11, 2026 at 10:59:51AM +0100, Marco Elver wrote:
> On Wed, 11 Nov 2026 at 10:22, Arnd Bergmann <arnd@kernel.org> wrote:
> >
> > From: Arnd Bergmann <arnd@arndb.de>
> >
> > I got another instance of a -Wmaybe-uninitialized in ntfs, as this is
> > the only place that enables the warning:
> >
> > In file included from include/asm-generic/rwonce.h:26,
> > from fs/ntfs3/file.c:10:
> > In function 'instrument_copy_from_user_before',
> > inlined from '_inline_copy_from_user' at include/linux/uaccess.h:184:2,
> > inlined from 'copy_from_user' at include/linux/uaccess.h:222:9,
> > inlined from 'ntfs_ioctl_fitrim' at fs/ntfs3/file.c:78:6,
> > inlined from 'ntfs_ioctl' at fs/ntfs3/file.c:246:10:
> > include/linux/kasan-checks.h:38:27: error: 'range' may be used uninitialized [-Werror=maybe-uninitialized]
> > 38 | #define kasan_check_write __kasan_check_write
> > include/linux/instrumented.h:146:9: note: in expansion of macro 'kasan_check_write'
> > 146 | kasan_check_write(to, n);
> > | ^~~~~~~~~~~~~~~~~
> > include/linux/kasan-checks.h: In function 'ntfs_ioctl':
> > include/linux/kasan-checks.h:20:6: note: by argument 1 of type 'const volatile void *' to '__kasan_check_write' declared here
> > 20 | bool __kasan_check_write(const volatile void *p, unsigned int size);
> > | ^~~~~~~~~~~~~~~~~~~
> > fs/ntfs3/file.c:66:29: note: 'range' declared here
> > 66 | struct fstrim_range range;
> > | ^~~~~
> >
> > The problem here is that copy_from_user() is called on an uninitialized
> > object, but the instrumentation passes the pointer into a function that
> > takes a const object. gcc deduces that any access to that object is
> > undefined behavior and warns about it.
> >
> > The only workaround I could come up with is to remove the 'const' keyword
> > from these annotations, which of course is not great either, as the
> > functions do not actually access the data at all.
>
> Agree, but the code where a real 'write' happens ought to never pass
> in a const-qualified variable or pointer anyway, so I think it's fine.
>
> > This also found incorrect 'const' annotations in
> > arch/s390/include/asm/fpu-insn.h, which writes to those pointers.
>
> That looks like a bug. Maybe split it into a separate patch.
>
> > Any ideas?
> >
> > Fixes: 33b75c1d884e ("instrumented.h: allow instrumenting both sides of copy_from_user()")
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>
> If there are no warnings that appear because of this elsewhere, then:
>
> Acked-by: Marco Elver <elver@google.com>
Yeah, this looks sane enough for me too. Shall I take this (after s390
acks it), or do we want to have it sit in a CI first?
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-11 10:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 9:21 [PATCH] [RFC] instrumented.h: mark instrument_write non-const Arnd Bergmann
2026-11-11 9:59 ` Marco Elver
2026-11-11 10:23 ` Peter Zijlstra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®