[PATCH v2] tftp.h: rework layout to work with fortification
Carlos O'Donell
carlos@systemhalted.org
Sun May 6 04:12:00 GMT 2012
On Thu, Apr 12, 2012 at 1:30 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> 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>
>
> 2012-04-12 Mike Frysinger <vapier@gentoo.org>
>
> * inet/arpa/tftp.h (struct tftphdr): Add a struct inside the union,
> and move tu_block/tu_code into a union of th_block/th_code inside
> of that. Move th_data[1] to the inner struct as th_data[0].
> Change tu_stuff[1] to th_stuff[0]. Delete th_u union name.
> (th_block): Delete
> (th_code, th_stuff): Likewise.
> ---
> v2
> - maintain packed in all unions/structs
>
> inet/arpa/tftp.h | 17 +++++++++--------
> 1 files changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/inet/arpa/tftp.h b/inet/arpa/tftp.h
> index 21b0559..f1baa30 100644
> --- a/inet/arpa/tftp.h
> +++ b/inet/arpa/tftp.h
> @@ -49,16 +49,17 @@
> 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 */
> + struct {
> + union {
> + unsigned short th_block; /* block # */
> + short th_code; /* error code */
> + } __attribute__ ((__packed__));
> + char th_data[0]; /* data or error string */
> + } __attribute__ ((__packed__));
> + char th_stuff[0]; /* request packet stuff */
> + } __attribute__ ((__packed__));
> } __attribute__ ((__packed__));
I understand that fortification causes some problems here, but...
Doesn't that break the ABI?
Can you show me that it doesn't?
> -#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
Why do you remove the defines for th_block, th_code and th_stuff?
Isn't it possible that defines are used by userspace code?
Cheers,
Carlos.
More information about the Libc-alpha
mailing list