From e6e8cc0c83320a14e7a74373e3079b80c368d488 Mon Sep 17 00:00:00 2001 From: Jean-Marc Zucconi Date: Thu, 23 Aug 2001 23:43:09 +0000 Subject: Fix a local DoS against xfs. Submitted by: kris Obtained from: XFree86 CVS repository --- x11/XFree86-4/Makefile | 2 +- x11/XFree86-4/files/patch-xfs | 292 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 x11/XFree86-4/files/patch-xfs (limited to 'x11') diff --git a/x11/XFree86-4/Makefile b/x11/XFree86-4/Makefile index 2dcafe7b144a..d68fbfd83677 100644 --- a/x11/XFree86-4/Makefile +++ b/x11/XFree86-4/Makefile @@ -7,7 +7,7 @@ PORTNAME= XFree86 PORTVERSION= 4.1.0 -PORTREVISION= 5 +PORTREVISION= 6 CATEGORIES= x11 MASTER_SITES= ${MASTER_SITE_XFREE} MASTER_SITE_SUBDIR= 4.1.0 diff --git a/x11/XFree86-4/files/patch-xfs b/x11/XFree86-4/files/patch-xfs new file mode 100644 index 000000000000..8ac159dd7603 --- /dev/null +++ b/x11/XFree86-4/files/patch-xfs @@ -0,0 +1,292 @@ +--- programs/xfs/difs/dispatch.c 2001/04/01 14:00:20 3.9 ++++ programs/xfs/difs/dispatch.c 2001/06/21 01:15:44 +@@ -141,8 +141,10 @@ + op = MAJOROP; + if (op >= NUM_PROC_VECTORS) + result = ProcBadRequest (client); +- else ++ else if (*client->requestVector[op] != NULL) + result = (*client->requestVector[op]) (client); ++ else ++ result = FSBadRequest; + } + if (result != FSSuccess) { + if (client->noClientException != FSSuccess) +@@ -202,8 +204,12 @@ + return (client->noClientException = -2); + if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || + (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) { ++ int status; ++ + client->swapped = TRUE; +- SwapConnClientPrefix(prefix); ++ status = SwapConnClientPrefix(client, prefix); ++ if (status != FSSuccess) ++ return (status); + } + client->major_version = prefix->major_version; + client->minor_version = prefix->minor_version; +@@ -257,7 +263,16 @@ + client_auth[i].name = (char *) ad; + ad += client_auth[i].namelen; + client_auth[i].data = (char *) ad; ++ + ad += client_auth[i].datalen; ++ ++ if (ad - (char *)auth_data > stuff->length - ++ (i < (int)prefix->num_auths) ? 8 : 0) { ++ int lengthword = stuff->length; ++ ++ SendErrToClient(client, FSBadLength, (pointer)&lengthword); ++ return (FSBadLength); ++ } + } + num_alts = ListAlternateServers(&altservers); + for (i = 0, altlen = 0; i < num_alts; i++) { +@@ -585,6 +600,13 @@ + ad += acp[i].namelen; + acp[i].data = (char *) ad; + ad += acp[i].datalen; ++ if (ad - (char *)stuff + SIZEOF(fsCreateACReq) > stuff->length - ++ (i < (int)stuff->num_auths ? 8 : 0)) { ++ int lengthword = stuff->length; ++ ++ SendErrToClient(client, FSBadLength, (pointer)&lengthword); ++ return (FSBadLength); ++ } + } + + /* XXX needs work for AuthContinue */ +@@ -702,6 +724,13 @@ + REQUEST(fsSetResolutionReq); + REQUEST_AT_LEAST_SIZE(fsSetResolutionReq); + ++ if (stuff->length - SIZEOF(fsResolution) != stuff->num_resolutions * ++ sizeof(fsResolution)) { ++ int lengthword = stuff->length; ++ ++ SendErrToClient(client, FSBadAlloc, &lengthword); ++ return FSBadLength; ++ } + new_res = (fsResolution *) + fsalloc(SIZEOF(fsResolution) * stuff->num_resolutions); + if (!new_res) { +@@ -725,6 +754,13 @@ + REQUEST(fsReq); + REQUEST_AT_LEAST_SIZE(fsReq); + ++ if (stuff->length - SIZEOF(fsResolution) != client->num_resolutions * ++ sizeof(fsResolution)) { ++ int lengthword = stuff->length; ++ ++ SendErrToClient(client, FSBadAlloc, &lengthword); ++ return FSBadLength; ++ } + reply.type = FS_Reply; + reply.num_resolutions = client->num_resolutions; + reply.sequenceNumber = client->sequence; +--- programs/xfs/difs/fonts.c 2001/04/01 14:00:20 3.9 ++++ programs/xfs/difs/fonts.c 2001/06/21 01:15:45 +@@ -709,8 +709,12 @@ + } + } + if (validpaths < npaths) { +- fplist = (FontPathElementPtr *) ++ FontPathElementPtr *ftmp = (FontPathElementPtr *) + fsrealloc(fplist, sizeof(FontPathElementPtr) * validpaths); ++ ++ if (!ftmp) ++ goto bail; ++ fplist = ftmp; + npaths = validpaths; + } + if (validpaths == 0) { +--- programs/xfs/difs/main.c 2001/04/01 14:00:20 3.7 ++++ programs/xfs/difs/main.c 2001/06/21 01:15:45 +@@ -171,11 +171,14 @@ + exit(0); + } + +-void ++int + NotImplemented(void) + { + NoopDDA(); /* dummy to get difsutils.o to link */ +- FatalError("Not implemented\n"); ++ /* Getting here can become the next xfs exploit... so don't exit */ ++ ErrorF("Not implemented\n"); ++ ++ return (FSBadImplementation); + } + + static Bool +--- programs/xfs/difs/swapreq.c 2001/01/17 23:45:29 1.5 ++++ programs/xfs/difs/swapreq.c 2001/06/21 01:15:46 +@@ -135,8 +135,8 @@ + return ((*ProcVector[stuff->reqType]) (client)); + } + +-static void +-swap_auth(pointer data, int num) ++static int ++swap_auth(ClientPtr client, pointer data, int num, int length) + { + unsigned char *p; + unsigned char t; +@@ -158,16 +158,29 @@ + p += 2; + p += (namelen + 3) & ~3; + p += (datalen + 3) & ~3; ++ if (p - (unsigned char *)data > length - (i < num ? 8 : 0)) { ++ int lengthword = length; ++ ++ SendErrToClient(client, FSBadLength, (pointer)&lengthword); ++ return (FSBadLength); ++ } + } ++ ++ return (FSSuccess); + } + + int + SProcCreateAC(ClientPtr client) + { ++ int status; ++ + REQUEST(fsCreateACReq); + stuff->length = lswaps(stuff->length); + stuff->acid = lswapl(stuff->acid); +- swap_auth((pointer) &stuff[1], stuff->num_auths); ++ status = swap_auth(client, (pointer) &stuff[1], ++ stuff->num_auths, stuff->length); ++ if (status != FSSuccess) ++ return (status); + return ((*ProcVector[stuff->reqType]) (client)); + } + +@@ -177,6 +190,8 @@ + REQUEST(fsSetResolutionReq); + stuff->length = lswaps(stuff->length); + stuff->num_resolutions = lswaps(stuff->num_resolutions); ++ if ((int)stuff->length - (&stuff[1] - &stuff[0]) < stuff->num_resolutions) ++ return (FSBadLength); + SwapShorts((short *) &stuff[1], stuff->num_resolutions); + + return ((*ProcVector[stuff->reqType]) (client)); +@@ -255,11 +270,14 @@ + return ((*ProcVector[stuff->reqType]) (client)); + } + +-void +-SwapConnClientPrefix(fsConnClientPrefix *pCCP) ++int ++SwapConnClientPrefix(ClientPtr client, fsConnClientPrefix *pCCP) + { ++ REQUEST(fsFakeReq); ++ + pCCP->major_version = lswaps(pCCP->major_version); + pCCP->minor_version = lswaps(pCCP->minor_version); + pCCP->auth_len = lswaps(pCCP->auth_len); +- swap_auth((pointer) &pCCP[1], pCCP->num_auths); ++ return (swap_auth(client, (pointer) &pCCP[1], ++ pCCP->num_auths, stuff->length)); + } +--- programs/xfs/include/difs.h 1999/08/21 13:48:50 1.2 ++++ programs/xfs/include/difs.h 2001/06/21 01:15:46 +@@ -83,6 +83,6 @@ + #endif + + /* difs/main.c */ +-extern void NotImplemented(void); ++extern int NotImplemented(void); + + #endif +--- programs/xfs/include/osstruct.h 2001/01/16 22:52:04 1.1.1.4 ++++ programs/xfs/include/osstruct.h 2001/06/21 01:15:46 +@@ -49,16 +49,16 @@ + #include "os.h" + + typedef struct _alt_server { +- char subset; +- short namelen; +- char *name; ++ char subset; ++ unsigned short namelen; ++ char *name; + } AlternateServerRec; + + typedef struct _auth { +- short namelen; +- short datalen; +- char *name; +- char *data; ++ unsigned short namelen; ++ unsigned short datalen; ++ char *name; ++ char *data; + } AuthRec; + + #endif /* _OSSTRUCT_H_ */ +--- programs/xfs/include/swapreq.h 1998/10/25 07:12:32 1.1 ++++ programs/xfs/include/swapreq.h 2001/06/21 01:15:47 +@@ -48,7 +48,7 @@ + extern int SProcResourceRequest(ClientPtr client); + extern int SProcSetResolution(ClientPtr client); + extern int SProcSimpleRequest(ClientPtr client); +-extern void SwapConnClientPrefix(fsConnClientPrefix *pCCP); ++extern int SwapConnClientPrefix(ClientPtr client, fsConnClientPrefix *pCCP); + extern void SwapLongs(long *list, unsigned long count); + extern void SwapShorts(short *list, unsigned long count); + +cvs server: Diffing xc/programs/xfs/os +--- programs/xfs/os/io.c 2001/01/17 23:45:32 3.12 ++++ programs/xfs/os/io.c 2001/06/21 01:15:47 +@@ -127,14 +127,24 @@ + int + ReadRequest(ClientPtr client) + { +- OsCommPtr oc = (OsCommPtr) client->osPrivate; +- ConnectionInputPtr oci = oc->input; ++ OsCommPtr oc; ++ ConnectionInputPtr oci; + fsReq *request; +- int fd = oc->fd; +- int result, ++ int fd, ++ result, + gotnow, + needed = 0; + ++ if (client == NULL) ++ return -1; ++ oc = (OsCommPtr) client->osPrivate; ++ if (oc == NULL) ++ return -1; ++ oci = oc->input; ++ fd = oc->fd; ++ if (oci == NULL || fd < 0) ++ return -1; ++ + if (AvailableInput) { + if (AvailableInput != oc) { + ConnectionInputPtr aci = AvailableInput->input; +@@ -207,6 +217,8 @@ + oci->bufcnt = gotnow; + } + /* fill 'er up */ ++ if (oc->trans_conn == NULL) ++ return -1; + result = _FontTransRead(oc->trans_conn, oci->buffer + oci->bufcnt, + oci->size - oci->bufcnt); + if (result <= 0) { +@@ -230,7 +242,7 @@ + (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE)) { + char *ibuf; + +- ibuf = (char *) fsrealloc(oci, BUFSIZE); ++ ibuf = (char *) fsrealloc(oci->buffer, BUFSIZE); + if (ibuf) { + oci->size = BUFSIZE; + oci->buffer = ibuf; + + -- cgit v1.2.3