[PATCH] libX11: check size of GetReqExtra after XFlush
Kees Cook
kees.cook at canonical.com
Sat Jul 9 12:42:57 PDT 2011
Two users of GetReqExtra pass arbitrarily sized allocations from the
caller (ModMap and Host). Adjust the GetReqExtra macro to double-check
the requested length and invalidate "req" when this happens. Users of
potentially >16K lengths in GetReqExtra now check "req" and fail if
something has gone wrong.
https://bugs.launchpad.net/ubuntu/+source/x11-xserver-utils/+bug/792628
Signed-off-by: Kees Cook <kees.cook at canonical.com>
---
include/X11/Xlibint.h | 28 ++++++++++++++++++----------
src/Host.c | 8 ++++++++
src/ModMap.c | 4 ++++
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h
index 2ce356d..81f8cfd 100644
--- a/include/X11/Xlibint.h
+++ b/include/X11/Xlibint.h
@@ -461,21 +461,29 @@ extern LockInfoPtr _Xglobal_lock;
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(x##name##Req) + n) > dpy->bufmax)\
_XFlush(dpy);\
- req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->reqType = X_##name;\
- req->length = (SIZEOF(x##name##Req) + n)>>2;\
- dpy->bufptr += SIZEOF(x##name##Req) + n;\
- dpy->request++
+ if ((dpy->bufptr + SIZEOF(x##name##Req) + n) <= dpy->bufmax) {\
+ req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_##name;\
+ req->length = (SIZEOF(x##name##Req) + n)>>2;\
+ dpy->bufptr += SIZEOF(x##name##Req) + n;\
+ dpy->request++;\
+ } else {\
+ req = NULL;\
+ }
#else
#define GetReqExtra(name, n, req) \
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) > dpy->bufmax)\
_XFlush(dpy);\
- req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
- req->reqType = X_/**/name;\
- req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\
- dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\
- dpy->request++
+ if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) <= dpy->bufmax) {\
+ req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_/**/name;\
+ req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\
+ dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\
+ dpy->request++;\
+ } else {\
+ req = NULL;\
+ }
#endif
diff --git a/src/Host.c b/src/Host.c
index da9923a..3f87731 100644
--- a/src/Host.c
+++ b/src/Host.c
@@ -83,6 +83,10 @@ XAddHost (
LockDisplay(dpy);
GetReqExtra (ChangeHosts, length, req);
+ if (!req) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
req->mode = HostInsert;
req->hostFamily = host->family;
req->hostLength = addrlen;
@@ -118,6 +122,10 @@ XRemoveHost (
LockDisplay(dpy);
GetReqExtra (ChangeHosts, length, req);
+ if (!req) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
req->mode = HostDelete;
req->hostFamily = host->family;
req->hostLength = addrlen;
diff --git a/src/ModMap.c b/src/ModMap.c
index c99bfdd..5deb894 100644
--- a/src/ModMap.c
+++ b/src/ModMap.c
@@ -75,6 +75,10 @@ XSetModifierMapping(
LockDisplay(dpy);
GetReqExtra(SetModifierMapping, mapSize, req);
+ if (!req) {
+ UnlockDisplay(dpy);
+ return 2;
+ }
req->numKeyPerModifier = modifier_map->max_keypermod;
--
1.7.4.1
--
Kees Cook
Ubuntu Security Team
More information about the xorg-devel
mailing list