emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] Changes to emacs/src/alloc.c


From: Kim F . Storm
Subject: [Emacs-diffs] Changes to emacs/src/alloc.c
Date: Wed, 01 Dec 2004 09:18:05 -0500

Index: emacs/src/alloc.c
diff -c emacs/src/alloc.c:1.352 emacs/src/alloc.c:1.353
*** emacs/src/alloc.c:1.352     Tue Nov 30 00:30:56 2004
--- emacs/src/alloc.c   Wed Dec  1 14:10:23 2004
***************
*** 516,526 ****
  }
  
  
- /* Like malloc but check for no memory and block interrupt input..  */
- 
  #ifdef XMALLOC_OVERRUN_CHECK
  
  #define XMALLOC_OVERRUN_CHECK_SIZE 16
  static char xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE-4] =
    { 0x9a, 0x9b, 0xae, 0xaf,
      0xbf, 0xbe, 0xce, 0xcf,
--- 516,537 ----
  }
  
  
  #ifdef XMALLOC_OVERRUN_CHECK
  
+ /* Check for overrun in malloc'ed buffers by wrapping a 16 byte header
+    and a 16 byte trailer around each block.
+ 
+    The header consists of 12 fixed bytes + a 4 byte integer contaning the
+    original block size, while the trailer consists of 16 fixed bytes.
+ 
+    The header is used to detect whether this block has been allocated
+    through these functions -- as it seems that some low-level libc
+    functions may bypass the malloc hooks.
+ */
+ 
+ 
  #define XMALLOC_OVERRUN_CHECK_SIZE 16
+ 
  static char xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE-4] =
    { 0x9a, 0x9b, 0xae, 0xaf,
      0xbf, 0xbe, 0xce, 0xcf,
***************
*** 532,605 ****
      0xca, 0xcb, 0xcc, 0xcd,
      0xda, 0xdb, 0xdc, 0xdd };
  
  POINTER_TYPE *
  overrun_check_malloc (size)
       size_t size;
  {
!   register char *val;
  
!   val = (char *) malloc (size + XMALLOC_OVERRUN_CHECK_SIZE*2);
    if (val)
      {
        bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 
4);
-       bcopy (&size, val + XMALLOC_OVERRUN_CHECK_SIZE - 4, sizeof (size));
        val += XMALLOC_OVERRUN_CHECK_SIZE;
        bcopy (xmalloc_overrun_check_trailer, val + size, 
XMALLOC_OVERRUN_CHECK_SIZE);
      }
    return (POINTER_TYPE *)val;
  }
  
  POINTER_TYPE *
  overrun_check_realloc (block, size)
       POINTER_TYPE *block;
       size_t size;
  {
!   register char *val = (char *)block;
  
    if (val
        && bcmp (xmalloc_overrun_check_header,
               val - XMALLOC_OVERRUN_CHECK_SIZE,
               XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
      {
!       size_t osize;
!       bcopy (val - 4, &osize, sizeof (osize));
        if (bcmp (xmalloc_overrun_check_trailer,
                val + osize,
                XMALLOC_OVERRUN_CHECK_SIZE))
        abort ();
        val -= XMALLOC_OVERRUN_CHECK_SIZE;
      }
  
!   val = (char *) realloc ((POINTER_TYPE *)val, size + 
XMALLOC_OVERRUN_CHECK_SIZE*2);
  
    if (val)
      {
        bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 
4);
-       bcopy (&size, val + XMALLOC_OVERRUN_CHECK_SIZE - 4, sizeof (size));
        val += XMALLOC_OVERRUN_CHECK_SIZE;
        bcopy (xmalloc_overrun_check_trailer, val + size, 
XMALLOC_OVERRUN_CHECK_SIZE);
      }
    return (POINTER_TYPE *)val;
  }
  
  void
  overrun_check_free (block)
       POINTER_TYPE *block;
  {
!   char *val = (char *)block;
  
    if (val
        && bcmp (xmalloc_overrun_check_header,
               val - XMALLOC_OVERRUN_CHECK_SIZE,
               XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
      {
!       size_t osize;
!       bcopy (val - 4, &osize, sizeof (osize));
        if (bcmp (xmalloc_overrun_check_trailer,
                val + osize,
                XMALLOC_OVERRUN_CHECK_SIZE))
        abort ();
        val -= XMALLOC_OVERRUN_CHECK_SIZE;
      }
  
    free (val);
--- 543,641 ----
      0xca, 0xcb, 0xcc, 0xcd,
      0xda, 0xdb, 0xdc, 0xdd };
  
+ /* Macros to insert and extract the block size in the header.  */
+ 
+ #define XMALLOC_PUT_SIZE(ptr, size)   \
+   (ptr[-1] = (size & 0xff),           \
+    ptr[-2] = ((size >> 8) & 0xff),    \
+    ptr[-3] = ((size >> 16) & 0xff),   \
+    ptr[-4] = ((size >> 24) & 0xff))
+ 
+ #define XMALLOC_GET_SIZE(ptr)                 \
+   (size_t)((unsigned)(ptr[-1])                |       \
+          ((unsigned)(ptr[-2]) << 8)   |       \
+          ((unsigned)(ptr[-3]) << 16)  |       \
+          ((unsigned)(ptr[-4]) << 24))
+ 
+ 
+ /* Like malloc, but wraps allocated block with header and trailer.  */
+ 
  POINTER_TYPE *
  overrun_check_malloc (size)
       size_t size;
  {
!   register unsigned char *val;
  
!   val = (unsigned char *) malloc (size + XMALLOC_OVERRUN_CHECK_SIZE*2);
    if (val)
      {
        bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 
4);
        val += XMALLOC_OVERRUN_CHECK_SIZE;
+       XMALLOC_PUT_SIZE(val, size);
        bcopy (xmalloc_overrun_check_trailer, val + size, 
XMALLOC_OVERRUN_CHECK_SIZE);
      }
    return (POINTER_TYPE *)val;
  }
  
+ 
+ /* Like realloc, but checks old block for overrun, and wraps new block
+    with header and trailer.  */
+ 
  POINTER_TYPE *
  overrun_check_realloc (block, size)
       POINTER_TYPE *block;
       size_t size;
  {
!   register unsigned char *val = (unsigned char *)block;
  
    if (val
        && bcmp (xmalloc_overrun_check_header,
               val - XMALLOC_OVERRUN_CHECK_SIZE,
               XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
      {
!       size_t osize = XMALLOC_GET_SIZE (val);
        if (bcmp (xmalloc_overrun_check_trailer,
                val + osize,
                XMALLOC_OVERRUN_CHECK_SIZE))
        abort ();
+       bzero (val + osize, XMALLOC_OVERRUN_CHECK_SIZE);
        val -= XMALLOC_OVERRUN_CHECK_SIZE;
+       bzero (val, XMALLOC_OVERRUN_CHECK_SIZE);
      }
  
!   val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + 
XMALLOC_OVERRUN_CHECK_SIZE*2);
  
    if (val)
      {
        bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 
4);
        val += XMALLOC_OVERRUN_CHECK_SIZE;
+       XMALLOC_PUT_SIZE(val, size);
        bcopy (xmalloc_overrun_check_trailer, val + size, 
XMALLOC_OVERRUN_CHECK_SIZE);
      }
    return (POINTER_TYPE *)val;
  }
  
+ /* Like free, but checks block for overrun.  */
+ 
  void
  overrun_check_free (block)
       POINTER_TYPE *block;
  {
!   unsigned char *val = (unsigned char *)block;
  
    if (val
        && bcmp (xmalloc_overrun_check_header,
               val - XMALLOC_OVERRUN_CHECK_SIZE,
               XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
      {
!       size_t osize = XMALLOC_GET_SIZE (val);
        if (bcmp (xmalloc_overrun_check_trailer,
                val + osize,
                XMALLOC_OVERRUN_CHECK_SIZE))
        abort ();
+       bzero (val + osize, XMALLOC_OVERRUN_CHECK_SIZE);
        val -= XMALLOC_OVERRUN_CHECK_SIZE;
+       bzero (val, XMALLOC_OVERRUN_CHECK_SIZE);
      }
  
    free (val);
***************
*** 613,618 ****
--- 649,657 ----
  #define free overrun_check_free
  #endif
  
+ 
+ /* Like malloc but check for no memory and block interrupt input..  */
+ 
  POINTER_TYPE *
  xmalloc (size)
       size_t size;
***************
*** 1527,1536 ****
  
  
  #ifdef GC_CHECK_STRING_OVERRUN
! #define GC_STRING_EXTRA       4
! static char string_overrun_pattern[GC_STRING_EXTRA] = { 0xde, 0xad, 0xbe, 
0xef };
  #else
! #define GC_STRING_EXTRA 0
  #endif
  
  /* Value is the size of an sdata structure large enough to hold NBYTES
--- 1566,1582 ----
  
  
  #ifdef GC_CHECK_STRING_OVERRUN
! 
! /* We check for overrun in string data blocks by appending a small
!    "cookie" after each allocated string data block, and check for the
!    presense of this cookie during GC.  */
! 
! #define GC_STRING_OVERRUN_COOKIE_SIZE 4
! static char string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
!   { 0xde, 0xad, 0xbe, 0xef };
! 
  #else
! #define GC_STRING_OVERRUN_COOKIE_SIZE 0
  #endif
  
  /* Value is the size of an sdata structure large enough to hold NBYTES
***************
*** 1556,1561 ****
--- 1602,1611 ----
  
  #endif /* not GC_CHECK_STRING_BYTES */
  
+ /* Extra bytes to allocate for each string.  */
+ 
+ #define GC_STRING_EXTRA (GC_STRING_OVERRUN_COOKIE_SIZE)
+ 
  /* Initialize string allocation.  Called from init_alloc_once.  */
  
  void
***************
*** 1655,1660 ****
--- 1705,1713 ----
  
  #ifdef GC_CHECK_STRING_FREE_LIST
  
+ /* Walk through the string free list looking for bogus next pointers.
+    This may catch buffer overrun from a previous string.  */
+ 
  static void
  check_string_free_list ()
  {
***************
*** 1703,1709 ****
        total_free_strings += STRING_BLOCK_SIZE;
      }
  
!   check_string_free_list();
  
    /* Pop a Lisp_String off the free-list.  */
    s = string_free_list;
--- 1756,1762 ----
        total_free_strings += STRING_BLOCK_SIZE;
      }
  
!   check_string_free_list ();
  
    /* Pop a Lisp_String off the free-list.  */
    s = string_free_list;
***************
*** 1819,1825 ****
    s->size_byte = nbytes;
    s->data[nbytes] = '\0';
  #ifdef GC_CHECK_STRING_OVERRUN
!   bcopy(string_overrun_pattern, (char *) data + needed, GC_STRING_EXTRA);
  #endif
    b->next_free = (struct sdata *) ((char *) data + needed + GC_STRING_EXTRA);
  
--- 1872,1879 ----
    s->size_byte = nbytes;
    s->data[nbytes] = '\0';
  #ifdef GC_CHECK_STRING_OVERRUN
!   bcopy (string_overrun_cookie, (char *) data + needed,
!        GC_STRING_OVERRUN_COOKIE_SIZE);
  #endif
    b->next_free = (struct sdata *) ((char *) data + needed + GC_STRING_EXTRA);
  
***************
*** 1926,1938 ****
        }
      }
  
!   check_string_free_list();
  
    string_blocks = live_blocks;
    free_large_strings ();
    compact_small_strings ();
  
!   check_string_free_list();
  }
  
  
--- 1980,1992 ----
        }
      }
  
!   check_string_free_list ();
  
    string_blocks = live_blocks;
    free_large_strings ();
    compact_small_strings ();
  
!   check_string_free_list ();
  }
  
  
***************
*** 2004,2019 ****
          else
            nbytes = SDATA_NBYTES (from);
  
- #ifdef GC_CHECK_STRING_BYTES
          if (nbytes > LARGE_STRING_BYTES)
            abort ();
- #endif
  
          nbytes = SDATA_SIZE (nbytes);
          from_end = (struct sdata *) ((char *) from + nbytes + 
GC_STRING_EXTRA);
  
  #ifdef GC_CHECK_STRING_OVERRUN
!         if (bcmp(string_overrun_pattern, ((char *) from_end) - 
GC_STRING_EXTRA, GC_STRING_EXTRA))
            abort ();
  #endif
  
--- 2058,2073 ----
          else
            nbytes = SDATA_NBYTES (from);
  
          if (nbytes > LARGE_STRING_BYTES)
            abort ();
  
          nbytes = SDATA_SIZE (nbytes);
          from_end = (struct sdata *) ((char *) from + nbytes + 
GC_STRING_EXTRA);
  
  #ifdef GC_CHECK_STRING_OVERRUN
!         if (bcmp (string_overrun_cookie,
!                   ((char *) from_end) - GC_STRING_OVERRUN_COOKIE_SIZE,
!                   GC_STRING_OVERRUN_COOKIE_SIZE))
            abort ();
  #endif
  




reply via email to

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