diff options
author | emaste <emaste@FreeBSD.org> | 2010-01-14 15:27:18 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2010-01-14 15:27:18 +0000 |
commit | 2ade2ff6c8b6dc6f30652fdba72dd2b5e4c908a3 (patch) | |
tree | 13d1e10d304c5076608b5517f036953a6287928c /sbin | |
parent | 922d9eeb784ff7f37e6c8a3cc33930502fd9e2ae (diff) | |
download | FreeBSD-src-2ade2ff6c8b6dc6f30652fdba72dd2b5e4c908a3.zip FreeBSD-src-2ade2ff6c8b6dc6f30652fdba72dd2b5e4c908a3.tar.gz |
Reject invalid CIDR widths rather than silently stopping at the first
non-digit character.
Due to an issue with rc(8) in a test configuration, ifconfig was being
invoked with the address used again as the width - for example,
ifconfig vlan0 10.0.0.1/10.0.0.1
Prior to this change, that address/width would be interpreted as
10.0.0.1/10.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ifconfig/af_inet.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index 2c75b01..2e27114 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -37,6 +37,7 @@ static const char rcsid[] = #include <sys/socket.h> #include <net/if.h> +#include <ctype.h> #include <err.h> #include <stdio.h> #include <stdlib.h> @@ -110,15 +111,18 @@ in_getaddr(const char *s, int which) char *p = NULL; if((p = strrchr(s, '/')) != NULL) { + const char *errstr; /* address is `name/masklen' */ int masklen; - int ret; struct sockaddr_in *min = sintab[MASK]; *p = '\0'; - ret = sscanf(p+1, "%u", &masklen); - if(ret != 1 || (masklen < 0 || masklen > 32)) { + if (!isdigit(*(p + 1))) + errstr = "invalid"; + else + masklen = (int)strtonum(p + 1, 0, 32, &errstr); + if (errstr != NULL) { *p = '/'; - errx(1, "%s: bad value", s); + errx(1, "%s: bad value (width %s)", s, errstr); } min->sin_len = sizeof(*min); min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) & |