Home page logo
/

fulldisclosure logo Full Disclosure mailing list archives

Re: [Linux kernel ipv6_setsockopt integer overflow]
From: Dan Yefimov <dan () lightwave net ru>
Date: Fri, 4 Feb 2005 00:47:58 +0300 (MSK)

On Thu, 3 Feb 2005, qobaiashi wrote:

There's no integer overflow here since there's the test for optlen < 0 in 
linux/net/socket.c


there exists an integer bug in the ipv6 implementation of the linux kernel.
(at least in 2.4.20 and 2.6.4 )
in /linux/net/ipv6/ipv6_sockglue.c:


int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
               int optlen)
{
        struct ipv6_pinfo *np = inet6_sk(sk);
        int val, valbool;
        int retv = -ENOPROTOOPT;

        if (level == SOL_IP && sk->sk_type != SOCK_RAW)
                return udp_prot.setsockopt(sk, level, optname, optval,optlen);

        if(level!=SOL_IPV6)
                goto out;

        if (optval == NULL)
                val=0;
        else if (get_user(val, (int *) optval))
                return -EFAULT;

        valbool = (val!=0);

        lock_sock(sk);

        switch (optname) {
 [...]

 case IPV6_PKTOPTIONS:
        {
                struct ipv6_txoptions *opt = NULL;
                struct msghdr msg;
                struct flowi fl;
                int junk;

                fl.fl6_flowlabel = 0;
                fl.oif = sk->sk_bound_dev_if;

[1]            if (optlen == 0)
                        goto update;

                /* 1K is probably excessive
                 * 1K is surely not enough, 2K per standard header is 16K.
                 */
                retv = -EINVAL;
[2]             if (optlen > 64*1024) 
                        break;

[3]            opt = sock_kmalloc(sk, sizeof(*opt) + optlen, GFP_KERNEL);
                retv = -ENOBUFS; sizeof(*opt)+0xfffffff8
                if (opt == NULL)
                        break;

[4]            memset(opt, 0, sizeof(*opt));
                opt->tot_len = sizeof(*opt) + optlen;
                retv = -EFAULT;
[5]            if (copy_from_user(opt+1, optval, optlen))
[...]

details:

condition [1] and [2] are easily passed for a value like -100, then at [3] 
sock_kmalloc allocates a too small object of the size (sizeof(*opt) + (-100))
which is then overflowed in [4] and [5] leading to a dos of the kernel...

that's it 
over and out!



-- 

    Sincerely Your, Dan.

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html


  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]
AlienVault