GNU bug report logs - #37795
26.1; Fixnum overflow on dpyinfo->last_user_time

Previous Next

Package: emacs;

Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>

Date: Thu, 17 Oct 2019 16:27:01 UTC

Severity: normal

Found in version 26.1

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 37795 in the body.
You can then email your comments to 37795 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#37795; Package emacs. (Thu, 17 Oct 2019 16:27:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 17 Oct 2019 16:27:05 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: bug-gnu-emacs <at> gnu.org
Subject: 26.1; Fixnum overflow on dpyinfo->last_user_time
Date: Thu, 17 Oct 2019 12:25:43 -0400
I just got an assertion failure:

    lisp.h:1151: Emacs fatal error: assertion failed: !FIXNUM_OVERFLOW_P (n)

where the backtrace looks like:

    #0  0x0817867e in terminate_due_to_signal (sig=6, backtrace_limit=2147483647)
        at emacs.c:371
    #1  0x081edce8 in die
        (msg=0x82e20f1 "!FIXNUM_OVERFLOW_P (n)", file=0x82e2008 "lisp.h", line=1151) at alloc.c:7374
    #2  0x0813a4ee in make_fixnum (n=<optimized out>) at lisp.h:1152
    #3  0x0813bb41 in list2i (x=x <at> entry=1, y=<optimized out>) at lisp.h:3938
    #4  0x08148f7c in x_ewmh_activate_frame (f=f <at> entry=0x8d67980) at xterm.c:11614
    #5  0x0814906f in x_focus_frame (f=0x8d67980, noactivate=false)
        at xterm.c:11664

The relevant data being:

    (gdb) p dpyinfo->last_user_time
    $1 = 537117447
    (gdb)

which was passed to list2i via:

      x_send_client_event (frame, make_fixnum (0), frame,
			   dpyinfo->Xatom_net_active_window,
			   make_fixnum (32),
			   list2i (1, dpyinfo->last_user_time));

Obviously, on 64bit systems this is not a problem, but on 32bit systems
such overflows can happen as I just found out.

I changed `list2i` to use `make_int` instead of `make_fixnum` and it
seems to have fixed the immediate problem, but the same problem showed
up further down in make_lispy_position because the event's timestamp was
similarly large.  So I'm now using the patch below, which seems "good
enough" but I also see other places where we do:

    selection_data = list4 (selection_name, selection_value,
			    INT_TO_INTEGER (timestamp), frame);

so maybe we should be using `INT_TO_INTEGER` rather than `make_int`?

Now, AFAICT the exact value of those timestamps doesn't really matter,
so rather than make_int we could use a wrap-around version of
make_fixnum which truncates the higher bits instead of signaling an
error on overflow.


        Stefan


diff --git a/src/keyboard.c b/src/keyboard.c
index d07376e8bea..fef2c094f26 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5301,7 +5301,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
 		Fcons (posn,
 		       Fcons (Fcons (make_fixnum (xret),
 				     make_fixnum (yret)),
-			      Fcons (make_fixnum (t),
+			      Fcons (make_int (t),
 				     extra_info))));
 }
 
@@ -5326,7 +5326,7 @@ static Lisp_Object
 make_scroll_bar_position (struct input_event *ev, Lisp_Object type)
 {
   return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y),
-		make_fixnum (ev->timestamp),
+		make_int (ev->timestamp),
 		builtin_lisp_symbol (scroll_bar_parts[ev->part]));
 }
 
@@ -5639,7 +5639,7 @@ make_lispy_event (struct input_event *event)
 		    position = list4 (event->frame_or_window,
 				      Qmenu_bar,
 				      Fcons (event->x, event->y),
-				      make_fixnum (event->timestamp));
+				      make_int (event->timestamp));
 
 		    return list2 (item, position);
 		  }
diff --git a/src/lisp.h b/src/lisp.h
index 66e631392e4..fd41b1b97b1 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3929,26 +3929,26 @@ extern void visit_static_gc_roots (struct gc_root_visitor visitor);
 INLINE Lisp_Object
 list1i (EMACS_INT x)
 {
-  return list1 (make_fixnum (x));
+  return list1 (make_int (x));
 }
 
 INLINE Lisp_Object
 list2i (EMACS_INT x, EMACS_INT y)
 {
-  return list2 (make_fixnum (x), make_fixnum (y));
+  return list2 (make_int (x), make_int (y));
 }
 
 INLINE Lisp_Object
 list3i (EMACS_INT x, EMACS_INT y, EMACS_INT w)
 {
-  return list3 (make_fixnum (x), make_fixnum (y), make_fixnum (w));
+  return list3 (make_int (x), make_int (y), make_int (w));
 }
 
 INLINE Lisp_Object
 list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
 {
-  return list4 (make_fixnum (x), make_fixnum (y),
-		make_fixnum (w), make_fixnum (h));
+  return list4 (make_int (x), make_int (y),
+		make_int (w), make_int (h));
 }
 
 extern Lisp_Object make_uninit_bool_vector (EMACS_INT);





Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Fri, 18 Oct 2019 20:34:02 GMT) Full text and rfc822 format available.

Notification sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
bug acknowledged by developer. (Fri, 18 Oct 2019 20:34:02 GMT) Full text and rfc822 format available.

Message #10 received at 37795-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 37795-done <at> debbugs.gnu.org
Subject: re: 26.1; Fixnum overflow on dpyinfo->last_user_time
Date: Fri, 18 Oct 2019 13:33:06 -0700
[Message part 1 (text/plain, inline)]
Thanks for reporting that. I installed the attached patches, which are 
along the lines that you suggested. They also fix a similar bug in 
xterm.c's x_ewmh_activate_frame.

> I also see other places where we do:
> 
>     selection_data = list4 (selection_name, selection_value,
> 			    INT_TO_INTEGER (timestamp), frame);
> 
> so maybe we should be using `INT_TO_INTEGER` rather than `make_int`?

Yes for Time values, since Time might be (usually is?) unsigned and 
might exceed INTMAX_MAX. However, list1i etc. accept signed integers so 
make_int is fine for them.

Changing list1i etc. to use intmax_t and make_int is a small performance 
hit in some cases, but is probably worth it given the reliability 
implications of ignoring integer overflow.

> AFAICT the exact value of those timestamps doesn't really matter,

Some Emacs code subtracts Time values and assumes wraparound overflow, 
so if we shoehorn them into fixnums we would need to take that into 
account. Probably better to leave things be.
[0001-Fix-integer-overflow-bug-in-Time-conversion.patch (text/x-patch, attachment)]
[0002-Generalize-list1i-etc.-to-all-signed-integer-types.patch (text/x-patch, attachment)]

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 16 Nov 2019 12:24:09 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 211 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.