From 3dc7da68a2731f661d7251a5fc759daffe24ca70 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 19 Feb 2025 14:14:27 +1100 Subject: conf: More thorough error checking when parsing --mtu option We're a bit sloppy with parsing MTU which can lead to some surprising, though fairly harmless, results: * Passing a non-number like '-m xyz' will not give an error and act like -m 0 * Junk after a number (e.g. '-m 1500pqr') will be ignored rather than giving an error * We parse the MTU as a long, then immediately assign to an int, so on some platforms certain ludicrously out of bounds values will be silently truncated, rather than giving an error Be a bit more thorough with the error checking to avoid that. Signed-off-by: David Gibson Signed-off-by: Stefano Brivio --- conf.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/conf.c b/conf.c index 18017f5..335f37c 100644 --- a/conf.c +++ b/conf.c @@ -1652,20 +1652,29 @@ void conf(struct ctx *c, int argc, char **argv) die("Invalid PID file: %s", optarg); break; - case 'm': + case 'm': { + unsigned long mtu; + char *e; + errno = 0; - c->mtu = strtol(optarg, NULL, 0); + mtu = strtoul(optarg, &e, 0); + + if (errno || *e) + die("Invalid MTU: %s", optarg); - if (!c->mtu) { + if (!mtu) { c->mtu = -1; break; } - if (c->mtu < ETH_MIN_MTU || c->mtu > (int)ETH_MAX_MTU || - errno) - die("Invalid MTU: %s", optarg); + if (mtu < ETH_MIN_MTU || mtu > ETH_MAX_MTU) { + die("MTU %lu out of range (%u..%u)", mtu, + ETH_MIN_MTU, ETH_MAX_MTU); + } + c->mtu = mtu; break; + } case 'a': if (inet_pton(AF_INET6, optarg, &c->ip6.addr) && !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) && -- cgit v1.2.3