Skip to contentSkip to conversation

Support the nonstring variable attribute (gcc >= 8)

PATCH Superseded Miguel Ojeda 2 participants 4 messages Aug 1, 2018 – Aug 5, 2018

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/2 Support the nonstring variable attribute (gcc >= 8)

From the GCC manual:

The nonstring variable attribute specifies that an object or member declaration with type array of char or pointer to char is intended to store character arrays that do not necessarily contain a terminating NUL character. This is useful in detecting uses of such arrays or pointers with functions that expect NUL-terminated strings, and to avoid warnings when such an array or pointer is used as an argument to a bounded string manipulation function such as strncpy.

https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html

Some reports are already coming to the LKML regarding these warnings. When they are false positives, like this one

https://lkml.org/lkml/2018/1/16/135

we can use __nonstring to let gcc know a NUL character is not required.

Cc Ingo Molnar <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kees Cook <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Geert Uytterhoeven <[email protected]>
Cc Will Deacon <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc David Rientjes <[email protected]>
Cc Martin Sebor <[email protected]>
Cc Arnd Bergmann <[email protected]>

---
Re-sending this since a few months have passed, Martin has improved GCC's feature and warnings are appearing in Geert's build bot. Added an example in the second patch as requested by David.

 include/linux/compiler-gcc.h   | 14 ++++++++++++++
 include/linux/compiler_types.h |  4 ++++
 2 files changed, 18 insertions(+)
include/linux/compiler-gcc.h +14 -0
index 573f5a7d42d4..fab4e904f1fe 100644
@@ -343,6 +343,20 @@
 #define __designated_init __attribute__((designated_init))
 #endif
 
+#if GCC_VERSION >= 80000
+/*
+ * The nonstring variable attribute specifies that an object or member
+ * declaration with type array of char or pointer to char is intended
+ * to store character arrays that do not necessarily contain a terminating
+ * NUL character. This is useful in detecting uses of such arrays or pointers
+ * with functions that expect NUL-terminated strings, and to avoid warnings
+ * when such an array or pointer is used as an argument to a bounded string
+ * manipulation function such as strncpy.
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
+ */
+#define __nonstring __attribute__((nonstring))
+#endif
+
 #endif	/* gcc version >= 40000 specific checks */
 
 #if !defined(__noclone)
include/linux/compiler_types.h +4 -0
index a8ba6b04152c..9c07be36e86a 100644
@@ -289,4 +289,8 @@ struct ftrace_likely_data {
 #define __diag_error(compiler, version, option, comment) \
 	__diag_ ## compiler(version, error, option)
 
+#ifndef __nonstring
+# define __nonstring
+#endif
+
 #endif /* __LINUX_COMPILER_TYPES_H */
Signature · 1 line
2.17.1
#1 lore raw
Quoted 48 lines · Miguel Ojeda

From the GCC manual:

The nonstring variable attribute specifies that an object or member declaration with type array of char or pointer to char is intended to store character arrays that do not necessarily contain a terminating NUL character. This is useful in detecting uses of such arrays or pointers with functions that expect NUL-terminated strings, and to avoid warnings when such an array or pointer is used as an argument to a bounded string manipulation function such as strncpy.

https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html

Some reports are already coming to the LKML regarding these warnings. When they are false positives, like this one

https://lkml.org/lkml/2018/1/16/135

we can use __nonstring to let gcc know a NUL character is not required.

Cc Ingo Molnar <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kees Cook <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Geert Uytterhoeven <[email protected]>
Cc Will Deacon <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc David Rientjes <[email protected]>
Cc Martin Sebor <[email protected]>
Cc Arnd Bergmann <[email protected]>

---
Re-sending this since a few months have passed, Martin has improved GCC's feature and warnings are appearing in Geert's build bot. Added an example in the second patch as requested by David.

 include/linux/compiler-gcc.h   | 14 ++++++++++++++
 include/linux/compiler_types.h |  4 ++++
 2 files changed, 18 insertions(+)
include/linux/compiler-gcc.h +1 -0
index 573f5a7d42d4..fab4e904f1fe 100644
@@ -343,6 +343,20 @@
 #define __designated_init __attribute__((designated_init))
 #endif
 
+#if GCC_VERSION >= 80000

include/linux/compiler-gcc.h line 356

Quoted 10 lines
include/linux/compiler-gcc.h +10 -0
+/*
+ * The nonstring variable attribute specifies that an object or member
+ * declaration with type array of char or pointer to char is intended
+ * to store character arrays that do not necessarily contain a terminating
+ * NUL character. This is useful in detecting uses of such arrays or pointers
+ * with functions that expect NUL-terminated strings, and to avoid warnings
+ * when such an array or pointer is used as an argument to a bounded string
+ * manipulation function such as strncpy.
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
+ */

Please move this down to the already existing test for GCC_VERSION >= 80000 near the bottom of the file so that version number tests are always in increasing order in the file.

Quoted 19 lines
include/linux/compiler-gcc.h +3 -0
+#define __nonstring __attribute__((nonstring))
+#endif
+
 #endif	/* gcc version >= 40000 specific checks */
 
 #if !defined(__noclone)
include/linux/compiler_types.h +4 -0
index a8ba6b04152c..9c07be36e86a 100644
@@ -289,4 +289,8 @@ struct ftrace_likely_data {
 #define __diag_error(compiler, version, option, comment) \
 	__diag_ ## compiler(version, error, option)
 
+#ifndef __nonstring
+# define __nonstring
+#endif
+
 #endif /* __LINUX_COMPILER_TYPES_H */
#2 lore raw
Quoted 48 lines · Joe Perches
Quoted 47 lines · Miguel Ojeda

From the GCC manual:

The nonstring variable attribute specifies that an object or member declaration with type array of char or pointer to char is intended to store character arrays that do not necessarily contain a terminating NUL character. This is useful in detecting uses of such arrays or pointers with functions that expect NUL-terminated strings, and to avoid warnings when such an array or pointer is used as an argument to a bounded string manipulation function such as strncpy.

https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html

Some reports are already coming to the LKML regarding these warnings. When they are false positives, like this one

https://lkml.org/lkml/2018/1/16/135

we can use __nonstring to let gcc know a NUL character is not required.

Cc Ingo Molnar <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kees Cook <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Geert Uytterhoeven <[email protected]>
Cc Will Deacon <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc David Rientjes <[email protected]>
Cc Martin Sebor <[email protected]>
Cc Arnd Bergmann <[email protected]>

---
Re-sending this since a few months have passed, Martin has improved GCC's feature and warnings are appearing in Geert's build bot. Added an example in the second patch as requested by David.

 include/linux/compiler-gcc.h   | 14 ++++++++++++++
 include/linux/compiler_types.h |  4 ++++
 2 files changed, 18 insertions(+)
include/linux/compiler-gcc.h +0 -0
index 573f5a7d42d4..fab4e904f1fe 100644
@@ -343,6 +343,20 @@
 #define __designated_init __attribute__((designated_init))
 #endif
 
Quoted 16 lines

include/linux/compiler-gcc.h line 356

Quoted 11 lines
include/linux/compiler-gcc.h +11 -0
+#if GCC_VERSION >= 80000
+/*
+ * The nonstring variable attribute specifies that an object or member
+ * declaration with type array of char or pointer to char is intended
+ * to store character arrays that do not necessarily contain a terminating
+ * NUL character. This is useful in detecting uses of such arrays or pointers
+ * with functions that expect NUL-terminated strings, and to avoid warnings
+ * when such an array or pointer is used as an argument to a bounded string
+ * manipulation function such as strncpy.
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
+ */

Please move this down to the already existing test for GCC_VERSION >= 80000 near the bottom of the file so that version number tests are always in increasing order in the file.

Ah, good catch! The test was added in the v1->v2 meantime. Will do, thanks!

By the way, the file is a mess... Some other tests go inside the big "#if GCC_VERSION >= 40000", others go at the end. We should clean it up and sort it. I might just do it...

Cheers,
Miguel

Quoted 20 lines
Quoted 20 lines
include/linux/compiler-gcc.h +3 -0
+#define __nonstring __attribute__((nonstring))
+#endif
+
 #endif       /* gcc version >= 40000 specific checks */
 
 #if !defined(__noclone)
include/linux/compiler_types.h +4 -0
index a8ba6b04152c..9c07be36e86a 100644
@@ -289,4 +289,8 @@ struct ftrace_likely_data {
 #define __diag_error(compiler, version, option, comment) \
      __diag_ ## compiler(version, error, option)
 
+#ifndef __nonstring
+# define __nonstring
+#endif
+
 #endif /* __LINUX_COMPILER_TYPES_H */
#3 lore raw
Quoted 66 lines · Miguel Ojeda
Quoted 48 lines · Joe Perches
Quoted 47 lines · Miguel Ojeda

From the GCC manual:

The nonstring variable attribute specifies that an object or member declaration with type array of char or pointer to char is intended to store character arrays that do not necessarily contain a terminating NUL character. This is useful in detecting uses of such arrays or pointers with functions that expect NUL-terminated strings, and to avoid warnings when such an array or pointer is used as an argument to a bounded string manipulation function such as strncpy.

https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html

Some reports are already coming to the LKML regarding these warnings. When they are false positives, like this one

https://lkml.org/lkml/2018/1/16/135

we can use __nonstring to let gcc know a NUL character is not required.

Cc Ingo Molnar <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kees Cook <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Geert Uytterhoeven <[email protected]>
Cc Will Deacon <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc David Rientjes <[email protected]>
Cc Martin Sebor <[email protected]>
Cc Arnd Bergmann <[email protected]>

---
Re-sending this since a few months have passed, Martin has improved GCC's feature and warnings are appearing in Geert's build bot. Added an example in the second patch as requested by David.

 include/linux/compiler-gcc.h   | 14 ++++++++++++++
 include/linux/compiler_types.h |  4 ++++
 2 files changed, 18 insertions(+)
include/linux/compiler-gcc.h +0 -0
index 573f5a7d42d4..fab4e904f1fe 100644
@@ -343,6 +343,20 @@
 #define __designated_init __attribute__((designated_init))
 #endif
 
Quoted 16 lines

include/linux/compiler-gcc.h line 356

Quoted 11 lines
include/linux/compiler-gcc.h +11 -0
+#if GCC_VERSION >= 80000
+/*
+ * The nonstring variable attribute specifies that an object or member
+ * declaration with type array of char or pointer to char is intended
+ * to store character arrays that do not necessarily contain a terminating
+ * NUL character. This is useful in detecting uses of such arrays or pointers
+ * with functions that expect NUL-terminated strings, and to avoid warnings
+ * when such an array or pointer is used as an argument to a bounded string
+ * manipulation function such as strncpy.
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
+ */

Please move this down to the already existing test for GCC_VERSION >= 80000 near the bottom of the file so that version number tests are always in increasing order in the file.

Quoted 2 lines

Ah, good catch! The test was added in the v1->v2 meantime. Will do, thanks!

On the other hand, it may get messy given that this has an "else" section:

    #if GCC_VERSION >= 80000
    #define __diag_GCC_8(s) __diag(s)
    #else
    #define __diag_GCC_8(s)
    #endif

Doing it feature-by-feature seems more readable. e.g. doing sorted single tests for versions would imply splitting the __diag feature.

For the moment I will move __nonstring to the bottom in v3, which looks better nevertheless, and I will think about how to do this.

Cheers,
Miguel

Quoted 27 lines

By the way, the file is a mess... Some other tests go inside the big "#if GCC_VERSION >= 40000", others go at the end. We should clean it up and sort it. I might just do it...

Cheers,
Miguel

Quoted 20 lines
Quoted 20 lines
include/linux/compiler-gcc.h +3 -0
+#define __nonstring __attribute__((nonstring))
+#endif
+
 #endif       /* gcc version >= 40000 specific checks */
 
 #if !defined(__noclone)
include/linux/compiler_types.h +4 -0
index a8ba6b04152c..9c07be36e86a 100644
@@ -289,4 +289,8 @@ struct ftrace_likely_data {
 #define __diag_error(compiler, version, option, comment) \
      __diag_ ## compiler(version, error, option)
 
+#ifndef __nonstring
+# define __nonstring
+#endif
+
 #endif /* __LINUX_COMPILER_TYPES_H */