From cb8e2bfba7e712815203264a0c40bf2da1ff4e64 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 22 Sep 2014 22:42:47 -0700 Subject: [PATCH] Fix SAFE_ALLOCA to not exhaust the stack when in a loop. Problem reported by Dmietry Antipov in thread leading to: http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP; the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS remain unfixed. * callproc.c (call_process): Save and restore sa_avail. * lisp.h (USE_SAFE_ALLOCA): Define sa_avail. (AVAIL_ALLOCA): New macro. (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP): Use it, and check against sa_avail rather than MAX_ALLOCA. --- src/ChangeLog | 14 ++++++++++++++ src/callproc.c | 2 ++ src/lisp.h | 15 +++++++++------ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 09426cfbf99..02d7871e884 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2014-09-23 Paul Eggert + + Fix SAFE_ALLOCA to not exhaust the stack when in a loop. + Problem reported by Dmietry Antipov in thread leading to: + http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html + This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP; + the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS + remain unfixed. + * callproc.c (call_process): Save and restore sa_avail. + * lisp.h (USE_SAFE_ALLOCA): Define sa_avail. + (AVAIL_ALLOCA): New macro. + (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP): + Use it, and check against sa_avail rather than MAX_ALLOCA. + 2014-09-22 Dmitry Antipov On OSX, do not free font-specific data more than once (Bug#18501). diff --git a/src/callproc.c b/src/callproc.c index 798f441bdef..4bedf671e83 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -632,6 +632,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, int volatile fd_error_volatile = fd_error; int volatile filefd_volatile = filefd; ptrdiff_t volatile count_volatile = count; + ptrdiff_t volatile sa_avail_volatile = sa_avail; ptrdiff_t volatile sa_count_volatile = sa_count; char **volatile new_argv_volatile = new_argv; int volatile callproc_fd_volatile[CALLPROC_FDS]; @@ -648,6 +649,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, fd_error = fd_error_volatile; filefd = filefd_volatile; count = count_volatile; + sa_avail = sa_avail_volatile; sa_count = sa_count_volatile; new_argv = new_argv_volatile; diff --git a/src/lisp.h b/src/lisp.h index 3795795c49a..21f652b81ac 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4496,12 +4496,15 @@ enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); #define USE_SAFE_ALLOCA \ + ptrdiff_t sa_avail = MAX_ALLOCA; \ ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false +#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size)) + /* SAFE_ALLOCA allocates a simple buffer. */ -#define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA \ - ? alloca (size) \ +#define SAFE_ALLOCA(size) ((size) <= sa_avail \ + ? AVAIL_ALLOCA (size) \ : (sa_must_free = true, record_xmalloc (size))) /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * @@ -4510,8 +4513,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); #define SAFE_NALLOCA(buf, multiplier, nitems) \ do { \ - if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ - (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ + if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier)) \ + (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \ else \ { \ (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ @@ -4543,8 +4546,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); #define SAFE_ALLOCA_LISP(buf, nelt) \ do { \ - if ((nelt) <= MAX_ALLOCA / word_size) \ - (buf) = alloca ((nelt) * word_size); \ + if ((nelt) <= sa_avail / word_size) \ + (buf) = AVAIL_ALLOCA ((nelt) * word_size); \ else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ { \ Lisp_Object arg_; \ -- 2.39.5