[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] inttostr.h: add compile-time buffer overrun checks
From: |
Jim Meyering |
Subject: |
Re: [PATCH] inttostr.h: add compile-time buffer overrun checks |
Date: |
Sun, 17 Oct 2010 10:30:09 +0200 |
Bruno Haible wrote:
> Hi Jim,
>
>> +# define inttostr(n, s) \
>> + ((void) verify_true (sizeof (s) == sizeof (void *) \
>> + || INT_BUFSIZE_BOUND (int) <= sizeof (s)), \
>> + (inttostr) (n, s))
>
> Nice and clever trick.
>
> Unfortunately, it does not work for variable-length arrays, which are allowed
> in C99 and C++.
>
> Test case:
>
> void foo (int n)
> {
> char buf[10 + (n < 0) + 1];
> char *result = inttostr (n, buf);
> }
Good counterexample.
> Yields:
>
> foo.c: In function ‘foo’:
> foo.c:38: error: bit-field ‘verify_error_if_negative_size__’ width not an
> integer constant
That fails because INT_BUFSIZE_BOUND(int) is 12 to accommodate
the negative sign on INT_MIN, yet sizeof(buf) is only 11.
> How to fix this? I tried __builtin_constant_p and __builtin_choose_expr, but
> haven't found the trick.
If there is no better work-around, I will add a comment advising such users
to use INT_BUFSIZE_BOUND(VAR) (hence no need for a variable-length array and
no need to change numbers if you change the type of VAR), or failing that,
to add an "#undef inttostr" in the affected compilation unit, thus disabling
the overrun check.
---------------------------------------------
While looking through gcc's documentation (latest upstream),
I noticed this, which can be put to good use in xalloc.h:
@item alloc_size
@cindex @code{alloc_size} attribute
The @code{alloc_size} attribute is used to tell the compiler that the
function return value points to memory, where the size is given by
one or two of the functions parameters. GCC uses this
information to improve the correctness of @code{__builtin_object_size}.
The function parameter(s) denoting the allocated size are specified by
one or two integer arguments supplied to the attribute. The allocated size
is either the value of the single function argument specified or the product
of the two function arguments specified. Argument numbering starts at
one.
For instance,
@smallexample
void* my_calloc(size_t, size_t) __attribute__((alloc_size(1,2)))
void my_realloc(void*, size_t) __attribute__((alloc_size(2)))
@end smallexample
declares that my_calloc will return memory of the size given by
the product of parameter 1 and 2 and that my_realloc will return memory
of the size given by parameter 2.
--------------------------------------
Continuing in the same vein, there's even more:
@smallexample
#undef memcpy
#define bos0(dest) __builtin_object_size (dest, 0)
#define memcpy(dest, src, n) \
__builtin___memcpy_chk (dest, src, n, bos0 (dest))
char *volatile p;
char buf[10];
/* It is unknown what object p points to, so this is optimized
into plain memcpy - no checking is possible. */
memcpy (p, "abcde", n);
/* Destination is known and length too. It is known at compile
time there will be no overflow. */
memcpy (&buf[5], "abcde", 5);
/* Destination is known, but the length is not known at compile time.
This will result in __memcpy_chk call that can check for overflow
at runtime. */
memcpy (&buf[5], "abcde", n);
/* Destination is known and it is known at compile time there will
be overflow. There will be a warning and __memcpy_chk call that
will abort the program at runtime. */
memcpy (&buf[6], "abcde", 5);
@end smallexample
Such built-in functions are provided for @code{memcpy}, @code{mempcpy},
@code{memmove}, @code{memset}, @code{strcpy}, @code{stpcpy}, @code{strncpy},
@code{strcat} and @code{strncat}.
There are also checking built-in functions for formatted output functions.
@smallexample
int __builtin___sprintf_chk (char *s, int flag, size_t os, const char *fmt,
...);
int __builtin___snprintf_chk (char *s, size_t maxlen, int flag, size_t os,
const char *fmt, ...);
int __builtin___vsprintf_chk (char *s, int flag, size_t os, const char *fmt,
va_list ap);
int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os,
const char *fmt, va_list ap);
@end smallexample
The added @var{flag} argument is passed unchanged to @code{__sprintf_chk}
etc.@: functions and can contain implementation specific flags on what
additional security measures the checking function might take, such as
handling @code{%n} differently.
The @var{os} argument is the object size @var{s} points to, like in the
other built-in functions. There is a small difference in the behavior
though, if @var{os} is @code{(size_t) -1}, the built-in functions are
optimized into the non-checking functions only if @var{flag} is 0, otherwise
the checking function is called with @var{os} argument set to
@code{(size_t) -1}.
In addition to this, there are checking built-in functions
@code{__builtin___printf_chk}, @code{__builtin___vprintf_chk},
@code{__builtin___fprintf_chk} and @code{__builtin___vfprintf_chk}.
These have just one additional argument, @var{flag}, right before
format string @var{fmt}. If the compiler is able to optimize them to
@code{fputc} etc.@: functions, it will, otherwise the checking function
should be called and the @var{flag} argument passed to it.
- [PATCH] inttostr.h: add compile-time buffer overrun checks, Jim Meyering, 2010/10/16
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Bruno Haible, 2010/10/16
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks,
Jim Meyering <=
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Bruno Haible, 2010/10/17
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Jim Meyering, 2010/10/17
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Bruno Haible, 2010/10/17
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Pádraig Brady, 2010/10/18
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Paolo Bonzini, 2010/10/18
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Bruno Haible, 2010/10/18
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Paul Eggert, 2010/10/18
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Ben Pfaff, 2010/10/18
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Pádraig Brady, 2010/10/18
- Re: [PATCH] inttostr.h: add compile-time buffer overrun checks, Pádraig Brady, 2010/10/18