aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2017-12-09 13:57:38 -0800
committerPaul Eggert2017-12-12 15:17:12 -0800
commit4295050e1194af13afa26403dd3ebdff80824ae0 (patch)
tree354002f3c84f4d8341bb07c5f68529f660a9a405 /src/alloc.c
parent881abfc7fb55db2d00adf352100cc58a6a86c176 (diff)
downloademacs-4295050e1194af13afa26403dd3ebdff80824ae0.tar.gz
emacs-4295050e1194af13afa26403dd3ebdff80824ae0.zip
Narrow pointer bounds when appropriate
This typically occurs in a storage manager, where the caller is expected to access only the newly-allocated object, instead of using the returned value to access unrelated parts of the heap. * src/alloc.c (allocate_string, allocate_string_data) (compact_small_strings, find_string_data_in_pure) (sweep_strings, setup_on_free_list, allocate_vectorlike (pure_alloc): * src/bytecode.c (exec_byte_code): * src/callint.c (Fcall_interactively): * src/dispnew.c (scrolling): * src/editfns.c (styled_format): * src/frame.c (xrdb_get_resource, x_get_resource_string): * src/fringe.c (Fdefine_fringe_bitmap): * src/gmalloc.c (malloc, realloc, aligned_alloc): Narrow pointer bounds when appropriate. * src/alloc.c (SDATA_OF_STRING): * src/lisp.h (make_lisp_symbol) [__CHKP__]: Widen bounds here, though. * src/bytecode.c, src/callint.c, src/dispnew.c, src/editfns.c: * src/emacs.c, src/frame.c, src/fringe.c: Include ptr-bounds.h. * src/ptr-bounds.h (ptr_bounds_clip): New function.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 96b9aaa0d2d..9197ff12ef5 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1727,7 +1727,8 @@ static EMACS_INT total_string_bytes;
1727 a pointer to the `u.data' member of its sdata structure; the 1727 a pointer to the `u.data' member of its sdata structure; the
1728 structure starts at a constant offset in front of that. */ 1728 structure starts at a constant offset in front of that. */
1729 1729
1730#define SDATA_OF_STRING(S) ((sdata *) ((S)->u.s.data - SDATA_DATA_OFFSET)) 1730#define SDATA_OF_STRING(S) ptr_bounds_init ((sdata *) ((S)->u.s.data \
1731 - SDATA_DATA_OFFSET))
1731 1732
1732 1733
1733#ifdef GC_CHECK_STRING_OVERRUN 1734#ifdef GC_CHECK_STRING_OVERRUN
@@ -1919,7 +1920,7 @@ allocate_string (void)
1919 /* Every string on a free list should have NULL data pointer. */ 1920 /* Every string on a free list should have NULL data pointer. */
1920 s->u.s.data = NULL; 1921 s->u.s.data = NULL;
1921 NEXT_FREE_LISP_STRING (s) = string_free_list; 1922 NEXT_FREE_LISP_STRING (s) = string_free_list;
1922 string_free_list = s; 1923 string_free_list = ptr_bounds_clip (s, sizeof *s);
1923 } 1924 }
1924 1925
1925 total_free_strings += STRING_BLOCK_SIZE; 1926 total_free_strings += STRING_BLOCK_SIZE;
@@ -2034,7 +2035,7 @@ allocate_string_data (struct Lisp_String *s,
2034 2035
2035 MALLOC_UNBLOCK_INPUT; 2036 MALLOC_UNBLOCK_INPUT;
2036 2037
2037 s->u.s.data = SDATA_DATA (data); 2038 s->u.s.data = ptr_bounds_clip (SDATA_DATA (data), nbytes + 1);
2038#ifdef GC_CHECK_STRING_BYTES 2039#ifdef GC_CHECK_STRING_BYTES
2039 SDATA_NBYTES (data) = nbytes; 2040 SDATA_NBYTES (data) = nbytes;
2040#endif 2041#endif
@@ -2120,7 +2121,7 @@ sweep_strings (void)
2120 2121
2121 /* Put the string on the free-list. */ 2122 /* Put the string on the free-list. */
2122 NEXT_FREE_LISP_STRING (s) = string_free_list; 2123 NEXT_FREE_LISP_STRING (s) = string_free_list;
2123 string_free_list = s; 2124 string_free_list = ptr_bounds_clip (s, sizeof *s);
2124 ++nfree; 2125 ++nfree;
2125 } 2126 }
2126 } 2127 }
@@ -2128,7 +2129,7 @@ sweep_strings (void)
2128 { 2129 {
2129 /* S was on the free-list before. Put it there again. */ 2130 /* S was on the free-list before. Put it there again. */
2130 NEXT_FREE_LISP_STRING (s) = string_free_list; 2131 NEXT_FREE_LISP_STRING (s) = string_free_list;
2131 string_free_list = s; 2132 string_free_list = ptr_bounds_clip (s, sizeof *s);
2132 ++nfree; 2133 ++nfree;
2133 } 2134 }
2134 } 2135 }
@@ -2224,9 +2225,9 @@ compact_small_strings (void)
2224 nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from); 2225 nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from);
2225 eassert (nbytes <= LARGE_STRING_BYTES); 2226 eassert (nbytes <= LARGE_STRING_BYTES);
2226 2227
2227 nbytes = SDATA_SIZE (nbytes); 2228 ptrdiff_t size = SDATA_SIZE (nbytes);
2228 sdata *from_end = (sdata *) ((char *) from 2229 sdata *from_end = (sdata *) ((char *) from
2229 + nbytes + GC_STRING_EXTRA); 2230 + size + GC_STRING_EXTRA);
2230 2231
2231#ifdef GC_CHECK_STRING_OVERRUN 2232#ifdef GC_CHECK_STRING_OVERRUN
2232 if (memcmp (string_overrun_cookie, 2233 if (memcmp (string_overrun_cookie,
@@ -2240,22 +2241,23 @@ compact_small_strings (void)
2240 { 2241 {
2241 /* If TB is full, proceed with the next sblock. */ 2242 /* If TB is full, proceed with the next sblock. */
2242 sdata *to_end = (sdata *) ((char *) to 2243 sdata *to_end = (sdata *) ((char *) to
2243 + nbytes + GC_STRING_EXTRA); 2244 + size + GC_STRING_EXTRA);
2244 if (to_end > tb_end) 2245 if (to_end > tb_end)
2245 { 2246 {
2246 tb->next_free = to; 2247 tb->next_free = to;
2247 tb = tb->next; 2248 tb = tb->next;
2248 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); 2249 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
2249 to = tb->data; 2250 to = tb->data;
2250 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); 2251 to_end = (sdata *) ((char *) to + size + GC_STRING_EXTRA);
2251 } 2252 }
2252 2253
2253 /* Copy, and update the string's `data' pointer. */ 2254 /* Copy, and update the string's `data' pointer. */
2254 if (from != to) 2255 if (from != to)
2255 { 2256 {
2256 eassert (tb != b || to < from); 2257 eassert (tb != b || to < from);
2257 memmove (to, from, nbytes + GC_STRING_EXTRA); 2258 memmove (to, from, size + GC_STRING_EXTRA);
2258 to->string->u.s.data = SDATA_DATA (to); 2259 to->string->u.s.data
2260 = ptr_bounds_clip (SDATA_DATA (to), nbytes + 1);
2259 } 2261 }
2260 2262
2261 /* Advance past the sdata we copied to. */ 2263 /* Advance past the sdata we copied to. */
@@ -3038,6 +3040,7 @@ static EMACS_INT total_vector_slots, total_free_vector_slots;
3038static void 3040static void
3039setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes) 3041setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes)
3040{ 3042{
3043 v = ptr_bounds_clip (v, nbytes);
3041 eassume (header_size <= nbytes); 3044 eassume (header_size <= nbytes);
3042 ptrdiff_t nwords = (nbytes - header_size) / word_size; 3045 ptrdiff_t nwords = (nbytes - header_size) / word_size;
3043 XSETPVECTYPESIZE (v, PVEC_FREE, 0, nwords); 3046 XSETPVECTYPESIZE (v, PVEC_FREE, 0, nwords);
@@ -3347,7 +3350,7 @@ allocate_vectorlike (ptrdiff_t len)
3347 3350
3348 MALLOC_UNBLOCK_INPUT; 3351 MALLOC_UNBLOCK_INPUT;
3349 3352
3350 return p; 3353 return ptr_bounds_clip (p, nbytes);
3351 } 3354 }
3352} 3355}
3353 3356
@@ -5358,7 +5361,7 @@ pure_alloc (size_t size, int type)
5358 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp; 5361 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp;
5359 5362
5360 if (pure_bytes_used <= pure_size) 5363 if (pure_bytes_used <= pure_size)
5361 return result; 5364 return ptr_bounds_clip (result, size);
5362 5365
5363 /* Don't allocate a large amount here, 5366 /* Don't allocate a large amount here,
5364 because it might get mmap'd and then its address 5367 because it might get mmap'd and then its address
@@ -5443,7 +5446,7 @@ find_string_data_in_pure (const char *data, ptrdiff_t nbytes)
5443 /* Check the remaining characters. */ 5446 /* Check the remaining characters. */
5444 if (memcmp (data, non_lisp_beg + start, nbytes) == 0) 5447 if (memcmp (data, non_lisp_beg + start, nbytes) == 0)
5445 /* Found. */ 5448 /* Found. */
5446 return non_lisp_beg + start; 5449 return ptr_bounds_clip (non_lisp_beg + start, nbytes + 1);
5447 5450
5448 start += last_char_skip; 5451 start += last_char_skip;
5449 } 5452 }