Interface group names must fit into IFNAMSIZ and be unique. But
authorbluhm <bluhm@openbsd.org>
Wed, 10 Feb 2021 14:41:53 +0000 (14:41 +0000)
committerbluhm <bluhm@openbsd.org>
Wed, 10 Feb 2021 14:41:53 +0000 (14:41 +0000)
the kernel made the unique check before trunkating with strlcpy().
So there could be two interface groups with the same name.  The kif
is created by a name lookup.  The trunkated names are equal, so
there was only one kif owned by both groups.  When the groups got
destroyed, the single kif was removed twice from the RB tree.
Check length of group name before doing the unique check.
The empty group name was allowed and is now invalid.
Reported-by: syzbot+f47e8296ebd559f9bbff@syzkaller.appspotmail.com
OK deraadt@ gnezdo@ anton@ mvs@ claudio@

sys/net/if.c

index 6b22927..e9c2950 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.c,v 1.627 2021/02/08 12:30:10 bluhm Exp $  */
+/*     $OpenBSD: if.c,v 1.628 2021/02/10 14:41:53 bluhm Exp $  */
 /*     $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
 
 /*
@@ -2621,9 +2621,11 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
        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)