aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-11-29 18:50:21 +0000
committerMark Johnston <markj@FreeBSD.org>2021-12-06 14:04:19 +0000
commit3f1756dabfe263c279c7dc29c54398d95f8b0988 (patch)
tree530293598c813e57d08ca607fbdbbf0ef235c9b4
parentd0bcdb3e10ce9daafb439903fa9a87a17c8b77ac (diff)
downloadsrc-3f1756dabfe263c279c7dc29c54398d95f8b0988.tar.gz
src-3f1756dabfe263c279c7dc29c54398d95f8b0988.zip
dummynet: Avoid an out-of-bounds read in do_config()
do_config() processes a buffer of variable-length dummynet commands. The loop which processes this buffer loads the fixed-length header before checking whether there are any bytes left to read, so it performs a 4-byte read past the end of the buffer before terminating. Restructure the loop to avoid this. Reported by: Jenkins (KASAN job) Reviewed by: kp Sponsored by: The FreeBSD Foundation (cherry picked from commit d5ea04ee7ba6c7cd8e0918a080caf5f2c8fb3955)
-rw-r--r--sys/netpfil/ipfw/ip_dummynet.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/netpfil/ipfw/ip_dummynet.c b/sys/netpfil/ipfw/ip_dummynet.c
index d3242fd85817..cee478a03274 100644
--- a/sys/netpfil/ipfw/ip_dummynet.c
+++ b/sys/netpfil/ipfw/ip_dummynet.c
@@ -2011,7 +2011,9 @@ do_config(void *p, int l)
}
arg = NULL;
dn = NULL;
- for (off = 0; l >= sizeof(o); memcpy(&o, (char *)p + off, sizeof(o))) {
+ off = 0;
+ while (l >= sizeof(o)) {
+ memcpy(&o, (char *)p + off, sizeof(o));
if (o.len < sizeof(o) || l < o.len) {
D("bad len o.len %d len %d", o.len, l);
err = EINVAL;