Alexander Bluhm <alexander.bl...@gmx.net> writes: > Hi, > > Next try to fix syzkaller crash > https://syzkaller.appspot.com/bug?id=54e16dc5bce6929e14b42e2f1379f1c18f62be43 > > Interface group names must fit into IFNAMSIZ and be unique. But > the kernel makes the unique check before trunkating with strlcpy(). > So there can be two interfaces groups with the same name. The kif > is created by a name lookup. The trunkated names are equal so there > is only one kif owned by both groups. When both groups are destroyed, > the single kif is removed twice from the RB tree. > > - Check length of group name before doing the unique check. > - The empty group name was allowed. That does not make much sense. > Does anyone use the empty interface group? > - Use the same check in kernel and ifconfig userland. > - ifconfig -group does not need name sanitation. The kernel will > just report that it does not exist. > > ok?
OK gnezdo@ > > bluhm > > Index: sys/net/if.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v > retrieving revision 1.627 > diff -u -p -r1.627 if.c > --- sys/net/if.c 8 Feb 2021 12:30:10 -0000 1.627 > +++ sys/net/if.c 9 Feb 2021 20:47:34 -0000 > @@ -2621,9 +2621,11 @@ if_addgroup(struct ifnet *ifp, const cha > struct ifg_list *ifgl; > struct ifg_group *ifg = NULL; > struct ifg_member *ifgm; > + size_t namelen; > > - if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' && > - groupname[strlen(groupname) - 1] <= '9') > + namelen = strlen(groupname); > + if (namelen == 0 || namelen >= IFNAMSIZ || > + (groupname[namelen - 1] >= '0' && groupname[namelen - 1] <= '9')) > return (EINVAL); > > TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) > Index: sbin/ifconfig/ifconfig.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sbin/ifconfig/ifconfig.c,v > retrieving revision 1.432 > diff -u -p -r1.432 ifconfig.c > --- sbin/ifconfig/ifconfig.c 16 Jan 2021 17:44:29 -0000 1.432 > +++ sbin/ifconfig/ifconfig.c 9 Feb 2021 21:02:50 -0000 > @@ -1634,16 +1634,20 @@ void > setifgroup(const char *group_name, int dummy) > { > struct ifgroupreq ifgr; > + size_t namelen; > > memset(&ifgr, 0, sizeof(ifgr)); > strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ); > > - if (group_name[0] && > - isdigit((unsigned char)group_name[strlen(group_name) - 1])) > + namelen = strlen(group_name); > + if (namelen == 0) > + errx(1, "setifgroup: group name empty"); > + if (namelen >= IFNAMSIZ) > + errx(1, "setifgroup: group name too long"); > + if (isdigit((unsigned char)group_name[namelen - 1])) > errx(1, "setifgroup: group names may not end in a digit"); > > - if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) > - errx(1, "setifgroup: group name too long"); > + strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ); > if (ioctl(sock, SIOCAIFGROUP, (caddr_t)&ifgr) == -1) { > if (errno != EEXIST) > err(1," SIOCAIFGROUP"); > @@ -1658,10 +1662,6 @@ unsetifgroup(const char *group_name, int > > memset(&ifgr, 0, sizeof(ifgr)); > strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ); > - > - if (group_name[0] && > - isdigit((unsigned char)group_name[strlen(group_name) - 1])) > - errx(1, "unsetifgroup: group names may not end in a digit"); > > if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) > errx(1, "unsetifgroup: group name too long");