Index: server/os/connection.c =================================================================== --- server/os/connection.c (revision 235) +++ server/os/connection.c (working copy) @@ -877,13 +877,19 @@ } #endif /* SVR4 */ +/* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #1, simple buffer + overflow. Now we limit to _MAX_SALVENM. + */ + +#define _MAX_SLAVENM (256) + static int accept_att_local(void) { int newconn; int read_in; - char length; - char path[64]; + unsigned char length; + char path[_MAX_SLAVENM]; /* * first get device-name @@ -893,6 +899,9 @@ return (-1); } + if (length >= _MAX_SLAVENM) + length = _MAX_SLAVENM - 1; + if ((read_in = read(ptsFd, path, length)) <= 0) { Error("audio server: Can't read slave name from USL client connection"); return (-1); @@ -1447,8 +1456,19 @@ (struct sockaddr *) NULL, (socklen_t *) NULL)) < 0) continue; - if (newconn > lastfdesc) { - ErrorConnMax(newconn); + + + + /* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #8. + shut down the client if the max is exceeded. Note, + if the client does not send any data or disconnect, + ErrorConnMax() has been modified to return if a + timeout occurs. If this happens the client will simply + be disconnected. + */ + + if (newconn >= lastfdesc - 1) { + ErrorConnMax(newconn); close(newconn); continue; } @@ -1526,6 +1546,7 @@ char byteOrder = 0; int whichbyte = 1; struct timeval waittime; + int rv = 0; #ifndef _MINIX long mask[mskcnt]; #endif /* !_MINIX */ @@ -1538,12 +1559,17 @@ CLEARBITS(mask); BITSET(mask, fd); #ifdef hpux - (void) select(fd + 1, (int *) mask, (int *) NULL, (int *) NULL, - &waittime); + rv = select(fd + 1, (int *) mask, (int *) NULL, (int *) NULL, + &waittime); #else - (void) select(fd + 1, (fd_set *) mask, (fd_set *) NULL, - (fd_set *) NULL, &waittime); + rv = select(fd + 1, (fd_set *) mask, (fd_set *) NULL, + (fd_set *) NULL, &waittime); #endif + + /* JET 3/17/2007, if we timed out, simply return */ + if (rv == 0) + return; + /* try to read the byte-order of the connection */ (void) read(fd, &byteOrder, 1); #else Index: server/dia/auutil.c =================================================================== --- server/dia/auutil.c (revision 235) +++ server/dia/auutil.c (working copy) @@ -209,6 +209,20 @@ dataSize = numSamples * sizeofFormat(format) * numTracks; minibufSize = auNativeBytesPerSample * auMinibufSamples * numTracks; + /* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #3, triggers + this. After the overflow the malloc will succeed, since it + becomes a small number when dataSize is very large. dataSize, + however will remain large, and attempts to copy data into the + buffer from the client will eventually core (like in + ProcAuWriteElement) as the buffer is overrun */ + + /* check for a possible integer overflow first, before possibly + allocating a much smaller buffer than is really required. */ + if (dataSize > (PAD4(sizeof(ComponentRec)) + + PAD4(dataSize) + + PAD4(minibufSize) * 2)) + return NULL; + /* the minibuf needs to be twice as large for output range checking */ if (!(port = (ComponentPtr) aualloc(PAD4(sizeof(ComponentRec)) + PAD4(dataSize) + @@ -649,6 +663,14 @@ /* compile the inputs for this output */ inputCnt = 0; + + /* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #6. + Make sure an invalid element number isn't going to be + used for output->firstInput. + */ + if (output->firstInput > flow->numElements) + return AuBadElement; + status = compileInputs(client, flow->elements, output, output->firstInput, AuFixedPointFromSum(1, 0), Index: server/dia/audispatch.c =================================================================== --- server/dia/audispatch.c (revision 235) +++ server/dia/audispatch.c (working copy) @@ -550,25 +550,31 @@ 0, /* AuElementTypeExportMonitor */ }; -#define ADD_VAR(n) \ -{ \ - AuUint8 *_t = (AuUint8 *) el; \ - \ - varLen += (n); \ - _t += (n); \ - el = (auElement *) _t; \ +#define ADD_VAR(n) \ +{ \ + AuUint8 *_t = (AuUint8 *) el; \ + \ + varLen += (n); \ + _t += (n); \ + el = (auElement *) _t; \ } -#define COMP_ACTIONS(num) \ -{ \ - numActions += (num) ? (num) : numDefaultActions[el->type]; \ - ADD_VAR((num) * sizeof(auElementAction)); \ +#define COMP_ACTIONS(num) \ +{ \ + numActions += (num) ? (num) : numDefaultActions[el->type]; \ + ADD_VAR((num) * sizeof(auElementAction)); \ } -#define FREE_FLOW_ERROR(e, v) \ -{ \ - AuFreeFlowElements(flow); \ - AU_ERROR(e, v); \ +/* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #5. Let's not be + stupid and free a flow, then deref data within the freed flow in + AU_ERROR(). +*/ + +#define FREE_FLOW_ERROR(e, v) \ +{ \ + CARD8 val = (v); \ + AuFreeFlowElements(flow); \ + AU_ERROR(e, val); \ } int @@ -591,6 +597,20 @@ /* compute length of variable data and do some error checking */ for (i = varLen = numActions = 0; i < stuff->numElements; i++, el++) + { + + /* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #4, + triggers this. while counting actions, make sure we do not + stray beyond the stuff buffer. If we do, then there wasn't + enough data supplied in the request. + */ + + if (el >= ((auElement *)&stuff[1] + + ((stuff->length << 2) - sizeof(auSetElementsReq))) ) + { + AU_ERROR(AuBadLength, 0); + } + switch (el->type) { case AuElementTypeImportClient: COMP_ACTIONS(el->importclient.actions.num_actions); @@ -628,6 +648,7 @@ default: AU_ERROR(AuBadElement, el->type); } + } /* size of element list */ len = (stuff->length << 2) - sizeof(auSetElementsReq); Index: server/dia/resource.c =================================================================== --- server/dia/resource.c (revision 235) +++ server/dia/resource.c (working copy) @@ -289,10 +289,22 @@ client = CLIENT_ID(id); rrec = &clientTable[client]; + + /* JET 3/17/2007 - Luigi Auriemma's nasbugs, attack #2. can + force nasd to terminate by specifying a non-existant clientid + to this request. Normally all proto requests are made via + libaudio, in which case this situation should never happen. + However, if you talk protocol to the server directly... Well, + we will log the condition when it occurs, but will not + terminate the server. + + It occurs to me that X servers should be vulnerable to this + DOS, since this code is present in X11 too. :) */ + if (!rrec->buckets) { - ErrorF("AddResource(%x, %x, %x), client=%d \n", + ErrorF("AddResource(%x, %x, %x), client=%d (client not in use)\n", id, type, (unsigned long) value, client); - FatalError("client not in use\n"); + return FALSE; } if ((rrec->elements >= 4 * rrec->buckets) && (rrec->hashsize < MAXHASHSIZE))