]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
tftp.h: rework layout to work with fortification
authorMike Frysinger <vapier@gentoo.org>
Thu, 12 Apr 2012 15:18:39 +0000 (11:18 -0400)
committerMike Frysinger <vapier@gentoo.org>
Tue, 8 May 2012 05:51:22 +0000 (01:51 -0400)
The current tftp structure does not work when fortification is enabled.
Starting with gcc-4.5, more size checking was added to trigger these.
Older versions just didn't have enough information, so they returned -1
as the sizes.

First, the tu_stuff field is declared as 1 byte (when it's really an
arbitrary length C string), so attempting to strcpy() with it results
in crashes.  This fails with _FORTIFY_SOURCE=1.

Second, even if we change that to [0] (since gcc does not allow flexible
array members in an union), gcc is not smart enough to see that they are
two overlapping flexible arrays (tu_stuff and tu_data), so it will still
trigger an abort with _FORTIFY_SOURCE=2.  This is because it thinks that
tu_stuff is 0 bytes and tu_data comes after it.

Talking to upstream gcc, they don't seem terribly inclined to fix the
2nd issue, but even if they did, we still have plenty of 4.5 and 4.6
installs that would hit problems.

So, let's re-order with a few more anonymous structs & unions so that
the fields are laid out with a zero-length array always as the last
field.  This seems to fix things with gcc-4.6, and the tftp-hpa pkg
continues to build & work.

URL: https://bugs.launchpad.net/ubuntu/+source/tftp-hpa/+bug/691345
URL: https://bugs.archlinux.org/task/28103
URL: https://bugs.gentoo.org/357083
URL: http://gcc.gnu.org/PR52944
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
ChangeLog
inet/arpa/tftp.h

index 92e6bca36c89aba30d6474dcec8ed5df290c8b6a..51027aea4899d3ded68c8ea96f672a602bcef5ea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-05-08  Mike Frysinger  <vapier@gentoo.org>
+
+       * inet/arpa/tftp.h (struct tftphdr): Rename th_u to th_u1.  Add
+       a struct th_u2 inside the union, and move tu_block/tu_code into
+       a new th_u3 union of tu_block/tu_code inside of that.  Move
+       th_data[1] into the th_u2 as tu_data[0].  Change tu_stuff[1] to
+       tu_stuff[0].  Add a new tu_padding[4] to keep sizeof() the same.
+       (th_block): Change to th_u1.th_u2.th_u3.tu_block.
+       (th_code): Change to th_u1.th_u2.th_u3.tu_code.
+       (th_stuff): Change to th_u1.tu_stuff.
+       (th_data): Define.
+       (th_msg): Change to th_u1.th_u2.tu_data.
+
 2012-05-07  David S. Miller  <davem@davemloft.net>
 
        * sysdeps/sparc/fpu/libm-test-ulps: Update.
index 21b0559e547a871e4851cf941b76e816b288e2f2..86e0b6e81489323754c00f3318e613f777641454 100644 (file)
 struct tftphdr {
        short   th_opcode;                      /* packet type */
        union {
-               unsigned short  tu_block;       /* block # */
-               short   tu_code;                /* error code */
-               char    tu_stuff[1];            /* request packet stuff */
-       } __attribute__ ((__packed__)) th_u;
-       char    th_data[1];                     /* data or error string */
+               char    tu_padding[3];          /* sizeof() compat */
+               struct {
+                       union {
+                               unsigned short  tu_block;       /* block # */
+                               short   tu_code;                /* error code */
+                       } __attribute__ ((__packed__)) th_u3;
+                       char tu_data[0];        /* data or error string */
+               } __attribute__ ((__packed__)) th_u2;
+               char    tu_stuff[0];            /* request packet stuff */
+       } __attribute__ ((__packed__)) th_u1;
 } __attribute__ ((__packed__));
 
-#define        th_block        th_u.tu_block
-#define        th_code         th_u.tu_code
-#define        th_stuff        th_u.tu_stuff
-#define        th_msg          th_data
+#define        th_block        th_u1.th_u2.th_u3.tu_block
+#define        th_code         th_u1.th_u2.th_u3.tu_code
+#define        th_stuff        th_u1.tu_stuff
+#define        th_data         th_u1.th_u2.tu_data
+#define        th_msg          th_u1.th_u2.tu_data
 
 /*
  * Error codes.