[PATCH v2.1] Use saturated arithmetic for overflow detection.
Joseph S. Myers
joseph@codesourcery.com
Tue Dec 3 16:42:00 GMT 2013
On Tue, 3 Dec 2013, Ondrej Bilka wrote:
> @@ -1067,10 +1068,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
> /* Allocate dynamically an array which definitely is long \
> enough for the wide character version. Each byte in the \
> multi-byte string can produce at most one wide character. */ \
> - if (__libc_use_alloca (len * sizeof (wchar_t))) \
> - string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \
> - else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \
> - == NULL) \
> + size_t needed = mul_s (len, sizeof (wchar_t)); \
> + if (__libc_use_alloca (needed)) \
> + string = (CHAR_T *) alloca (needed); \
> + else if ((string = (CHAR_T *) malloc (needed)) == NULL) \
If this is fixing a bug with a missing overflow check, where valid (even
if unusual) inputs could result in overflow, a corresponding bug should be
filed in Bugzilla if not already present. (Distribution security people
can decide which such bugs are worth requesting CVEs for.)
> +static inline __attribute__((always_inline, unused)) size_t
Space before open parenthesis. Function needs a comment explaining its
semantics.
> +static inline __attribute__((always_inline, unused)) size_t
> +mul_s (size_t x, size_t y)
Likewise.
> +{
> + if (__builtin_constant_p (x))
> + {
> + size_t tmp = x;
> + x = y;
> + y = tmp;
> + }
> + if (__builtin_constant_p (y))
> + {
> + if (y == 0)
> + return 0;
> + if (__glibc_unlikely (x > SIZE_MAX / y))
> + return SIZE_MAX;
> + return x * y;
> + }
Have you verified that both the case of constant x and the case of
constant y get optimized into a single comparison against a constant? It
would be less confusing anyway for each "if" to repeat the contents rather
than swapping x and y, given that if __builtin_constant_p holds then only
one "if" is going to be used anyway.
> +static inline __attribute__((always_inline, unused)) size_t
> +div_s (size_t x, size_t y)
I don't see the point of this function, and it's particularly confusing
without properly documented semantics.
> @@ -619,14 +620,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
> if (i > 0 && *pat != NULL)
> --i;
>
> - if (__libc_use_alloca (alloca_used
> - + i * sizeof (struct gaih_addrtuple)))
> - addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
> - alloca_used);
> + size_t needed = mul_s (i, sizeof (struct gaih_addrtuple));
> + if (__libc_use_alloca (alloca_used + needed))
> + addrmem = alloca_account (needed, alloca_used);
Again, if fixing a user-visible bug (rather than simply reworking existing
logic that already checks correctly for overflow) then please file it in
Bugzilla.
--
Joseph S. Myers
joseph@codesourcery.com
More information about the Libc-alpha
mailing list