Fixes unchecked results from parsecmd 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.
diff --git a/kern/drivers/dev/alarm.c b/kern/drivers/dev/alarm.c index d131d8f..096d086 100644 --- a/kern/drivers/dev/alarm.c +++ b/kern/drivers/dev/alarm.c
@@ -363,6 +363,8 @@ 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");
diff --git a/kern/drivers/dev/ether.c b/kern/drivers/dev/ether.c index b774889..99921bb 100644 --- a/kern/drivers/dev/ether.c +++ b/kern/drivers/dev/ether.c
@@ -429,6 +429,10 @@ 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;
diff --git a/kern/drivers/dev/nix.c b/kern/drivers/dev/nix.c index 7ed4386..a50bcef 100644 --- a/kern/drivers/dev/nix.c +++ b/kern/drivers/dev/nix.c
@@ -430,6 +430,8 @@ kfree(cb); nexterror(); } + if (cb->nf < 1) + error("short control request"); if (!strcmp(cb->f[0], "run")) { int core; uintptr_t ip;
diff --git a/kern/drivers/dev/vm.c b/kern/drivers/dev/vm.c index 9c7abb7..67b3924 100644 --- a/kern/drivers/dev/vm.c +++ b/kern/drivers/dev/vm.c
@@ -446,6 +446,8 @@ kfree(cb); nexterror(); } + if (cb->nf < 1) + error("short control request"); if (!strcmp(cb->f[0], "run")) { int ret; if (cb->nf != 4)
diff --git a/kern/drivers/net/bnx2x/bnx2x_dev.c b/kern/drivers/net/bnx2x/bnx2x_dev.c index 60e276b..a989290 100644 --- a/kern/drivers/net/bnx2x/bnx2x_dev.c +++ b/kern/drivers/net/bnx2x/bnx2x_dev.c
@@ -107,6 +107,8 @@ 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));
diff --git a/kern/src/net/iproute.c b/kern/src/net/iproute.c index 3f0693d..27db012 100644 --- a/kern/src/net/iproute.c +++ b/kern/src/net/iproute.c
@@ -793,6 +793,8 @@ kfree(cb); nexterror(); } + if (cb->nf < 1) + error("short control request"); if (strcmp(cb->f[0], "flush") == 0) { tag = cb->f[1];