emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 4670969: Fix buffer overflow in x-send-client-message


From: Lars Ingebrigtsen
Subject: master 4670969: Fix buffer overflow in x-send-client-message
Date: Tue, 18 Aug 2020 11:05:14 -0400 (EDT)

branch: master
commit 4670969e6791c76460c647b5f86317ddb75898bc
Author: Kalle Olavi Niemitalo <kon@iki.fi>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    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
---
 src/xfns.c    |  3 ++-
 src/xselect.c | 15 +++++++++++----
 src/xterm.h   |  1 +
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index d56fc0a..78f977b 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 bf50c59..383aebf 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 bc10043..db8d584 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 *,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]