xorl %eax, %eax

FreeBSD-SA-09:10: IPv6 IOCTL Missing Check

leave a comment »

This is a design flaw in the ioctl(2) handler of IPv6 protocol implementation of FreeBSD discovered by Hiroki Sato. The bug affects all the supported versions of FreeBSD. Here is the buggy code from FreeBSD 7.2-RELEASE:

int
in6_control(struct socket *so, u_long cmd, caddr_t data,
    struct ifnet *ifp, struct thread *td)
{
        struct  in6_ifreq *ifr = (struct in6_ifreq *)data;
        struct  in6_ifaddr *ia = NULL;
        struct  in6_aliasreq *ifra = (struct in6_aliasreq *)data;
        struct sockaddr_in6 *sa6;
        int error;

        switch (cmd) {
      ...
       }

        if (ifp == NULL)
                return (EOPNOTSUPP);

        switch (cmd) {
        case SIOCSNDFLUSH_IN6:
        case SIOCSPFXFLUSH_IN6:
        case SIOCSRTRFLUSH_IN6:
        case SIOCSDEFIFACE_IN6:
        case SIOCSIFINFO_FLAGS:
                if (td != NULL) {
                        error = priv_check(td, PRIV_NETINET_ND6);
                        if (error)
                                return (error);
                }
                /* FALLTHROUGH */
        case OSIOCGIFINFO_IN6:
        case SIOCGIFINFO_IN6:
        case SIOCSIFINFO_IN6:
        case SIOCGDRLST_IN6:
        case SIOCGPRLST_IN6:
        case SIOCGNBRINFO_IN6:
        case SIOCGDEFIFACE_IN6:
                return (nd6_ioctl(cmd, data, ifp));
        }
       ...
}

This code is part of sys/netinet6/in6.c file which is part of the IPv6 protocol. Hiroki Sato noticed that SIOCSIFINFO_IN6 IOCTL command had no special privilege check and thus any user was able to request and set it like the rest of the fall-through commands. However, this IOCTL is used to change host variables and because of this any user is able to manipulate them. This was patched like this:

+	case SIOCSIFINFO_FLAGS:
++	case SIOCSIFINFO_IN6:
+		if (!privileged)
+			return (EPERM);
+		/* FALLTHROUGH */
+	case OSIOCGIFINFO_IN6:
+	case SIOCGIFINFO_IN6:
--	case SIOCSIFINFO_IN6:
+ 	case SIOCGDRLST_IN6:

They excluded SIOCSIFINFO_IN6 from the fall-through commands and they added a privilege check. This is probably one of the most straightforward kernel vulnerabilities considering its “exploitation”.

Written by xorl

June 10, 2009 at 20:15

Posted in bugs, freebsd

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s