Comment 2 for bug 547016

Revision history for this message
Colin Watson (cjwatson) wrote : Re: [Bug 547016] [NEW] gcc optimization problem related to varargs

(I think there's an extra "n" in your first argument to testfunc(), at
least when compared to your expected output.)

Thanks for your report. What's happening here is that, when you pass
five arguments to vsnprintf but only consume the fifth, vsnprintf has no
idea what the types of the other four arguments are. Due to the way
variable-length argument lists work, this means that vsnprintf doesn't
know the position of the fifth argument on the stack.

The reason that it doesn't fail with -O0 is that Ubuntu's gcc sets
-D_FORTIFY_SOURCE=2 at -O2 and higher. When _FORTIFY_SOURCE is not set,
all positional arguments are assumed to be int unless there's evidence
to the contrary. Otherwise, any undefined-type positional arguments
produce this error. (I think %N$ is a GNU extension, so it seems within
its rights to behave this way, and it's not an unreasonable security
check since this can at the very least cause surprising behaviour,
particularly in conjunction with %n.)

Thus, a short-term workaround for you is to build with
-U_FORTIFY_SOURCE, but I think you should also change your application
to avoid using undefined-type positional arguments like this. The two
bugs in Ubuntu here are that (as far as I can see) glibc doesn't
document this behaviour, and that gcc doesn't warn about the risky code.

 affects ubuntu/gcc-4.4
 status triaged
 severity wishlist
 affects ubuntu/eglibc
 status triaged
 severity low