aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2011-07-27 17:48:01 -0700
committerPaul Eggert2011-07-27 17:48:01 -0700
commit044c22e545acef592ed95e4e3bb9f8aeff67291a (patch)
tree167a4c706b62b12ea979bdf6ad47e70b66bb0394 /src/alloc.c
parentdbf38e02c9ade4979418f24a99962cfef170b957 (diff)
parent8265d3bb30544e58683fc16e23f9908f3d5d0abc (diff)
downloademacs-044c22e545acef592ed95e4e3bb9f8aeff67291a.tar.gz
emacs-044c22e545acef592ed95e4e3bb9f8aeff67291a.zip
Merge: Integer signedness and overflow and related fixes.
Fixes: debbugs:9079
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c147
1 files changed, 81 insertions, 66 deletions
diff --git a/src/alloc.c b/src/alloc.c
index d48d1f34dbd..eb0185a8e35 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -68,10 +68,6 @@ extern POINTER_TYPE *sbrk ();
68#ifdef DOUG_LEA_MALLOC 68#ifdef DOUG_LEA_MALLOC
69 69
70#include <malloc.h> 70#include <malloc.h>
71/* malloc.h #defines this as size_t, at least in glibc2. */
72#ifndef __malloc_size_t
73#define __malloc_size_t int
74#endif
75 71
76/* Specify maximum number of areas to mmap. It would be nice to use a 72/* Specify maximum number of areas to mmap. It would be nice to use a
77 value that explicitly means "no limit". */ 73 value that explicitly means "no limit". */
@@ -82,9 +78,8 @@ extern POINTER_TYPE *sbrk ();
82 78
83/* The following come from gmalloc.c. */ 79/* The following come from gmalloc.c. */
84 80
85#define __malloc_size_t size_t 81extern size_t _bytes_used;
86extern __malloc_size_t _bytes_used; 82extern size_t __malloc_extra_blocks;
87extern __malloc_size_t __malloc_extra_blocks;
88 83
89#endif /* not DOUG_LEA_MALLOC */ 84#endif /* not DOUG_LEA_MALLOC */
90 85
@@ -214,12 +209,12 @@ EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,};
214/* Pointer to the pure area, and its size. */ 209/* Pointer to the pure area, and its size. */
215 210
216static char *purebeg; 211static char *purebeg;
217static size_t pure_size; 212static ptrdiff_t pure_size;
218 213
219/* Number of bytes of pure storage used before pure storage overflowed. 214/* Number of bytes of pure storage used before pure storage overflowed.
220 If this is non-zero, this implies that an overflow occurred. */ 215 If this is non-zero, this implies that an overflow occurred. */
221 216
222static size_t pure_bytes_used_before_overflow; 217static ptrdiff_t pure_bytes_used_before_overflow;
223 218
224/* Value is non-zero if P points into pure space. */ 219/* Value is non-zero if P points into pure space. */
225 220
@@ -252,7 +247,7 @@ const char *pending_malloc_warning;
252 247
253#if MAX_SAVE_STACK > 0 248#if MAX_SAVE_STACK > 0
254static char *stack_copy; 249static char *stack_copy;
255static size_t stack_copy_size; 250static ptrdiff_t stack_copy_size;
256#endif 251#endif
257 252
258/* Non-zero means ignore malloc warnings. Set during initialization. 253/* Non-zero means ignore malloc warnings. Set during initialization.
@@ -486,14 +481,15 @@ buffer_memory_full (EMACS_INT nbytes)
486 481
487 482
488#ifndef XMALLOC_OVERRUN_CHECK 483#ifndef XMALLOC_OVERRUN_CHECK
489#define XMALLOC_OVERRUN_CHECK_SIZE 0 484#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
490#else 485#else
491 486
492/* Check for overrun in malloc'ed buffers by wrapping a 16 byte header 487/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
493 and a 16 byte trailer around each block. 488 around each block.
494 489
495 The header consists of 12 fixed bytes + a 4 byte integer contaning the 490 The header consists of 16 fixed bytes followed by sizeof (size_t) bytes
496 original block size, while the trailer consists of 16 fixed bytes. 491 containing the original block size in little-endian order,
492 while the trailer consists of 16 fixed bytes.
497 493
498 The header is used to detect whether this block has been allocated 494 The header is used to detect whether this block has been allocated
499 through these functions -- as it seems that some low-level libc 495 through these functions -- as it seems that some low-level libc
@@ -502,31 +498,47 @@ buffer_memory_full (EMACS_INT nbytes)
502 498
503 499
504#define XMALLOC_OVERRUN_CHECK_SIZE 16 500#define XMALLOC_OVERRUN_CHECK_SIZE 16
501#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
502 (2 * XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t))
505 503
506static char xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE-4] = 504static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
507 { 0x9a, 0x9b, 0xae, 0xaf, 505 { '\x9a', '\x9b', '\xae', '\xaf',
508 0xbf, 0xbe, 0xce, 0xcf, 506 '\xbf', '\xbe', '\xce', '\xcf',
509 0xea, 0xeb, 0xec, 0xed }; 507 '\xea', '\xeb', '\xec', '\xed',
508 '\xdf', '\xde', '\x9c', '\x9d' };
510 509
511static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] = 510static char const xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
512 { 0xaa, 0xab, 0xac, 0xad, 511 { '\xaa', '\xab', '\xac', '\xad',
513 0xba, 0xbb, 0xbc, 0xbd, 512 '\xba', '\xbb', '\xbc', '\xbd',
514 0xca, 0xcb, 0xcc, 0xcd, 513 '\xca', '\xcb', '\xcc', '\xcd',
515 0xda, 0xdb, 0xdc, 0xdd }; 514 '\xda', '\xdb', '\xdc', '\xdd' };
516 515
517/* Macros to insert and extract the block size in the header. */ 516/* Insert and extract the block size in the header. */
518 517
519#define XMALLOC_PUT_SIZE(ptr, size) \ 518static void
520 (ptr[-1] = (size & 0xff), \ 519xmalloc_put_size (unsigned char *ptr, size_t size)
521 ptr[-2] = ((size >> 8) & 0xff), \ 520{
522 ptr[-3] = ((size >> 16) & 0xff), \ 521 int i;
523 ptr[-4] = ((size >> 24) & 0xff)) 522 for (i = 0; i < sizeof (size_t); i++)
523 {
524 *--ptr = size & (1 << CHAR_BIT) - 1;
525 size >>= CHAR_BIT;
526 }
527}
524 528
525#define XMALLOC_GET_SIZE(ptr) \ 529static size_t
526 (size_t)((unsigned)(ptr[-1]) | \ 530xmalloc_get_size (unsigned char *ptr)
527 ((unsigned)(ptr[-2]) << 8) | \ 531{
528 ((unsigned)(ptr[-3]) << 16) | \ 532 size_t size = 0;
529 ((unsigned)(ptr[-4]) << 24)) 533 int i;
534 ptr -= sizeof (size_t);
535 for (i = 0; i < sizeof (size_t); i++)
536 {
537 size <<= CHAR_BIT;
538 size += *ptr++;
539 }
540 return size;
541}
530 542
531 543
532/* The call depth in overrun_check functions. For example, this might happen: 544/* The call depth in overrun_check functions. For example, this might happen:
@@ -545,10 +557,10 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
545 557
546 xfree(10032) 558 xfree(10032)
547 overrun_check_free(10032) 559 overrun_check_free(10032)
548 decrease overhed 560 decrease overhead
549 free(10016) <- crash, because 10000 is the original pointer. */ 561 free(10016) <- crash, because 10000 is the original pointer. */
550 562
551static int check_depth; 563static ptrdiff_t check_depth;
552 564
553/* Like malloc, but wraps allocated block with header and trailer. */ 565/* Like malloc, but wraps allocated block with header and trailer. */
554 566
@@ -556,15 +568,16 @@ static POINTER_TYPE *
556overrun_check_malloc (size_t size) 568overrun_check_malloc (size_t size)
557{ 569{
558 register unsigned char *val; 570 register unsigned char *val;
559 size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; 571 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
572 if (SIZE_MAX - overhead < size)
573 abort ();
560 574
561 val = (unsigned char *) malloc (size + overhead); 575 val = (unsigned char *) malloc (size + overhead);
562 if (val && check_depth == 1) 576 if (val && check_depth == 1)
563 { 577 {
564 memcpy (val, xmalloc_overrun_check_header, 578 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
565 XMALLOC_OVERRUN_CHECK_SIZE - 4); 579 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
566 val += XMALLOC_OVERRUN_CHECK_SIZE; 580 xmalloc_put_size (val, size);
567 XMALLOC_PUT_SIZE(val, size);
568 memcpy (val + size, xmalloc_overrun_check_trailer, 581 memcpy (val + size, xmalloc_overrun_check_trailer,
569 XMALLOC_OVERRUN_CHECK_SIZE); 582 XMALLOC_OVERRUN_CHECK_SIZE);
570 } 583 }
@@ -580,31 +593,32 @@ static POINTER_TYPE *
580overrun_check_realloc (POINTER_TYPE *block, size_t size) 593overrun_check_realloc (POINTER_TYPE *block, size_t size)
581{ 594{
582 register unsigned char *val = (unsigned char *) block; 595 register unsigned char *val = (unsigned char *) block;
583 size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; 596 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
597 if (SIZE_MAX - overhead < size)
598 abort ();
584 599
585 if (val 600 if (val
586 && check_depth == 1 601 && check_depth == 1
587 && memcmp (xmalloc_overrun_check_header, 602 && memcmp (xmalloc_overrun_check_header,
588 val - XMALLOC_OVERRUN_CHECK_SIZE, 603 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
589 XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) 604 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
590 { 605 {
591 size_t osize = XMALLOC_GET_SIZE (val); 606 size_t osize = xmalloc_get_size (val);
592 if (memcmp (xmalloc_overrun_check_trailer, val + osize, 607 if (memcmp (xmalloc_overrun_check_trailer, val + osize,
593 XMALLOC_OVERRUN_CHECK_SIZE)) 608 XMALLOC_OVERRUN_CHECK_SIZE))
594 abort (); 609 abort ();
595 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 610 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
596 val -= XMALLOC_OVERRUN_CHECK_SIZE; 611 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
597 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE); 612 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
598 } 613 }
599 614
600 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); 615 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
601 616
602 if (val && check_depth == 1) 617 if (val && check_depth == 1)
603 { 618 {
604 memcpy (val, xmalloc_overrun_check_header, 619 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
605 XMALLOC_OVERRUN_CHECK_SIZE - 4); 620 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
606 val += XMALLOC_OVERRUN_CHECK_SIZE; 621 xmalloc_put_size (val, size);
607 XMALLOC_PUT_SIZE(val, size);
608 memcpy (val + size, xmalloc_overrun_check_trailer, 622 memcpy (val + size, xmalloc_overrun_check_trailer,
609 XMALLOC_OVERRUN_CHECK_SIZE); 623 XMALLOC_OVERRUN_CHECK_SIZE);
610 } 624 }
@@ -623,20 +637,20 @@ overrun_check_free (POINTER_TYPE *block)
623 if (val 637 if (val
624 && check_depth == 1 638 && check_depth == 1
625 && memcmp (xmalloc_overrun_check_header, 639 && memcmp (xmalloc_overrun_check_header,
626 val - XMALLOC_OVERRUN_CHECK_SIZE, 640 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
627 XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) 641 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
628 { 642 {
629 size_t osize = XMALLOC_GET_SIZE (val); 643 size_t osize = xmalloc_get_size (val);
630 if (memcmp (xmalloc_overrun_check_trailer, val + osize, 644 if (memcmp (xmalloc_overrun_check_trailer, val + osize,
631 XMALLOC_OVERRUN_CHECK_SIZE)) 645 XMALLOC_OVERRUN_CHECK_SIZE))
632 abort (); 646 abort ();
633#ifdef XMALLOC_CLEAR_FREE_MEMORY 647#ifdef XMALLOC_CLEAR_FREE_MEMORY
634 val -= XMALLOC_OVERRUN_CHECK_SIZE; 648 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
635 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_SIZE*2); 649 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
636#else 650#else
637 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 651 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
638 val -= XMALLOC_OVERRUN_CHECK_SIZE; 652 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
639 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE); 653 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
640#endif 654#endif
641 } 655 }
642 656
@@ -1092,11 +1106,11 @@ static void (*old_free_hook) (void*, const void*);
1092# define BYTES_USED _bytes_used 1106# define BYTES_USED _bytes_used
1093#endif 1107#endif
1094 1108
1095static __malloc_size_t bytes_used_when_reconsidered; 1109static size_t bytes_used_when_reconsidered;
1096 1110
1097/* Value of _bytes_used, when spare_memory was freed. */ 1111/* Value of _bytes_used, when spare_memory was freed. */
1098 1112
1099static __malloc_size_t bytes_used_when_full; 1113static size_t bytes_used_when_full;
1100 1114
1101/* This function is used as the hook for free to call. */ 1115/* This function is used as the hook for free to call. */
1102 1116
@@ -1661,7 +1675,8 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
1661 calculating a value to be passed to malloc. */ 1675 calculating a value to be passed to malloc. */
1662#define STRING_BYTES_MAX \ 1676#define STRING_BYTES_MAX \
1663 min (STRING_BYTES_BOUND, \ 1677 min (STRING_BYTES_BOUND, \
1664 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_SIZE - GC_STRING_EXTRA \ 1678 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD \
1679 - GC_STRING_EXTRA \
1665 - offsetof (struct sblock, first_data) \ 1680 - offsetof (struct sblock, first_data) \
1666 - SDATA_DATA_OFFSET) \ 1681 - SDATA_DATA_OFFSET) \
1667 & ~(sizeof (EMACS_INT) - 1))) 1682 & ~(sizeof (EMACS_INT) - 1)))
@@ -3320,7 +3335,7 @@ refill_memory_reserve (void)
3320{ 3335{
3321#ifndef SYSTEM_MALLOC 3336#ifndef SYSTEM_MALLOC
3322 if (spare_memory[0] == 0) 3337 if (spare_memory[0] == 0)
3323 spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY); 3338 spare_memory[0] = (char *) malloc (SPARE_MEMORY);
3324 if (spare_memory[1] == 0) 3339 if (spare_memory[1] == 0)
3325 spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), 3340 spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block),
3326 MEM_TYPE_CONS); 3341 MEM_TYPE_CONS);
@@ -4922,7 +4937,7 @@ returns nil, because real GC can't be done. */)
4922 if (NILP (Vpurify_flag)) 4937 if (NILP (Vpurify_flag))
4923 { 4938 {
4924 char *stack; 4939 char *stack;
4925 size_t stack_size; 4940 ptrdiff_t stack_size;
4926 if (&stack_top_variable < stack_bottom) 4941 if (&stack_top_variable < stack_bottom)
4927 { 4942 {
4928 stack = &stack_top_variable; 4943 stack = &stack_top_variable;
@@ -5233,7 +5248,7 @@ static int last_marked_index;
5233 links of a list, in mark_object. In debugging, 5248 links of a list, in mark_object. In debugging,
5234 the call to abort will hit a breakpoint. 5249 the call to abort will hit a breakpoint.
5235 Normally this is zero and the check never goes off. */ 5250 Normally this is zero and the check never goes off. */
5236static size_t mark_object_loop_halt; 5251ptrdiff_t mark_object_loop_halt EXTERNALLY_VISIBLE;
5237 5252
5238static void 5253static void
5239mark_vectorlike (struct Lisp_Vector *ptr) 5254mark_vectorlike (struct Lisp_Vector *ptr)
@@ -5290,7 +5305,7 @@ mark_object (Lisp_Object arg)
5290 void *po; 5305 void *po;
5291 struct mem_node *m; 5306 struct mem_node *m;
5292#endif 5307#endif
5293 size_t cdr_count = 0; 5308 ptrdiff_t cdr_count = 0;
5294 5309
5295 loop: 5310 loop:
5296 5311