aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKalle Olavi Niemitalo2020-08-18 17:03:07 +0200
committerLars Ingebrigtsen2020-08-18 17:05:08 +0200
commit4670969e6791c76460c647b5f86317ddb75898bc (patch)
tree1a7d39efb5edef837d04a692fd9f543aef12f43a /src
parent06738a40d10706e36ca0dc767ed3a0ef6fe17078 (diff)
downloademacs-4670969e6791c76460c647b5f86317ddb75898bc.tar.gz
emacs-4670969e6791c76460c647b5f86317ddb75898bc.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/xfns.c3
-rw-r--r--src/xselect.c15
-rw-r--r--src/xterm.h1
3 files changed, 14 insertions, 5 deletions
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
5890 elsize = element_format == 32 ? sizeof (long) : element_format >> 3; 5890 elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
5891 data = xnmalloc (nelements, elsize); 5891 data = xnmalloc (nelements, elsize);
5892 5892
5893 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); 5893 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, nelements,
5894 element_format);
5894 } 5895 }
5895 else 5896 else
5896 { 5897 {
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)
2276 2276
2277 DPY is the display use to look up X atoms. 2277 DPY is the display use to look up X atoms.
2278 DATA is a Lisp list of values to be converted. 2278 DATA is a Lisp list of values to be converted.
2279 RET is the C array that contains the converted values. It is assumed 2279 RET is the C array that contains the converted values.
2280 it is big enough to hold all values. 2280 NELEMENTS_MAX is the number of values that will fit in RET.
2281 Any excess values in DATA are ignored.
2281 FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to 2282 FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to
2282 be stored in RET. Note that long is used for 32 even if long is more 2283 be stored in RET. Note that long is used for 32 even if long is more
2283 than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and 2284 than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and
2284 XClientMessageEvent). */ 2285 XClientMessageEvent). */
2285 2286
2286void 2287void
2287x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) 2288x_fill_property_data (Display *dpy, Lisp_Object data, void *ret,
2289 int nelements_max, int format)
2288{ 2290{
2289 unsigned long val; 2291 unsigned long val;
2290 unsigned long *d32 = (unsigned long *) ret; 2292 unsigned long *d32 = (unsigned long *) ret;
2291 unsigned short *d16 = (unsigned short *) ret; 2293 unsigned short *d16 = (unsigned short *) ret;
2292 unsigned char *d08 = (unsigned char *) ret; 2294 unsigned char *d08 = (unsigned char *) ret;
2295 int nelements;
2293 Lisp_Object iter; 2296 Lisp_Object iter;
2294 2297
2295 for (iter = data; CONSP (iter); iter = XCDR (iter)) 2298 for (iter = data, nelements = 0;
2299 CONSP (iter) && nelements < nelements_max;
2300 iter = XCDR (iter), nelements++)
2296 { 2301 {
2297 Lisp_Object o = XCAR (iter); 2302 Lisp_Object o = XCAR (iter);
2298 2303
@@ -2593,7 +2598,9 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
2593 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; 2598 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
2594 2599
2595 memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l)); 2600 memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
2601 /* event.xclient.data can hold 20 chars, 10 shorts, or 5 longs. */
2596 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, 2602 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
2603 5 * 32 / event.xclient.format,
2597 event.xclient.format); 2604 event.xclient.format);
2598 2605
2599 /* If event mask is 0 the event is sent to the client that created 2606 /* 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);
1207extern void x_fill_property_data (Display *, 1207extern void x_fill_property_data (Display *,
1208 Lisp_Object, 1208 Lisp_Object,
1209 void *, 1209 void *,
1210 int,
1210 int); 1211 int);
1211extern Lisp_Object x_property_data_to_lisp (struct frame *, 1212extern Lisp_Object x_property_data_to_lisp (struct frame *,
1212 const unsigned char *, 1213 const unsigned char *,