oss-sec mailing list archives

CVE request - Linux kernel through 4.6.2 allows escalade privileges via IP6T_SO_SET_REPLACE compat setsockopt call


From: 张谦 <zhangqian-c () 360 cn>
Date: Thu, 29 Sep 2016 07:43:35 +0000

Hi there,
I found a memory corruption vulnerabiliry in Linux kernel through 4.6.2, and I have a working exploit to escalade 
privileges which requires the ip6_tables module to be loaded, that it is properly blocked on all up-to-date versions.
Due to the number of users running vulnerable code(not update to 4.7 or higher), and that this exploit is only 
available to security researchers and kernel packagers upon request but that I don't want it to spread.

I have reported this issue to Linux kernel official and they have already fixed this.
And I would like to request CVE-ID for this issue.

DESCRIPTION
===========
The IPv6 netfilter subsystem in the Linux kernel through 4.6.2 does not validate certain offset fields,
which allows local users to escalade privileges via an IP6T_SO_SET_REPLACE compat setsockopt call

PRODUCTS AFFECTED
==================
Linux Kernel through 4.6.2
Ubuntu 14.04
Ubuntu 16.04

VULNERABILITY DETAILS
====================
In net/ipv6/netfilter/ip6_tables.c:1490
check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, . . .)
{
xt_ematch_foreach(ematch, e) {
                   ret = compat_find_calc_match(ematch, &e->ipv6, &off);
                   if (ret != 0)
                            goto release_matches;
                  ++j;
}

t = compat_ip6t_get_target(e);
target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name, t->u.user.revision);

t->u.kernel.target = target;
}

struct xt_entry_target *
compat_ip6t_get_target(struct compat_ip6t_entry *e)
{
         return (void *)e + e->target_offset;
}

/* can only be xt_entry_match, so no use of typeof here */
#define xt_ematch_foreach(pos, entry) \
         for ((pos) = (struct xt_entry_match *)entry->elems; \
            (pos) < (struct xt_entry_match *)((char *)(entry) + \
                 (entry)->target_offset); \
            (pos) = (struct xt_entry_match *)((char *)(pos) + \
            (pos)->u.match_size))

The entry->target_offset field didn’t verification well, so that it can cause a memory corruption via 
t->u.kernel.target = target

CREDIT
======
This issue was discovered by Qian Zhang@MarvelTeam Qihoo 360

PATCH
===========
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ce683e5f9d045e5d67d1312a42b359cb2ab2a13c

regards,
Qian Zhang@MarvelTeam Qihoo 360

Current thread: