Sophie

Sophie

distrib > Mandriva > 2007.1 > x86_64 > by-pkgid > 85b3ad2b33921122d97416d29df69bca > files > 1

nas-1.8a-3mdv2007.1.src.rpm

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))