From: Kalle Olavi Niemitalo Date: Tue, 18 Aug 2020 15:03:07 +0000 (+0200) Subject: Fix buffer overflow in x-send-client-message X-Git-Tag: emacs-28.0.90~6549 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=4670969e6791c76460c647b5f86317ddb75898bc;p=emacs.git Fix buffer overflow in x-send-client-message * xselect.c (x_fill_property_data): Add parameter NELEMENTS_MAX. * xterm.h (x_fill_property_data): Update prototype. * xselect.c (Fx_send_client_event): Update call. This fixes a buffer overflow in event.xclient.data. * xfns.c (Fx_change_window_property): Update call (bug#23482). Copyright-paperwork-exempt: yes --- diff --git a/src/xfns.c b/src/xfns.c index d56fc0ad05d..78f977bf0aa 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5890,7 +5890,8 @@ If WINDOW-ID is non-nil, change the property of that window instead elsize = element_format == 32 ? sizeof (long) : element_format >> 3; data = xnmalloc (nelements, elsize); - x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); + x_fill_property_data (FRAME_X_DISPLAY (f), value, data, nelements, + element_format); } else { diff --git a/src/xselect.c b/src/xselect.c index bf50c598b2a..383aebf96c8 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -2276,23 +2276,28 @@ x_check_property_data (Lisp_Object data) DPY is the display use to look up X atoms. DATA is a Lisp list of values to be converted. - RET is the C array that contains the converted values. It is assumed - it is big enough to hold all values. + RET is the C array that contains the converted values. + NELEMENTS_MAX is the number of values that will fit in RET. + Any excess values in DATA are ignored. FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to be stored in RET. Note that long is used for 32 even if long is more than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and XClientMessageEvent). */ void -x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) +x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, + int nelements_max, int format) { unsigned long val; unsigned long *d32 = (unsigned long *) ret; unsigned short *d16 = (unsigned short *) ret; unsigned char *d08 = (unsigned char *) ret; + int nelements; Lisp_Object iter; - for (iter = data; CONSP (iter); iter = XCDR (iter)) + for (iter = data, nelements = 0; + CONSP (iter) && nelements < nelements_max; + iter = XCDR (iter), nelements++) { Lisp_Object o = XCAR (iter); @@ -2593,7 +2598,9 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l)); + /* event.xclient.data can hold 20 chars, 10 shorts, or 5 longs. */ x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, + 5 * 32 / event.xclient.format, event.xclient.format); /* If event mask is 0 the event is sent to the client that created diff --git a/src/xterm.h b/src/xterm.h index bc10043c54c..db8d5847814 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1207,6 +1207,7 @@ extern int x_check_property_data (Lisp_Object); extern void x_fill_property_data (Display *, Lisp_Object, void *, + int, int); extern Lisp_Object x_property_data_to_lisp (struct frame *, const unsigned char *,