This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] add attribute nonstring
- From: Martin Sebor <msebor at gmail dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Fri, 10 Nov 2017 10:31:04 -0700
- Subject: [PATCH] add attribute nonstring
- Authentication-results: sourceware.org; auth=none
The latest revision of GCC 8.0 adds a -Wstringop-truncation option
to detect common misuses of the strncpy and strncat functions that
may truncate the copy and leave the result without a terminating
nul character.
On its own, the warning cannot distinguish the intended and safe
uses of the functions (to fill a buffer with data) from the
incorrect and unsafe ones (to make a "bounded" copy of a string).
Because the misuses have become prevalent and the correct/intended
uses are in a minority, GCC has added a new attribute called
nonstring to annotate character arrays that aren't meant to be
treated as nul-terminated strings. The attribute disables
the checker. In the future, GCC will also use the attribute to
issue warnings when such arrays are passed to functions that
expect nul-terminated strings.
Attached is a patch to annotate such arrays in Glibc to prevent
warnings on x86_64 (I didn't test any other targets). The patch
touches the timezone/tzfile.h header even though (IIUC) it comes
from another project. I'm not familiar with the process for
keeping the timezone directory in sync with tzcode. Please let
me know how you'd like to go about making this change.
Thanks
Martin
The -Wstringop-truncation option new in GCC 8 detects common misuses
of the strncat and strncpy function that may result in truncating
the copied string before the terminating NUL. To avoid false positive
warnings for correct code that intentionally creates sequences of
characters that aren't guaranteed to be NUL-terminated, arrays that
are intended to store such sequences should be decorated with a new
nonstring attribute. This change add this attribute to Glibc and
uses it to suppress such false positives.
ChangeLog:
* misc/sys/cdefs.h (__NONSTRING): New macro.
* sysdeps/gnu/bits/utmp.h (struct utmp): Use it.
* sysdeps/gnu/net/if.h (struct ifreq): Same.
* timezone/tzfile.h (struct tzhead): Same.
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index cfd39d5..af6d1ac 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -407,6 +407,14 @@
# endif
#endif
+#if __GNUC__ >= 8
+/* Describes a char array that is not necessarily a NUL-terminated
+ string. */
+# define __NONSTRING __attribute__ ((__nonstring__))
+#else
+# define __NONSTRING
+#endif
+
#if (!defined _Static_assert && !defined __cplusplus \
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
&& (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
diff --git a/sysdeps/gnu/bits/utmp.h b/sysdeps/gnu/bits/utmp.h
index 2ee11cb..d4885f3 100644
--- a/sysdeps/gnu/bits/utmp.h
+++ b/sysdeps/gnu/bits/utmp.h
@@ -59,9 +59,13 @@ struct utmp
{
short int ut_type; /* Type of login. */
pid_t ut_pid; /* Process ID of login process. */
+ __NONSTRING
char ut_line[UT_LINESIZE]; /* Devicename. */
+ __NONSTRING
char ut_id[4]; /* Inittab ID. */
+ __NONSTRING
char ut_user[UT_NAMESIZE]; /* Username. */
+ __NONSTRING
char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */
struct exit_status ut_exit; /* Exit status of a process marked
as DEAD_PROCESS. */
diff --git a/sysdeps/gnu/net/if.h b/sysdeps/gnu/net/if.h
index 0afce08..eb11813 100644
--- a/sysdeps/gnu/net/if.h
+++ b/sysdeps/gnu/net/if.h
@@ -129,6 +129,7 @@ struct ifreq
# define IFNAMSIZ IF_NAMESIZE
union
{
+ __NONSTRING
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
} ifr_ifrn;
diff --git a/timezone/tzfile.h b/timezone/tzfile.h
index 0e51dce..19fe20a 100644
--- a/timezone/tzfile.h
+++ b/timezone/tzfile.h
@@ -38,6 +38,7 @@
#define TZ_MAGIC "TZif"
struct tzhead {
+ __NONSTRING
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */
char tzh_reserved[15]; /* reserved; must be zero */