[PATCH 1/2] libX11: check size of GetReqExtra after XFlush
Kees Cook
kees at outflux.net
Mon Jun 24 11:24:46 PDT 2013
Any comment on these patches? Can someone commit them if they're okay?
Thanks,
-Kees
On Sun, Jun 09, 2013 at 11:13:42AM -0700, Kees Cook wrote:
> Two users of GetReqExtra pass arbitrarily sized allocations from the
> caller (ModMap and Host). Adjust _XGetRequest() (called by the GetReqExtra
> macro) to double-check the requested length and invalidate "req" when
> this happens. Users of GetReqExtra passing lengths greater than the Xlib
> buffer size (normally 16K) must check "req" and fail gracefully instead
> of crashing.
>
> Any callers of GetReqExtra that do not check "req" for NULL
> will experience this change, in the pathological case, as a NULL
> dereference instead of a buffer overflow. This is an improvement, but
> the documentation for GetReqExtra has been updated to reflect the need
> to check the value of "req" after the call.
>
> Bug that manifested the problem:
> https://bugs.launchpad.net/ubuntu/+source/x11-xserver-utils/+bug/792628
>
> Signed-off-by: Kees Cook <kees at outflux.net>
> ---
> specs/libX11/AppC.xml | 4 +++-
> src/XlibInt.c | 8 ++++++++
> 2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/specs/libX11/AppC.xml b/specs/libX11/AppC.xml
> index df25027..0b37048 100644
> --- a/specs/libX11/AppC.xml
> +++ b/specs/libX11/AppC.xml
> @@ -2468,7 +2468,9 @@ which is the same as
> <function>GetReq</function>
> except that it takes an additional argument (the number of
> extra bytes to allocate in the output buffer after the request structure).
> -This number should always be a multiple of four.
> +This number should always be a multiple of four. Note that it is possible
> +for req to be set to NULL as a defensive measure if the requested length
> +exceeds the Xlib's buffer size (normally 16K).
> </para>
> </sect2>
> <sect2 id="Variable_Length_Arguments">
> diff --git a/src/XlibInt.c b/src/XlibInt.c
> index b06e57b..c3273a8 100644
> --- a/src/XlibInt.c
> +++ b/src/XlibInt.c
> @@ -1733,6 +1733,14 @@ void *_XGetRequest(Display *dpy, CARD8 type, size_t len)
>
> if (dpy->bufptr + len > dpy->bufmax)
> _XFlush(dpy);
> + /* Request still too large, so do not allow it to overflow. */
> + if (dpy->bufptr + len > dpy->bufmax) {
> + fprintf(stderr,
> + "Xlib: request %d length %zd would exceed buffer size.\n",
> + type, len);
> + /* Changes failure condition from overflow to NULL dereference. */
> + return NULL;
> + }
>
> if (len % 4)
> fprintf(stderr,
> --
> 1.8.1.2
--
Kees Cook @outflux.net
More information about the xorg-devel
mailing list