Fixes unchecked results from parsecmd
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 6 Mar 2015 15:00:20 +0000 (10:00 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 6 Mar 2015 15:00:20 +0000 (10:00 -0500)
Before accessing the strings of a parsecmd, we must check the nf (num
fields).  Many devices were not checking, so something like
echo "" > /net/ether0/stats
Would trigger a PF.

Using lookupcmd() is safe, since it check the nf internally.  But any
naked access to the fields (like with strcmp) requires a check.

kern/drivers/dev/alarm.c
kern/drivers/dev/ether.c
kern/drivers/dev/nix.c
kern/drivers/dev/vm.c
kern/drivers/net/bnx2x/bnx2x_dev.c
kern/src/net/iproute.c

index d131d8f..096d086 100644 (file)
@@ -363,6 +363,8 @@ static long alarmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                                kfree(cb);
                                nexterror();
                        }
+                       if (cb->nf < 1)
+                               error("short control request");
                        if (!strcmp(cb->f[0], "evq")) {
                                if (cb->nf < 2)
                                        error("evq needs a pointer");
index b774889..99921bb 100644 (file)
@@ -429,6 +429,10 @@ static long etherwrite(struct chan *chan, void *buf, long n, int64_t unused)
                if (l >= 0)
                        goto out;
                cb = parsecmd(buf, n);
+               if (cb->nf < 1) {
+                       kfree(cb);
+                       error("short control request");
+               }
                if (strcmp(cb->f[0], "nonblocking") == 0) {
                        if (cb->nf <= 1)
                                onoff = 1;
index 7ed4386..a50bcef 100644 (file)
@@ -430,6 +430,8 @@ static long nixwrite(struct chan *c, void *ubuf, long n, int64_t off)
                        kfree(cb);
                        nexterror();
                }
+               if (cb->nf < 1)
+                       error("short control request");
                if (!strcmp(cb->f[0], "run")) {
                        int core;
                        uintptr_t ip;
index 9c7abb7..67b3924 100644 (file)
@@ -446,6 +446,8 @@ static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                                kfree(cb);
                                nexterror();
                        }
+                       if (cb->nf < 1)
+                               error("short control request");
                        if (!strcmp(cb->f[0], "run")) {
                                int ret;
                                if (cb->nf != 4)
index 60e276b..a989290 100644 (file)
@@ -107,6 +107,8 @@ static long bnx2x_ctl(struct ether *edev, void *buf, long n)
                kfree(cb);
                nexterror();
        }
+       if (cb->nf < 1)
+               error("short control request");
 
        /* TODO: handle ctl command somehow.  igbe did the following: */
        //ct = lookupcmd(cb, igbectlmsg, ARRAY_SIZE(igbectlmsg));
index 3f0693d..27db012 100644 (file)
@@ -793,6 +793,8 @@ long routewrite(struct Fs *f, struct chan *c, char *p, int n)
                kfree(cb);
                nexterror();
        }
+       if (cb->nf < 1)
+               error("short control request");
 
        if (strcmp(cb->f[0], "flush") == 0) {
                tag = cb->f[1];