Make gcc die on init overflow of an array.
authorWayne Davison <wayne@opencoder.net>
Tue, 29 Sep 2020 20:04:41 +0000 (13:04 -0700)
committerWayne Davison <wayne@opencoder.net>
Tue, 29 Sep 2020 20:18:28 +0000 (13:18 -0700)
- Use -pedantic-errors with gcc to make an array-init fatal.
- Fix all the extra warnings that gcc outputs due to this option.
- Also add -Wno-pedantic to gcc if we're using the internal popt
  code (since it has lots of pedantic issues).

configure.ac
generator.c
loadparm.c
log.c
tls.c
token.c
xattrs.c

index e8c06f420892d61878f7eece00c7a93174e1166f..eda5f0fa17882e196e016a7ff2e7e804474733b7 100644 (file)
@@ -116,9 +116,9 @@ fi
 # I don't want our version too far out of sync.
 CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
 
-# If GCC, turn on warnings.
+# If GCC, turn on warnings and turn pedantic warnings into errors to ensure an array-init overflow is an error.
 if test x"$GCC" = x"yes"; then
-       CFLAGS="$CFLAGS -Wall -W"
+       CFLAGS="$CFLAGS -Wall -W -pedantic-errors"
 fi
 
 AC_ARG_WITH(included-popt,
@@ -1046,6 +1046,12 @@ elif test x"$ac_cv_header_popt_h" != x"yes"; then
     with_included_popt=yes
 fi
 
+if test x"$with_included_popt" = x"yes" -a x"$GCC" = x"yes"; then
+       # Our internal popt code cannot be compiled with pedantic warnings as errors, so turn off
+       # pedantic warnings.  This does not affect the array-init overflow as an error, though.
+       CFLAGS="$CFLAGS -Wno-pedantic"
+fi
+
 AC_MSG_CHECKING([whether to use included libpopt])
 if test x"$with_included_popt" = x"yes"; then
     AC_MSG_RESULT($srcdir/popt)
index 20599d83d3c3b86140a75d15a890e75935e1783a..a890bdc3c5b7e9577289d9837deffe1055f1f7d4 100644 (file)
@@ -182,7 +182,8 @@ static int remember_delete(struct file_struct *file, const char *fname, int flag
 static int read_delay_line(char *buf, int *flags_p)
 {
        static int read_pos = 0;
-       int j, len, mode;
+       unsigned int mode;
+       int j, len;
        char *bp, *past_space;
 
        while (1) {
index 952a0b74301fc3140c1da54e2e99b9b55596a321..3906bc0f419faea3c4d4d666ce77fa560b5c3a60 100644 (file)
@@ -437,7 +437,7 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
                break;
 
        case P_OCTAL:
-               sscanf(parmvalue, "%o", (int *)parm_ptr);
+               sscanf(parmvalue, "%o", (unsigned int *)parm_ptr);
                break;
 
        case P_PATH:
diff --git a/log.c b/log.c
index 062a930eb2f21ec055380df8a1a1a3e190586130..06844a9421afe31599423d7d239032201efb045a 100644 (file)
--- a/log.c
+++ b/log.c
@@ -838,14 +838,24 @@ void maybe_log_item(struct file_struct *file, int iflags, int itemizing, const c
 
 void log_delete(const char *fname, int mode)
 {
-       static struct {
-               union file_extras ex[4]; /* just in case... */
-               struct file_struct file;
-       } x; /* Zero-initialized due to static declaration. */
+       static struct file_struct *file = NULL;
        int len = strlen(fname);
        const char *fmt;
 
-       x.file.mode = mode;
+       if (!file) {
+               int extra_len = (file_extra_cnt + 2) * EXTRA_LEN;
+               char *bp;
+#if EXTRA_ROUNDING > 0
+               if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
+                       extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
+#endif
+
+               bp = new_array0(char, FILE_STRUCT_LEN + extra_len + 1);
+               bp += extra_len;
+               file = (struct file_struct *)bp;
+       }
+
+       file->mode = mode;
 
        if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
                if (S_ISDIR(mode))
@@ -855,14 +865,14 @@ void log_delete(const char *fname, int mode)
                ;
        else {
                fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
-               log_formatted(FCLIENT, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
+               log_formatted(FCLIENT, fmt, "del.", file, fname, ITEM_DELETED, NULL);
        }
 
        if (!logfile_name || dry_run || !logfile_format)
                return;
 
        fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
-       log_formatted(FLOG, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
+       log_formatted(FLOG, fmt, "del.", file, fname, ITEM_DELETED, NULL);
 }
 
 /*
diff --git a/tls.c b/tls.c
index c50fa6c3e81bc8f87c5b842b873e58428324db2c..cb497360e88b5aa16a78d166bbe94b335e55921d 100644 (file)
--- a/tls.c
+++ b/tls.c
@@ -60,7 +60,8 @@ int nsec_times = 0;
 
 static int stat_xattr(const char *fname, STRUCT_STAT *fst)
 {
-       int mode, rdev_major, rdev_minor, uid, gid, len;
+       unsigned int mode;
+       int rdev_major, rdev_minor, uid, gid, len;
        char buf[256];
 
        if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode))
diff --git a/token.c b/token.c
index 61be8dd950136a04988313e8b32ff765b75ac6b6..3a6d069ed8e7de56bd66efc0596ed23ab81b1785 100644 (file)
--- a/token.c
+++ b/token.c
@@ -570,7 +570,7 @@ static int32 recv_deflated_token(int f, char **data)
                                rx_strm.avail_in = 4;
                                rx_strm.next_in = (Bytef *)cbuf;
                                cbuf[0] = cbuf[1] = 0;
-                               cbuf[2] = cbuf[3] = 0xff;
+                               cbuf[2] = cbuf[3] = (char)0xff;
                                inflate(&rx_strm, Z_SYNC_FLUSH);
                                recv_state = r_idle;
                        }
index bcb4bcacf31d73ff14d1f37b14c554cea435bdb4..508649c000244b792b1a45ac55ebbbc398ea3635 100644 (file)
--- a/xattrs.c
+++ b/xattrs.c
@@ -1118,7 +1118,8 @@ int del_def_xattr_acl(const char *fname)
 
 int get_stat_xattr(const char *fname, int fd, STRUCT_STAT *fst, STRUCT_STAT *xst)
 {
-       int mode, rdev_major, rdev_minor, uid, gid, len;
+       unsigned int mode;
+       int rdev_major, rdev_minor, uid, gid, len;
        char buf[256];
 
        if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode))