diff options
| author | Kalle Olavi Niemitalo | 2020-08-18 17:03:07 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2020-08-18 17:05:08 +0200 |
| commit | 4670969e6791c76460c647b5f86317ddb75898bc (patch) | |
| tree | 1a7d39efb5edef837d04a692fd9f543aef12f43a /src | |
| parent | 06738a40d10706e36ca0dc767ed3a0ef6fe17078 (diff) | |
| download | emacs-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.c | 3 | ||||
| -rw-r--r-- | src/xselect.c | 15 | ||||
| -rw-r--r-- | src/xterm.h | 1 |
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 | ||
| 2286 | void | 2287 | void |
| 2287 | x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | 2288 | x_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); | |||
| 1207 | extern void x_fill_property_data (Display *, | 1207 | extern void x_fill_property_data (Display *, |
| 1208 | Lisp_Object, | 1208 | Lisp_Object, |
| 1209 | void *, | 1209 | void *, |
| 1210 | int, | ||
| 1210 | int); | 1211 | int); |
| 1211 | extern Lisp_Object x_property_data_to_lisp (struct frame *, | 1212 | extern Lisp_Object x_property_data_to_lisp (struct frame *, |
| 1212 | const unsigned char *, | 1213 | const unsigned char *, |