bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-gnulib] proposed vasnprintf patches for address arithmetic and


From: Bruno Haible
Subject: Re: [Bug-gnulib] proposed vasnprintf patches for address arithmetic and stack overflow
Date: Tue, 18 Nov 2003 16:35:06 +0100
User-agent: KMail/1.5

Paul Eggert wrote:
>       I also fixed a potential alloca overflow while I was in the
>       neighborhood.

Thanks, I've now committed the appended patch.

> +# define ALLOCA_LIMIT 8000

I took 4000 instead of 8000: We found out that for alloca to be "safe" in your
sense, i.e. that if there is stack overflow you want a 100% predictable
failure, - on Linux - the argument must be at most 1 page, since the
heap_stack_gap is by default 1 page. And on many CPUs the page size is 4096.

Bruno


2003-11-17  Bruno Haible  <address@hidden>

        * vasnprintf.c (alloca): Remove fallback definition.
        (freea): Remove definition.
        (VASNPRINTF): Use alloca only for small sizes, say <= 4000 bytes.
        Reported by Paul Eggert.

*** vasnprintf.c        Mon Nov 17 02:05:29 2003
--- vasnprintf.c        Mon Nov 17 23:59:59 2003
***************
*** 52,66 ****
  /* Checked size_t computations.  */
  #include "xsize.h"
  
- /* For those losing systems which don't have 'alloca' we have to add
-    some additional code emulating it.  */
- #ifdef HAVE_ALLOCA
- # define freea(p) /* nothing */
- #else
- # define alloca(n) malloc (n)
- # define freea(p) free (p)
- #endif
- 
  #ifdef HAVE_WCHAR_T
  # ifdef HAVE_WCSLEN
  #  define local_wcslen wcslen
--- 52,57 ----
***************
*** 140,149 ****
      }
  
    {
!     size_t buf_neededlength =
!       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
!     CHAR_T *buf =
!       (CHAR_T *) alloca (xtimes (buf_neededlength, sizeof (CHAR_T)));
      const CHAR_T *cp;
      size_t i;
      DIRECTIVE *dp;
--- 131,139 ----
      }
  
    {
!     size_t buf_neededlength;
!     CHAR_T *buf;
!     CHAR_T *buf_malloced;
      const CHAR_T *cp;
      size_t i;
      DIRECTIVE *dp;
***************
*** 152,157 ****
--- 142,169 ----
      size_t allocated;
      size_t length;
  
+     /* Allocate a small buffer that will hold a directive passed to
+        sprintf or snprintf.  */
+     buf_neededlength =
+       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
+ #if HAVE_ALLOCA
+     if (buf_neededlength < 4000 / sizeof (CHAR_T))
+       {
+       buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
+       buf_malloced = NULL;
+       }
+     else
+ #endif
+       {
+       size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
+       if (size_overflow_p (buf_memsize))
+         goto out_of_memory_1;
+       buf = (CHAR_T *) malloc (buf_memsize);
+       if (buf == NULL)
+         goto out_of_memory_1;
+       buf_malloced = buf;
+       }
+ 
      if (resultbuf != NULL)
        {
        result = resultbuf;
***************
*** 789,795 ****
                      {
                        if (!(result == resultbuf || result == NULL))
                          free (result);
!                       freea (buf);
                        CLEANUP ();
                        errno = EINVAL;
                        return NULL;
--- 801,808 ----
                      {
                        if (!(result == resultbuf || result == NULL))
                          free (result);
!                       if (buf_malloced != NULL)
!                         free (buf_malloced);
                        CLEANUP ();
                        errno = EINVAL;
                        return NULL;
***************
*** 847,853 ****
          result = memory;
        }
  
!     freea (buf);
      CLEANUP ();
      *lengthp = length;
      return result;
--- 860,867 ----
          result = memory;
        }
  
!     if (buf_malloced != NULL)
!       free (buf_malloced);
      CLEANUP ();
      *lengthp = length;
      return result;
***************
*** 855,861 ****
    out_of_memory:
      if (!(result == resultbuf || result == NULL))
        free (result);
!     freea (buf);
      CLEANUP ();
      errno = ENOMEM;
      return NULL;
--- 869,877 ----
    out_of_memory:
      if (!(result == resultbuf || result == NULL))
        free (result);
!     if (buf_malloced != NULL)
!       free (buf_malloced);
!   out_of_memory_1:
      CLEANUP ();
      errno = ENOMEM;
      return NULL;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]