Hi,
Although ifconfig(8) checks it already, contiguous inet netmask
should be enforced by the kernel. Currently the routing table does
not support non-contiguous netmask, but we should error out early
during interface ioctl(2).
ok?
bluhm
Index: netinet/in.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in.c,v
retrieving revision 1.166
diff -u -p -r1.166 in.c
--- netinet/in.c 8 Nov 2019 07:16:29 -0000 1.166
+++ netinet/in.c 18 Nov 2019 22:50:38 -0000
@@ -330,8 +330,16 @@ in_ioctl(u_long cmd, caddr_t data, struc
error = EINVAL;
break;
}
+ /* do not check inet family or strict len */
+ sin = satosin(&ifr->ifr_addr);
+ if (ntohl(sin->sin_addr.s_addr) &
+ (~ntohl(sin->sin_addr.s_addr) >> 1)) {
+ /* non-contiguous netmask */
+ error = EINVAL;
+ break;
+ }
ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
- satosin(&ifr->ifr_addr)->sin_addr.s_addr;
+ sin->sin_addr.s_addr;
break;
}
err:
@@ -404,6 +412,7 @@ in_ioctl_change_ifaddr(u_long cmd, caddr
struct in_ifaddr *ia = NULL;
struct in_aliasreq *ifra = (struct in_aliasreq *)data;
struct sockaddr_in *sin = NULL, *dstsin = NULL, *broadsin = NULL;
+ struct sockaddr_in *masksin = NULL;
int error = 0;
int newifaddr;
@@ -440,6 +449,14 @@ in_ioctl_change_ifaddr(u_long cmd, caddr
error = EINVAL;
break;
}
+ /* do not check inet family or strict len */
+ masksin = &ifra->ifra_mask;
+ if (ntohl(masksin->sin_addr.s_addr) &
+ (~ntohl(masksin->sin_addr.s_addr) >> 1)) {
+ /* non-contiguous netmask */
+ error = EINVAL;
+ break;
+ }
}
if ((ifp->if_flags & IFF_POINTOPOINT) &&
ifra->ifra_dstaddr.sin_family == AF_INET) {
@@ -480,10 +497,10 @@ in_ioctl_change_ifaddr(u_long cmd, caddr
sin->sin_addr.s_addr != ia->ia_addr.sin_addr.s_addr) {
needinit = 1;
}
- if (ifra->ifra_mask.sin_len) {
+ if (masksin != NULL) {
in_ifscrub(ifp, ia);
ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
- ifra->ifra_mask.sin_addr.s_addr;
+ masksin->sin_addr.s_addr;
needinit = 1;
}
if (dstsin != NULL) {