From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Kenichi Handa Newsgroups: gmane.emacs.devel Subject: Re: Preventing stack overflows with alloca. Date: Fri, 18 Jun 2004 20:13:24 +0900 (JST) Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <200406181113.UAA03743@etlken.m17n.org> References: NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 (generated by SEMI 1.14.3 - "Ushinoya") Content-Type: text/plain; charset=US-ASCII X-Trace: sea.gmane.org 1087557537 29777 80.91.224.253 (18 Jun 2004 11:18:57 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 18 Jun 2004 11:18:57 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Fri Jun 18 13:18:41 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BbHOK-0000QF-00 for ; Fri, 18 Jun 2004 13:18:40 +0200 Original-Received: from lists.gnu.org ([199.232.76.165]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BbHOK-0005bO-00 for ; Fri, 18 Jun 2004 13:18:40 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BbHPP-0006p2-Tb for emacs-devel@quimby.gnus.org; Fri, 18 Jun 2004 07:19:47 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BbHPI-0006ox-6o for emacs-devel@gnu.org; Fri, 18 Jun 2004 07:19:40 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BbHPF-0006no-R5 for emacs-devel@gnu.org; Fri, 18 Jun 2004 07:19:39 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BbHPF-0006ne-O1 for emacs-devel@gnu.org; Fri, 18 Jun 2004 07:19:37 -0400 Original-Received: from [199.232.41.8] (helo=mx20.gnu.org) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1BbHNi-0002ri-SX for emacs-devel@gnu.org; Fri, 18 Jun 2004 07:18:03 -0400 Original-Received: from [192.47.44.130] (helo=tsukuba.m17n.org) by mx20.gnu.org with esmtp (Exim 4.34) id 1BbHJa-0001La-8j for emacs-devel@gnu.org; Fri, 18 Jun 2004 07:13:47 -0400 Original-Received: from fs.m17n.org (fs.m17n.org [192.47.44.2]) by tsukuba.m17n.org (8.12.3/8.12.3/Debian-6.6) with ESMTP id i5IBDOno018430; Fri, 18 Jun 2004 20:13:25 +0900 Original-Received: from etlken.m17n.org (etlken.m17n.org [192.47.44.125]) by fs.m17n.org (8.11.6p2/8.11.6) with ESMTP id i5IBDOW01248; Fri, 18 Jun 2004 20:13:24 +0900 (JST) Original-Received: (from handa@localhost) by etlken.m17n.org (8.8.8+Sun/3.7W-2001040620) id UAA03743; Fri, 18 Jun 2004 20:13:24 +0900 (JST) Original-To: storm@cua.dk In-reply-to: (storm@cua.dk) User-Agent: SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.2 Emacs/21.3 (sparc-sun-solaris2.6) MULE/5.0 (SAKAKI) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:25080 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:25080 In article , storm@cua.dk (Kim F. Storm) writes: > Jan just installed a change to fns.c to use xmalloc instead of > alloca in string_to_multibyte. > Always using xmalloc seems a bit expensive, so I suggest > only using it if the size is > MAX_ALLOCA (already defined > in fns.c). > But there are other risky uses of alloca, so I suggest the > patch below which takes care of the problems in fns.c. Oops, I have completely forgotten about this problem. Actually I noticed it last year and sent the attached mail, but haven't worked on it any further. I remember Richard agreed with having the macro SAFE_ALLOCA. Of course we need the pairing SAFE_FREE which frees `address' and calls unbind_to if necessary. --- Ken'ichi HANDA handa@m17n.org Date: Thu, 20 Nov 2003 22:01:20 +0900 (JST) From: Kenichi Handa To: emacs-devel@gnu.org Subject: dangerous alloca calls Sender: emacs-devel-bounces+handa=m17n.org@gnu.org With CVS HEAD emacs on GNU/Linux, (mapcar 'car (make-list #x400000 nil)) causes segfault. The attached patch fixes it. But, I found such dangerous alloca calls in several other places. E.g. (format (make-string #x1000000 32)) (apply 'car (make-list #x100000 nil)) It seems that it is better that we use a macro something like this consitently. What do you think? #define SAFE_ALLOCA(address, size, unwind_function) \ do { \ if (size < MAX_ALLOCA) \ address = alloca (size); \ else \ { \ address = xmalloc (size); \ if (unwind_function) \ record_unwind_protect (unwind_function, Qnil); \ } \ } while (0) --- Ken'ichi HANDA handa@m17n.org *** fns.c.~1.346.~ Wed Nov 19 20:06:32 2003 --- fns.c Thu Nov 20 21:26:50 2003 *************** *** 79,84 **** --- 79,88 ---- #ifndef HAVE_UNISTD_H extern long time (); #endif + + /* Don't use alloca for bytes larger than this, lest we overflow + their stack. */ + #define MAX_ALLOCA 16*1024 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, doc: /* Return the argument unchanged. */) *************** *** 2937,2942 **** --- 2941,2956 ---- UNGCPRO; } + static Lisp_Object *mapcar_args; + + static Lisp_Object + mapcar_unwind (arg) + Lisp_Object arg; + { + xfree (mapcar_args); + return Qnil; + } + DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0, doc: /* Apply FUNCTION to each element of SEQUENCE, and concat the results as strings. In between each pair of results, stick in SEPARATOR. Thus, " " as *************** *** 2951,2963 **** register Lisp_Object *args; register int i; struct gcpro gcpro1; len = Flength (sequence); leni = XINT (len); nargs = leni + leni - 1; if (nargs < 0) return build_string (""); ! args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object)); GCPRO1 (separator); mapcar1 (leni, args, function, sequence); --- 2965,2986 ---- register Lisp_Object *args; register int i; struct gcpro gcpro1; + int nbytes; + int count = SPECPDL_INDEX (); len = Flength (sequence); leni = XINT (len); nargs = leni + leni - 1; if (nargs < 0) return build_string (""); ! nbytes = nargs * sizeof (Lisp_Object); ! if (nbytes < MAX_ALLOCA) ! args = (Lisp_Object *) alloca (nbytes); ! else ! { ! args = mapcar_args = (Lisp_Object *) xmalloc (nbytes); ! record_unwind_protect (mapcar_unwind, Qnil); ! } GCPRO1 (separator); mapcar1 (leni, args, function, sequence); *************** *** 2969,2975 **** for (i = 1; i < nargs; i += 2) args[i] = separator; ! return Fconcat (nargs, args); } DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0, --- 2992,3001 ---- for (i = 1; i < nargs; i += 2) args[i] = separator; ! if (nbytes < MAX_ALLOCA) ! return Fconcat (nargs, args); ! else ! return unbind_to (count, Fconcat (nargs, args)); } DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0, *************** *** 2982,2995 **** register Lisp_Object len; register int leni; register Lisp_Object *args; len = Flength (sequence); leni = XFASTINT (len); ! args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object)); mapcar1 (leni, args, function, sequence); ! return Flist (leni, args); } DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0, --- 3008,3035 ---- register Lisp_Object len; register int leni; register Lisp_Object *args; + int nbytes; + int count = SPECPDL_INDEX (); len = Flength (sequence); leni = XFASTINT (len); ! if (leni < 0) return Qnil; ! ! nbytes = leni * sizeof (Lisp_Object); ! if (nbytes < MAX_ALLOCA) ! args = (Lisp_Object *) alloca (nbytes); ! else ! { ! args = mapcar_args = (Lisp_Object *) xmalloc (nbytes); ! record_unwind_protect (mapcar_unwind, Qnil); ! } mapcar1 (leni, args, function, sequence); ! if (nbytes < MAX_ALLOCA) ! return Flist (leni, args); ! else ! return unbind_to (count, Flist (leni, args)); } DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0, *************** *** 3603,3612 **** c = from[i++]; \ } \ while (IS_BASE64_IGNORABLE (c)) - - /* Don't use alloca for regions larger than this, lest we overflow - their stack. */ - #define MAX_ALLOCA 16*1024 /* Table of characters coding the 64 values. */ static char base64_value_to_char[64] = --- 3643,3648 ---- _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://mail.gnu.org/mailman/listinfo/emacs-devel