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];