From 2ade2ff6c8b6dc6f30652fdba72dd2b5e4c908a3 Mon Sep 17 00:00:00 2001 From: emaste Date: Thu, 14 Jan 2010 15:27:18 +0000 Subject: 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. --- sbin/ifconfig/af_inet.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sbin/ifconfig/af_inet.c') 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 #include +#include #include #include #include @@ -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) & -- cgit v1.1