From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Jeff Norden Newsgroups: gmane.emacs.bugs Subject: bug#43499: 27.1; It is possible for (forward-comment -1) to crash emacs Date: Fri, 18 Sep 2020 20:25:33 -0500 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="17718"; mail-complaints-to="usenet@ciao.gmane.io" To: 43499@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Sep 19 03:26:23 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJRdu-0004Tn-UA for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 19 Sep 2020 03:26:23 +0200 Original-Received: from localhost ([::1]:59552 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kJRds-0002m6-UJ for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 18 Sep 2020 21:26:20 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39808) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kJRdb-0002lv-4d for bug-gnu-emacs@gnu.org; Fri, 18 Sep 2020 21:26:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:33823) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kJRda-0005fg-3J for bug-gnu-emacs@gnu.org; Fri, 18 Sep 2020 21:26:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kJRda-0004ts-0G for bug-gnu-emacs@gnu.org; Fri, 18 Sep 2020 21:26:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Jeff Norden Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 19 Sep 2020 01:26:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 43499 X-GNU-PR-Package: emacs X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.160047874618809 (code B ref -1); Sat, 19 Sep 2020 01:26:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 19 Sep 2020 01:25:46 +0000 Original-Received: from localhost ([127.0.0.1]:45369 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJRdJ-0004tJ-LX for submit@debbugs.gnu.org; Fri, 18 Sep 2020 21:25:46 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:54216) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJRdI-0004tB-5h for submit@debbugs.gnu.org; Fri, 18 Sep 2020 21:25:44 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39760) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kJRdH-0002lA-W0 for bug-gnu-emacs@gnu.org; Fri, 18 Sep 2020 21:25:44 -0400 Original-Received: from mta.tntech.edu ([149.149.2.87]:28120) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kJRdD-0005ZP-RV for bug-gnu-emacs@gnu.org; Fri, 18 Sep 2020 21:25:43 -0400 Original-Received: from math.tntech.edu (unknown [149.149.102.6]) by mta.tntech.edu (Postfix) with ESMTPS id 403E8300007B for ; Fri, 18 Sep 2020 20:25:36 -0500 (CDT) Original-Received: from norden.tntech.edu ([149.149.102.4] helo=norden.math.tntech.edu) by math.tntech.edu with esmtp (Exim 4.92) (envelope-from ) id 1kJRd7-0001aD-Sk for bug-gnu-emacs@gnu.org; Fri, 18 Sep 2020 20:25:34 -0500 Original-Received: by norden.math.tntech.edu (Postfix, from userid 742) id CC6C72572B73; Fri, 18 Sep 2020 20:25:33 -0500 (CDT) X-SA-Spam-Score: 0.0 X-SA-Spam-Report: Spam detection software, running on the system "math.tntech.edu", has NOT identified this incoming email as spam. If you have any questions, contact @@CONTACT_ADDRESS@@ pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 T_SPF_HELO_TEMPERROR SPF: test of HELO record failed (temperror) Received-SPF: pass client-ip=149.149.2.87; envelope-from=jnorden@tntech.edu; helo=mta.tntech.edu X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/18 21:25:36 X-ACL-Warn: Detected OS = Linux 3.11 and newer [fuzzy] X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:188358 Archived-At: --=-=-= Content-Type: text/plain In an unusual circumstance, (forward-comment -1) can move the point before the accessible buffer text. This can even result in the point becoming negative. In the worst-case scenario, emacs becomes completely unresponsive, and it might even be necessary to reboot the computer. Instructions for those who want to verify this bug are below. But the explanation and fix are fairly simple, so I'll start with that. The problem is the following code for forward-comment, from syntax.c starting at line 2542 (emacs-27.1). This is in the 2nd part of the function, which is the code that runs when forward-comment is called with a negative arg to move backwards. I've marked two relevant lines with * and **. if (code == Scomment_fence) { /* Skip until first preceding unquoted comment_fence. */ bool fence_found = 0; ptrdiff_t ini = from, ini_byte = from_byte; while (1) { * DEC_BOTH (from, from_byte); UPDATE_SYNTAX_TABLE_BACKWARD (from); c = FETCH_CHAR_AS_MULTIBYTE (from_byte); if (SYNTAX (c) == Scomment_fence && !char_quoted (from, from_byte)) { fence_found = 1; break; } ** else if (from == stop) break; rarely_quit (++quit_count); } The loop should, I think, be changed to the following. The only change is how from and stop are compared. while (from > stop) { DEC_BOTH (from, from_byte); UPDATE_SYNTAX_TABLE_BACKWARD (from); c = FETCH_CHAR_AS_MULTIBYTE (from_byte); if (SYNTAX (c) == Scomment_fence && !char_quoted (from, from_byte)) { fence_found = 1; break; } rarely_quit (++quit_count); } Analysis: 'stop' is equal to BEGV. 'from' started out at PT, but will already have been decremented once before the above is reached (to check the syntax of the char before the point). This makes it possible for (from == stop) to already be true, and thus (*) can make (from < stop) true the first time it runs. If that happens, the test at (**) will never succeed. This can occur if the char at point-min has comment-fence syntax, and the point is at point-min+1 when (forward-comment -1) is called. --- If this bug is triggerd in a narrowed buffer, and a there is another fence before point-min, then forward-comment will currently return with the point set before BEGV. This is likely to lead to an args-out-of-range error. However, if no fence if found, or if the buffer wasn't narrowed, then 'from' becomes negative. This may result in a segfault, but it can also happen that another fence-comment char will be found in the memory being scanned, and forward-comment returns with the point set to a basically random negative number. It seems that this can cause all hell to break loose, but I didn't figure out the exact mechanism. Emacs can become unresponsive to C-g or any keyboard input. It seems to be constantly updating the display, which may cause the entire window system to hang. --- The first thing I tried was to just change (**) to 'else if (from <= stop)'. The suggested fix above is better, though. It will never try to access any characters before BEGV. It will also put the point at BEGV if a matching fence is found there, which is probably why the original test is placed after the syntax check. An alternative would be to check for (from == stop) before the loop, which is equivalent. I've been using a version of 27.1 with the above change for a few days with no problems. A simple git-patch for this change is also attached. ------------------------------ Here are instructions for verifying this bug. The behavior below is what I've observed under linux with the mate and gnome3 desktops. I don't know what will happen under ms-windows or macos. 1) Please be sure that there are no open applications with unsaved data. Obviously, don't try this on a mission-critical server. 2) The safest thing is to run 'emacs -nw -Q' from a terminal window. Or, use a linux console, as long as you will be able to switch to another console to kill emacs. 3) Open a plain fundamental-mode buffer. Do "M-x modify-syntax-entry @ !" to make the at-sign into a generic fence comment character. Then put @This is a fenced comment@ at the start of the buffer. The first at-sign should be the first character of the buffer. 4) Try 'M-: (forward-comment -1)' with the cursor at the start of the second line. The cursor should move to the beginning of the buffer, verifying that the first line is a comment. 5) Now place the cursor on the 'T' after the first at-sign, so the point is between them, at the 2nd buffer position. Do 'M-: (forward-comment -1)' again, and emacs should be dead. ------------------------------ When I trip this bug, emacs won't respond to C-g or any other key. I can close the terminal window, which kills emacs. If I do the above from a graphical emacs, then my entire desktop freezes, including the mouse. I can recover with ctrl-alt-backspace, but that is often disabled by default. If I switch to a linux console, top shows that both emacs and the window-manager are each using about 100% of a cpu. I can recover by re-starting X from here. Someone unable to get to a console might need to power-cycle the computer. If I do 'M-x toggle-debug-on-error' between steps 4 and 5, then emacs will quickly die with a segfault. If, in step 5, I instead do M-: (cons (forward-comment -1) (point)) I can see in the frozen window that forward-comment did return 't with PT<0. So, except when emacs segfaults, the problem isn't during forward-comment, it's what happens after the negative point-value is returned. AFAICT, there doesn't seem to be a similar problem with (forward-comment +1). ============================== In case you are wondering how I stumbled onto this, in CWEB (the Knuth/Levy literate programming system) sections are defined and referenced with the following syntax: @ One way to highlight these is to set the syntax-table property of the initial '@' and the final '>' to comment-fence, which also prevents the description itself from being interpreted as code. A CWEB file won't ever start with this construct, but the definition of a code section does, and it is useful to temporarily narrow the buffer to a section of code, including its name. When I traced the source of args-out-of-range errors to forward-comment, I realized that narrowing the buffer wasn't even necessary. When I tested that hypothesis, emacs froze up my desktop. -Jeff ============================================================ In GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.22, cairo version 1.17.3) of 2020-08-28 built on juergen Windowing system distributor 'The X.Org Foundation', version 11.0.12008000 System Description: Manjaro Linux Recent messages: For information about GNU Emacs and the GNU system, type C-h C-a. Configured using: 'configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib --localstatedir=/var --with-x-toolkit=gtk3 --with-xft --with-wide-int --with-modules --with-cairo --with-harfbuzz 'CFLAGS=-march=x86-64 -mtune=generic -O2 -pipe -fno-plt' CPPFLAGS=-D_FORTIFY_SOURCE=2 LDFLAGS=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now' Configured features: XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY INOTIFY ACL GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS LIBSYSTEMD JSON PDUMPER LCMS2 GMP Important settings: value of $LC_COLLATE: C value of $LC_MONETARY: en_US.UTF-8 value of $LC_NUMERIC: en_US.UTF-8 value of $LC_TIME: en_US.UTF-8 value of $LANG: en_US.utf8 locale-coding-system: utf-8-unix Major mode: Lisp Interaction Minor modes in effect: mouse-wheel-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t line-number-mode: t Load-path shadows: None found. Features: (shadow sort flyspell ispell mail-extr emacsbug message rmc puny dired dired-loaddefs format-spec rfc822 mml easymenu mml-sec password-cache epa derived epg epg-config gnus-util rmail rmail-loaddefs text-property-search time-date subr-x seq byte-opt gv bytecomp byte-compile cconv mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils jeff-tex jeff-commands jeff-keys win-move jeff-custom tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting cairo move-toolbar gtk x-toolkit x multi-tty make-network-process emacs) Memory information: ((conses 16 52204 5081) (symbols 48 18686 1) (strings 32 74127 3714) (string-bytes 1 1711817) (vectors 16 11238) (vector-slots 8 537394 9004) (floats 8 29 30) (intervals 56 203 0) (buffers 1000 11)) --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Fix-bug-in-forward-comment-that-allowed-the-point-to.patch Content-Transfer-Encoding: base64 RnJvbSA1NzkyZmNlYWQ3YmMzNzllNGQ4NTU3NDZiNTlhZTBhZGU1MWUxMzAzIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQ0KRnJvbTogSmVmZiBOb3JkZW4gPGpub2RlbkB0bnRlY2guZWR1Pg0KRGF0 ZTogRnJpLCAxOCBTZXAgMjAyMCAxOTozNDoxOCAtMDUwMA0KU3ViamVjdDogW1BBVENIXSBGaXgg YnVnIGluIGZvcndhcmQtY29tbWVudCB0aGF0IGFsbG93ZWQgdGhlIHBvaW50IHRvIG1vdmUNCiBi ZWZvcmUgQkVHViwgYW5kIGV2ZW4gYmVjb21lIG5lZ2F0aXZlLg0KDQotLS0NCiBzcmMvc3ludGF4 LmMgfCA0ICstLS0NCiAxIGZpbGUgY2hhbmdlZCwgMSBpbnNlcnRpb24oKyksIDMgZGVsZXRpb25z KC0pDQoNCmRpZmYgLS1naXQgYS9zcmMvc3ludGF4LmMgYi9zcmMvc3ludGF4LmMNCmluZGV4IDdm MGZjMzQuLjNkY2M3ZWMgMTAwNjQ0DQotLS0gYS9zcmMvc3ludGF4LmMNCisrKyBiL3NyYy9zeW50 YXguYw0KQEAgLTI1NDIsNyArMjU0Miw3IEBAIGJldHdlZW4gdGhlbSwgcmV0dXJuIHQ7IG90aGVy d2lzZSByZXR1cm4gbmlsLiAgKi8pDQogCSAgICAgIGJvb2wgZmVuY2VfZm91bmQgPSAwOw0KIAkg ICAgICBwdHJkaWZmX3QgaW5pID0gZnJvbSwgaW5pX2J5dGUgPSBmcm9tX2J5dGU7DQogDQotCSAg ICAgIHdoaWxlICgxKQ0KKwkgICAgICB3aGlsZSAoZnJvbSA+IHN0b3ApDQogCQl7DQogCQkgIGRl Y19ib3RoICgmZnJvbSwgJmZyb21fYnl0ZSk7DQogCQkgIFVQREFURV9TWU5UQVhfVEFCTEVfQkFD S1dBUkQgKGZyb20pOw0KQEAgLTI1NTMsOCArMjU1Myw2IEBAIGJldHdlZW4gdGhlbSwgcmV0dXJu IHQ7IG90aGVyd2lzZSByZXR1cm4gbmlsLiAgKi8pDQogCQkgICAgICBmZW5jZV9mb3VuZCA9IDE7 DQogCQkgICAgICBicmVhazsNCiAJCSAgICB9DQotCQkgIGVsc2UgaWYgKGZyb20gPT0gc3RvcCkN Ci0JCSAgICBicmVhazsNCiAJCSAgcmFyZWx5X3F1aXQgKCsrcXVpdF9jb3VudCk7DQogCQl9DQog CSAgICAgIGlmIChmZW5jZV9mb3VuZCA9PSAwKQ0KLS0gDQoyLjcuNA0KDQo= --=-=-=--