Changeset 5011:512edfc544df in roaraudio


Ignore:
Timestamp:
05/26/11 10:14:15 (11 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Added memory corruption and double free detection to buffer API.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5010 r5011  
    22        * Updated roar_panic() (Closes: #132) 
    33        * Updated roar_reset() (Closes: #131) 
     4        * Added memory corruption and double free detection to buffer API. 
    45 
    56v. 0.4beta6 - Mon May 23 2011 19:49 CEST 
  • include/libroar/buffer.h

    r4901 r5011  
    4343#define ROAR_BUFFER_FLAG_RING            0x02 
    4444#define ROAR_BUFFER_FLAG_FREE_RUNNING    0x04 
     45 
     46// for memory corruption detection: 
     47#define ROAR_BUFFER_FLAG_USEABLE         0x40 
     48#define ROAR_BUFFER_FLAG_FREED           0x80 
    4549 
    4650#define ROAR_BUFFER_SET                     0 
  • libroar/buffer.c

    r4989 r5011  
    5757}; 
    5858 
    59 #define _ckbuf(m)  if ( buf == NULL || (m) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } 
     59#define _ckbuf_free(m)  if ( buf == NULL || (m) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } 
     60#define _ckbuf(m)  _ckbuf_free((m)); if ( _ckmem_corruption(buf) == -1 ) return -1; 
     61 
     62static int inline _ckmem_corruption(struct roar_buffer * buf) { 
     63 int flags = buf->flags & (ROAR_BUFFER_FLAG_USEABLE|ROAR_BUFFER_FLAG_FREED); 
     64 
     65 ROAR_DBG("_ckmem_corruption(buf=%p{.flags=0x%.4x, ...} = ?", buf, buf->flags); 
     66 
     67 if ( flags == ROAR_BUFFER_FLAG_USEABLE ) { 
     68  // seems ok, continue with next check. 
     69 } else if ( flags == ROAR_BUFFER_FLAG_FREED ) { 
     70  roar_panic(ROAR_FATAL_ERROR_MEMORY_USED_AFTER_FREE, NULL); 
     71  roar_err_set(ROAR_ERROR_FAULT); 
     72  return -1; 
     73 } else { 
     74  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); 
     75  roar_err_set(ROAR_ERROR_BADCKSUM); 
     76  return -1; 
     77 } 
     78 
     79 if ( buf->refc == 0 ) { 
     80  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); 
     81 } 
     82 
     83 return 0; 
     84} 
    6085 
    6186int roar_buffer_new_data (struct roar_buffer ** buf, size_t len, void ** data) { 
     
    93118 ROAR_DBG("buffer_new(buf=%p, len=%i) = ?", buf, len); 
    94119 
    95  _ckbuf(data == NULL) 
     120 _ckbuf_free(data == NULL) 
    96121 
    97122 if ((new = roar_mm_malloc(sizeof(struct roar_buffer))) == NULL) { 
     
    104129 new->data      = data; 
    105130 
    106  new->flags     = ROAR_BUFFER_FLAG_NONE|ROAR_BUFFER_FLAG_NOFREE; 
     131 new->flags     = ROAR_BUFFER_FLAG_NONE|ROAR_BUFFER_FLAG_NOFREE|ROAR_BUFFER_FLAG_USEABLE; 
    107132 new->type      = -1; 
    108133 
     
    129154 
    130155int roar_buffer_unref     (struct roar_buffer * buf) { 
    131  struct roar_buffer * next; 
    132  
    133  _ckbuf(0) 
     156 struct roar_buffer * next, * cur; 
     157 int flags; 
     158 
     159 ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); 
     160 
     161 _ckbuf_free(0) 
     162 
     163 ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); 
     164 
     165 flags = buf->flags & (ROAR_BUFFER_FLAG_USEABLE|ROAR_BUFFER_FLAG_FREED); 
     166 if ( flags == ROAR_BUFFER_FLAG_FREED ) { 
     167  roar_panic(ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE, NULL); 
     168 } 
     169 
     170 _ckmem_corruption(buf); 
     171 
     172 ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); 
    134173 
    135174 if ( buf->refc == 0 ) { 
     
    141180 buf->refc--; 
    142181 
    143  if ( buf->refc ) 
     182 if ( buf->refc ) { 
     183  ROAR_DBG("roar_buffer_unref(buf=%p) = 0", buf); 
    144184  return 0; 
    145  
    146  while ((next = buf->next)) { 
    147   if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 ) 
    148    roar_mm_free(buf->data); 
    149  
    150   roar_mm_free(buf); 
    151   buf = next; 
    152  } 
    153  
    154  if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 ) 
     185 } 
     186 
     187 ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); 
     188 
     189 cur = buf->next; 
     190 while (cur != NULL) { 
     191  flags = cur->flags & (ROAR_BUFFER_FLAG_USEABLE|ROAR_BUFFER_FLAG_FREED); 
     192  if ( flags == ROAR_BUFFER_FLAG_FREED ) { 
     193   roar_panic(ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE, NULL); 
     194  } 
     195 
     196  ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); 
     197 
     198  _ckmem_corruption(cur); 
     199 
     200  if ( roar_buffer_get_flag(cur, ROAR_BUFFER_FLAG_NOFREE) != 1 ) 
     201   roar_mm_free(cur->data); 
     202 
     203  cur->flags = ROAR_BUFFER_FLAG_FREED; 
     204  next = cur->next; 
     205  roar_mm_free(cur); 
     206  cur = next; 
     207 } 
     208 
     209 ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); 
     210 
     211 if ( !(buf->flags & ROAR_BUFFER_FLAG_NOFREE) ) 
    155212  roar_mm_free(buf->data); 
    156213 
     214 ROAR_DBG("roar_buffer_unref(buf=%p): setting flags = ROAR_BUFFER_FLAG_FREED", buf); 
     215 buf->flags = ROAR_BUFFER_FLAG_FREED; 
     216 
    157217 roar_mm_free(buf); 
    158218 
     219 ROAR_DBG("roar_buffer_unref(buf=%p) = 0", buf); 
    159220 return 0; 
    160221} 
     
    238299 struct roar_buffer * n; 
    239300 
    240  _ckbuf(0) 
     301 _ckbuf_free(0) 
    241302 
    242303 if ( len == 0 ) { 
     
    293354 void * cd; 
    294355 
    295  _ckbuf(len == NULL || data == NULL); 
     356 _ckbuf_free(len == NULL || data == NULL); 
    296357 
    297358 if ( *buf == NULL ) { 
     
    305366 
    306367 *len = 0; 
     368 
     369 _ckmem_corruption(cur); 
    307370 
    308371 while (todo && cur != NULL) { 
     
    336399   if ( roar_buffer_next(&cur) == -1 ) 
    337400    return -1; 
     401   _ckmem_corruption(cur); 
    338402  } 
    339403 
Note: See TracChangeset for help on using the changeset viewer.