From d6d6cba90215d323567fef13d6565756c9956f60 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp@keithp.com>
Date: Sun, 11 Dec 2022 10:32:26 -0800
Subject: [PATCH] Update XPutBackEvent() to support clients that put back
 unpadded events

It seems to be common practice of some X11 clients to pass specific event
types into APIs that take XEvent*.  For example, freeglut does:

   XConfigureEvent fakeEvent = {0};
   ...
   XPutBackEvent(fgDisplay.Display, (XEvent*)&fakeEvent);

This can result in reads overflowing the input event when libX11 does:

   XEvent store = *event;

=================================================================
==75304==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x00016ee4a8e8 at pc 0x000101c54d14 bp 0x00016ee4a0d0 sp 0x00016ee49888
READ of size 192 at 0x00016ee4a8e8 thread T0
    #0 0x101c54d10 in __asan_memcpy+0x1a4 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3cd10)
    #1 0x102848a18 in _XPutBackEvent PutBEvent.c:41
    #2 0x1028490a4 in XPutBackEvent PutBEvent.c:84
    #3 0x1013295c8 in fgOpenWindow freeglut_window.c:1178
    #4 0x101321984 in fgCreateWindow freeglut_structure.c:108
    #5 0x10132b138 in glutCreateWindow freeglut_window.c:1551
    #6 0x100fb7d94 in main+0x78 (checkeredTriangles:arm64+0x100003d94)
    #7 0x197de3e4c  (<unknown module>)

Address 0x00016ee4a8e8 is located in stack of thread T0 at offset 840 in frame
    #0 0x1013282f8 in fgOpenWindow freeglut_window.c:1063

  This frame has 8 object(s):
    [32, 40) 'title.addr'
    [64, 176) 'winAttr' (line 1066)
    [208, 240) 'textProperty' (line 1067)
    [272, 352) 'sizeHints' (line 1068)
    [384, 440) 'wmHints' (line 1069)
    [480, 672) 'eventReturnBuffer' (line 1070)
    [736, 740) 'num_FBConfigs' (line 1072)
    [752, 840) 'fakeEvent' (line 1074) <== Memory access at offset 840 overflows this variable

This change allows XPutBackEvent() to support such clients without
risk of memory read overflow.

Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Tested-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
---
 src/PutBEvent.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/PutBEvent.c b/src/PutBEvent.c
index 0f9df342..f7b74b31 100644
--- a/src/PutBEvent.c
+++ b/src/PutBEvent.c
@@ -79,9 +79,22 @@ XPutBackEvent (
     register XEvent *event)
 	{
 	int ret;
+	xEvent wire = {0};
+	XEvent lib = {0};
+	Status (*fp)(Display *, XEvent *, xEvent *);
+	int type = event->type & 0177;
 
 	LockDisplay(dpy);
-	ret = _XPutBackEvent(dpy, event);
+	fp = dpy->wire_vec[type];
+	if (fp == NULL)
+		fp = _XEventToWire;
+	ret = (*fp)(dpy, event, &wire);
+	if (ret)
+	{
+		ret = (*dpy->event_vec[type])(dpy, &lib, &wire);
+		if (ret)
+			ret = _XPutBackEvent(dpy, &lib);
+	}
 	UnlockDisplay(dpy);
 	return ret;
 	}
-- 
GitLab