This patches fixes an integer overflow in libiberty, which leads to
crashes in binutils.  The long version of the objalloc_alloc macro
would have needed another conditional, so I removed that and replaced
it with a call to the actual implementation.

This has been compiled-tested only.  We do not use this function in
GCC, therefore I want to commit this just to the trunk.

2012-08-29  Florian Weimer  <f...@deneb.enyo.de>

        PR other/54411
        * objalloc.h (objalloc_alloc): Always use the simple definition of
        the macro.

2012-08-29  Florian Weimer  <f...@deneb.enyo.de>

        PR other/54411
        * objalloc.c (_objalloc_alloc): Add overflow check covering
        alignment and CHUNK_HEADER_SIZE addition.

Index: include/objalloc.h
===================================================================
--- include/objalloc.h  (revision 190780)
+++ include/objalloc.h  (working copy)
@@ -1,5 +1,5 @@
 /* objalloc.h -- routines to allocate memory for objects
-   Copyright 1997, 2001 Free Software Foundation, Inc.
+   Copyright 1997-2012 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Solutions.
 
 This program is free software; you can redistribute it and/or modify it
@@ -71,38 +71,8 @@
 
 extern void *_objalloc_alloc (struct objalloc *, unsigned long);
 
-/* The macro version of objalloc_alloc.  We only define this if using
-   gcc, because otherwise we would have to evaluate the arguments
-   multiple times, or use a temporary field as obstack.h does.  */
-
-#if defined (__GNUC__) && defined (__STDC__) && __STDC__
-
-/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
-   does not implement __extension__.  But that compiler doesn't define
-   __GNUC_MINOR__.  */
-#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
-#define __extension__
-#endif
-
-#define objalloc_alloc(o, l)                                           \
-  __extension__                                                                
\
-  ({ struct objalloc *__o = (o);                                       \
-     unsigned long __len = (l);                                                
\
-     if (__len == 0)                                                   \
-       __len = 1;                                                      \
-     __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);     \
-     (__len <= __o->current_space                                      \
-      ? (__o->current_ptr += __len,                                    \
-        __o->current_space -= __len,                                   \
-        (void *) (__o->current_ptr - __len))                           \
-      : _objalloc_alloc (__o, __len)); })
-
-#else /* ! __GNUC__ */
-
 #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
 
-#endif /* ! __GNUC__ */
-
 /* Free an entire objalloc structure.  */
 
 extern void objalloc_free (struct objalloc *);
Index: libiberty/objalloc.c
===================================================================
--- libiberty/objalloc.c        (revision 190780)
+++ libiberty/objalloc.c        (working copy)
@@ -1,5 +1,5 @@
 /* objalloc.c -- routines to allocate memory for objects
-   Copyright 1997 Free Software Foundation, Inc.
+   Copyright 1997-2012 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Solutions.
 
 This program is free software; you can redistribute it and/or modify it
@@ -112,8 +112,9 @@
 /* Allocate space from an objalloc structure.  */
 
 PTR
-_objalloc_alloc (struct objalloc *o, unsigned long len)
+_objalloc_alloc (struct objalloc *o, unsigned long original_len)
 {
+  unsigned long len = original_len;
   /* We avoid confusion from zero sized objects by always allocating
      at least 1 byte.  */
   if (len == 0)
@@ -121,6 +122,11 @@
 
   len = (len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);
 
+  /* Check for overflow in the alignment operator above and the malloc
+     argument below. */
+  if (len + CHUNK_HEADER_SIZE < original_len)
+    return NULL;
+
   if (len <= o->current_space)
     {
       o->current_ptr += len;

Reply via email to