]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
OpenAFS-SA-2013-0001: Buffer overflow in OpenAFS fileserver
authorRuss Allbery <rra@debian.org>
Sun, 24 Feb 2013 23:05:48 +0000 (15:05 -0800)
committerRuss Allbery <rra@debian.org>
Sun, 24 Feb 2013 23:05:48 +0000 (15:05 -0800)
By carefully crafting an ACL entry an attacker may overflow fixed length
buffers within the OpenAFS fileserver, crashing the fileserver, and
potentially permitting the execution of arbitrary code. To perform the
exploit, the attacker must already have permissions to create ACLs on the
fileserver in question.

Once such an ACL is present on a fileserver, client utilities such as 'fs'
which manipulate ACLs, may be crashed when they attempt to read or modify
the ACL.

src/libacl/aclprocs.c
src/libadmin/client/afs_clientAdmin.c
src/venus/fs.c

index f294d0949a6e9a2c056d96f3624d9fe5b100c544..5a1dbdc8c827dcf812a79aba1512473a47377aee 100644 (file)
@@ -23,6 +23,7 @@
 #else
 #include <netinet/in.h>
 #endif
+#include <limits.h>
 #include <string.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
@@ -247,7 +248,7 @@ acl_Internalize(elist, acl)
 
     if (sscanf(elist, "%d\n%d\n", &p, &n) != 2)
        return -1;
-    if (p + n > ACL_MAXENTRIES)
+    if (p < 0 || n < 0 || p > INT_MAX - n || p + n > ACL_MAXENTRIES)
        return (-1);
     acl_NewACL(p + n, acl);
     (*acl)->total = p + n;
@@ -272,7 +273,7 @@ acl_Internalize(elist, acl)
     nextc++;                   /* now at the beginning of the entry list */
     for (i = 0; i < (*acl)->positive; i++) {
        int k;
-       if (sscanf(nextc, "%s\t%d\n", lnames.namelist_val[i], &k) != 2) {
+       if (sscanf(nextc, "%63s\t%d\n", lnames.namelist_val[i], &k) != 2) {
            free(lnames.namelist_val);
            return (-1);
        }
@@ -284,7 +285,7 @@ acl_Internalize(elist, acl)
     for (i = (*acl)->total - 1; i >= (*acl)->total - (*acl)->negative;
         i--, j++) {
        if (sscanf
-           (nextc, "%s\t%d\n", lnames.namelist_val[j],
+           (nextc, "%63s\t%d\n", lnames.namelist_val[j],
             &((*acl)->entries[j].rights)) != 2) {
            free(lnames.namelist_val);
            return (-1);
index a228d0ac448577dfd701f1f94bc43e6e280bcf04..ae7b387ee08fa3adaca3b8b0437294f88747de70 100644 (file)
@@ -1530,7 +1530,7 @@ afsclient_ACLEntryAdd(const char *directory, const char *user,
      */
 
     is_dfs =
-       sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
+       sscanf(old_acl_string, "%d dfs:%d %1024s", &cur_acl.nplus, &cur_acl.dfs,
               cur_acl.cell);
     ptr = strchr(old_acl_string, '\n');
     ptr++;
@@ -1555,7 +1555,7 @@ afsclient_ACLEntryAdd(const char *directory, const char *user,
      */
 
     for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
-       sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
+       sscanf(ptr, "%63s%d\n", cur_user, &cur_user_acl);
        /*
         * Skip the entry for the user we are replacing/adding
         */
index fb4f4f1dbb890f238d5e9cbfb647e4d5c1f10b77..7b4a992a3ad541eed56d561145d5ff6e5e9e4928 100644 (file)
@@ -561,7 +561,7 @@ EmptyAcl(char *astr)
     tp->nplus = tp->nminus = 0;
     tp->pluslist = tp->minuslist = 0;
     tp->dfs = 0;
-    sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell);
+    sscanf(astr, "%d dfs:%d %1024s", &junk, &tp->dfs, tp->cell);
     return tp;
 }
 
@@ -576,7 +576,7 @@ ParseAcl(char *astr)
     ta = (struct Acl *)malloc(sizeof(struct Acl));
     assert(ta);
     ta->dfs = 0;
-    sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
+    sscanf(astr, "%d dfs:%d %1024s", &ta->nplus, &ta->dfs, ta->cell);
     astr = SkipLine(astr);
     sscanf(astr, "%d", &ta->nminus);
     astr = SkipLine(astr);
@@ -587,7 +587,7 @@ ParseAcl(char *astr)
     last = 0;
     first = 0;
     for (i = 0; i < nplus; i++) {
-       sscanf(astr, "%100s %d", tname, &trights);
+       sscanf(astr, "%99s %d", tname, &trights);
        astr = SkipLine(astr);
        tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
        assert(tl);
@@ -605,7 +605,7 @@ ParseAcl(char *astr)
     last = 0;
     first = 0;
     for (i = 0; i < nminus; i++) {
-       sscanf(astr, "%100s %d", tname, &trights);
+       sscanf(astr, "%99s %d", tname, &trights);
        astr = SkipLine(astr);
        tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
        assert(tl);