[PATCH] - improve sprintf buffer overflow detection (middle-end/49905)

Martin Sebor msebor@gmail.com
Wed Oct 5 00:31:00 GMT 2016


On 10/04/2016 06:21 PM, Joseph Myers wrote:
> On Tue, 4 Oct 2016, Martin Sebor wrote:
>
>> I've built the sparc-sun-solaris2.12 toolchain and reproduced these
>> warnings.  They are vestiges of those I saw and some of which I fixed
>> before.  The problem is that %lc expects a wint_t argument which on
>> this target is an alias for long in but the argument of 0 has type
>> int.  The warning is coming out of the -Wformat checker which doesn't
>> seem to care that int and long have the same size.  I've committed
>> r240758 that should fix the remaining warnings of this kind but long
>> term I think GCC should change to avoid warning in this case (Clang
>> doesn't).
>
> Well, typically cases where one of long and int is passed and the other is
> expected, but they have the same size, are bugs waiting to happen when the
> code is built on a 64-bit system.  That is, they *should* warn.

Typically, yes.  In the case of wchar_t (or int) and wint_t I don't
think it's helpful.  Consider this case from my comment #5 on bug
72858.  I don't think there is any point in issuing a warning here.
On the majority of targets they either all are or promote to a type
of the same size, don't they?

$ cat t.c && gcc -S -Wall -m32 t.c
typedef __WCHAR_TYPE__ wchar_t;

void f (const wchar_t *ws)
{
   __builtin_printf ("%lc", *ws);
}
t.c: In function ‘f’:
t.c:5:24: warning: format ‘%lc’ expects argument of type ‘wint_t’, but 
argument 2 has type ‘wchar_t {aka const long int}’ [-Wformat=]
    __builtin_printf ("%lc", *ws);
                       ~~^   ~~~
                       %ld
>
> There have been arguments that we should go further and warn for e.g. %zu
> with a type that happens to be the same as size_t but doesn't use the
> size_t typedef (or sizeof etc.), %td for something that happens to be the
> same as ptrdiff_t but doesn't use the typedef (or pointer difference
> etc.), etc. - which would get many similar cases of bugs waiting to happen
> on a different system, but is also tricker because you need to decide
> whether a given type is logically size_t etc. or not - code could validly
> use autoconf to identify the underlying type, or use __SIZE_TYPE__, or use
> an expression mixing size_t with other types, or in the case of %j*
> (intmax_t) use the INTMAX_C macro to construct constants.  That probably
> *would* need an option to disable just those format warnings (whereas I
> don't see the need for such an option for the case of mixing int and
> long).

I would view it useful if GCC warned on %zu with an argument that's
not size_t, and similarly for other directives and typedefs, for the
reason you mention.  But I don't think the same rationale applies
to warning on %lc with wchar_t or int arguments.

Martin



More information about the Gcc-patches mailing list