public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Marco Elver <elver@google.com>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	ntfs3@lists.linux.dev, linux-kernel@vger.kernel.org,
	kasan-dev@googlegroups.com
Subject: Re: kcsan -Wmaybe-uninitialized warning in ntfs3
Date: Tue, 21 Apr 2026 15:18:37 +0200	[thread overview]
Message-ID: <aed5LYnQvjgWm5Rc@elver.google.com> (raw)
In-Reply-To: <0df31031-23d4-49cf-8643-f605561bf7fb@app.fastmail.com>

On Tue, Apr 21, 2026 at 02:28PM +0200, Arnd Bergmann wrote:
> On Tue, Apr 21, 2026, at 13:35, Marco Elver wrote:
> > On Tue, 21 Apr 2026 at 12:21, Arnd Bergmann <arnd@arndb.de> wrote:
> >>
> >> I ran into this during randconfig testing, I have attached a
> >> reproducer .config here, but have not tried to narrow down the
> >> configuration options that are required for triggering it.
> >
> > The attached .config is a KASAN config, still can't reproduce.
> 
> Odd, this is what I see in the attached file:

Mea culpa - I added one '.' too many and ended up copying some old
config.

Anyway, I can reproduce this now.

There appear to be 2 options to fix, see patch below:

1. __kcsan_nodiag wrapper to disable warnings for the kcsan_check
   helpers. Tested and seems to work in this case.

2. __attribute__((access(none, 1))) per https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html:
   "The access attribute enables the detection of invalid or unsafe
   accesses by functions or their callers, as well as write-only
   accesses to objects that are never read from. Such accesses may be
   diagnosed by warnings such as -Wstringop-overflow, -Wuninitialized,
   -Wunused, and others."

Option #2 seems a lot simpler. While KCSAN does read the accessed
memory, for the purpose of diagnostics hiding this fact from the
compiler is perfectly fine as it's not part of "normal" kernel code.

Preferences?

------ >8 ------


diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index b041639ab406..088412189f16 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -73,6 +73,7 @@ static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
 	if (!bdev_max_discard_sectors(dev))
 		return -EOPNOTSUPP;
 
+	kcsan_check_write(&range, sizeof(range));
 	user_range = (struct fstrim_range __user *)arg;
 	if (copy_from_user(&range, user_range, sizeof(range)))
 		return -EFAULT;
diff --git a/include/linux/kcsan-checks.h b/include/linux/kcsan-checks.h
index 92f3843d9ebb..7304512cf2a2 100644
--- a/include/linux/kcsan-checks.h
+++ b/include/linux/kcsan-checks.h
@@ -27,6 +27,14 @@
  * to validate access to an address. Never use these in header files!
  */
 #ifdef CONFIG_KCSAN
+#define __kcsan_nodiag(...)					\
+({								\
+	__diag_push();						\
+	__diag_ignore_all("-Wmaybe-uninitialized", "")		\
+	__VA_ARGS__;						\
+	__diag_pop()						\
+})
+
 /**
  * __kcsan_check_access - check generic access for races
  *
@@ -34,7 +42,7 @@
  * @size: size of access
  * @type: access type modifier
  */
-void __kcsan_check_access(const volatile void *ptr, size_t size, int type);
+void __kcsan_check_access(const volatile void *ptr, size_t size, int type)/* __attribute__((access (none, 1)))*/;
 
 /*
  * See definition of __tsan_atomic_signal_fence() in kernel/kcsan/core.c.
@@ -186,6 +194,8 @@ void kcsan_end_scoped_access(struct kcsan_scoped_access *sa);
 
 #else /* CONFIG_KCSAN */
 
+#define __kcsan_nodiag(...) ({ __VA_ARGS__; })
+
 static inline void __kcsan_check_access(const volatile void *ptr, size_t size,
 					int type) { }
 
@@ -273,7 +283,7 @@ static inline void __kcsan_disable_current(void) { }
  * @ptr: address of access
  * @size: size of access
  */
-#define __kcsan_check_read(ptr, size) __kcsan_check_access(ptr, size, 0)
+#define __kcsan_check_read(ptr, size) __kcsan_nodiag(__kcsan_check_access(ptr, size, 0))
 
 /**
  * __kcsan_check_write - check regular write access for races
@@ -282,7 +292,7 @@ static inline void __kcsan_disable_current(void) { }
  * @size: size of access
  */
 #define __kcsan_check_write(ptr, size)                                         \
-	__kcsan_check_access(ptr, size, KCSAN_ACCESS_WRITE)
+	__kcsan_nodiag(__kcsan_check_access(ptr, size, KCSAN_ACCESS_WRITE))
 
 /**
  * __kcsan_check_read_write - check regular read-write access for races
@@ -291,7 +301,7 @@ static inline void __kcsan_disable_current(void) { }
  * @size: size of access
  */
 #define __kcsan_check_read_write(ptr, size)                                    \
-	__kcsan_check_access(ptr, size, KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE)
+	__kcsan_nodiag(__kcsan_check_access(ptr, size, KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE))
 
 /**
  * kcsan_check_read - check regular read access for races
@@ -299,7 +309,7 @@ static inline void __kcsan_disable_current(void) { }
  * @ptr: address of access
  * @size: size of access
  */
-#define kcsan_check_read(ptr, size) kcsan_check_access(ptr, size, 0)
+#define kcsan_check_read(ptr, size) __kcsan_nodiag(kcsan_check_access(ptr, size, 0))
 
 /**
  * kcsan_check_write - check regular write access for races
@@ -308,7 +318,7 @@ static inline void __kcsan_disable_current(void) { }
  * @size: size of access
  */
 #define kcsan_check_write(ptr, size)                                           \
-	kcsan_check_access(ptr, size, KCSAN_ACCESS_WRITE)
+	__kcsan_nodiag(kcsan_check_access(ptr, size, KCSAN_ACCESS_WRITE))
 
 /**
  * kcsan_check_read_write - check regular read-write access for races
@@ -317,7 +327,7 @@ static inline void __kcsan_disable_current(void) { }
  * @size: size of access
  */
 #define kcsan_check_read_write(ptr, size)                                      \
-	kcsan_check_access(ptr, size, KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE)
+	__kcsan_nodiag(kcsan_check_access(ptr, size, KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE))
 
 /*
  * Check for atomic accesses: if atomic accesses are not ignored, this simply
@@ -329,11 +339,11 @@ static inline void __kcsan_disable_current(void) { }
 #define kcsan_check_atomic_read_write(...)	do { } while (0)
 #else
 #define kcsan_check_atomic_read(ptr, size)                                     \
-	kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC)
+	__kcsan_nodiag(kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC))
 #define kcsan_check_atomic_write(ptr, size)                                    \
-	kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE)
+	__kcsan_nodiag(kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE))
 #define kcsan_check_atomic_read_write(ptr, size)                               \
-	kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE | KCSAN_ACCESS_COMPOUND)
+	__kcsan_nodiag(kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE | KCSAN_ACCESS_COMPOUND))
 #endif
 
 /**
@@ -368,7 +378,7 @@ static inline void __kcsan_disable_current(void) { }
  * @var: variable to assert on
  */
 #define ASSERT_EXCLUSIVE_WRITER(var)                                           \
-	__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT)
+	__kcsan_nodiag(__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT))
 
 /*
  * Helper macros for implementation of for ASSERT_EXCLUSIVE_*_SCOPED(). @id is
@@ -380,9 +390,9 @@ static inline void __kcsan_disable_current(void) { }
 	struct kcsan_scoped_access __kcsan_scoped_name(id, _)                  \
 		__kcsan_cleanup_scoped;                                        \
 	struct kcsan_scoped_access *__kcsan_scoped_name(id, _dummy_p)          \
-		__maybe_unused = kcsan_begin_scoped_access(                    \
+		__maybe_unused = __kcsan_nodiag(kcsan_begin_scoped_access(     \
 			&(var), sizeof(var), KCSAN_ACCESS_SCOPED | (type),     \
-			&__kcsan_scoped_name(id, _))
+			&__kcsan_scoped_name(id, _)))
 
 /**
  * ASSERT_EXCLUSIVE_WRITER_SCOPED - assert no concurrent writes to @var in scope
@@ -449,7 +459,7 @@ static inline void __kcsan_disable_current(void) { }
  * @var: variable to assert on
  */
 #define ASSERT_EXCLUSIVE_ACCESS(var)                                           \
-	__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT)
+	__kcsan_nodiag(__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT))
 
 /**
  * ASSERT_EXCLUSIVE_ACCESS_SCOPED - assert no concurrent accesses to @var in scope
@@ -525,7 +535,7 @@ static inline void __kcsan_disable_current(void) { }
 #define ASSERT_EXCLUSIVE_BITS(var, mask)                                       \
 	do {                                                                   \
 		kcsan_set_access_mask(mask);                                   \
-		__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT);\
+		__kcsan_nodiag(__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT));\
 		kcsan_set_access_mask(0);                                      \
 		kcsan_atomic_next(1);                                          \
 	} while (0)

  reply	other threads:[~2026-04-21 13:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-21  7:53 kcsan -Wmaybe-uninitialized warning in ntfs3 Arnd Bergmann
2026-04-21  9:33 ` Marco Elver
2026-04-21 10:21   ` Arnd Bergmann
2026-04-21 11:35     ` Marco Elver
2026-04-21 12:28       ` Arnd Bergmann
2026-04-21 13:18         ` Marco Elver [this message]
2026-04-21 14:11           ` Arnd Bergmann
2026-04-21 15:26             ` Marco Elver
2026-04-21 19:06               ` Marco Elver
2026-04-21 19:12                 ` Arnd Bergmann
2026-04-22  8:00                   ` Arnd Bergmann
2026-04-22  8:23                     ` Marco Elver
2026-04-22 11:35                       ` Marco Elver
2026-04-22 11:51                         ` Marco Elver
2026-04-22 20:57                       ` Arnd Bergmann
2026-04-22 21:50                         ` Marco Elver
2026-04-23  8:12                           ` David Laight
2026-04-23 11:35                             ` Marco Elver
2026-04-23 13:06                               ` David Laight
2026-04-24 10:03                                 ` Marco Elver
2026-04-21 12:26     ` Marco Elver

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aed5LYnQvjgWm5Rc@elver.google.com \
    --to=elver@google.com \
    --cc=almaz.alexandrovich@paragon-software.com \
    --cc=arnd@arndb.de \
    --cc=dvyukov@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ntfs3@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox