android_kernel_samsung_msm8226/net/core
Christoph Paasch da7f770c1a net: Set sk_prot_creator when cloning sockets to the right proto
sk->sk_prot and sk->sk_prot_creator can differ when the app uses
IPV6_ADDRFORM (transforming an IPv6-socket to an IPv4-one).
Which is why sk_prot_creator is there to make sure that sk_prot_free()
does the kmem_cache_free() on the right kmem_cache slab.

Now, if such a socket gets transformed back to a listening socket (using
connect() with AF_UNSPEC) we will allocate an IPv4 tcp_sock through
sk_clone_lock() when a new connection comes in. But sk_prot_creator will
still point to the IPv6 kmem_cache (as everything got copied in
sk_clone_lock()). When freeing, we will thus put this
memory back into the IPv6 kmem_cache although it was allocated in the
IPv4 cache. I have seen memory corruption happening because of this.

With slub-debugging and MEMCG_KMEM enabled this gives the warning
	"cache_from_obj: Wrong slab cache. TCPv6 but object is from TCP"

A C-program to trigger this:

void main(void)
{
        int fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
        int new_fd, newest_fd, client_fd;
        struct sockaddr_in6 bind_addr;
        struct sockaddr_in bind_addr4, client_addr1, client_addr2;
        struct sockaddr unsp;
        int val;

        memset(&bind_addr, 0, sizeof(bind_addr));
        bind_addr.sin6_family = AF_INET6;
        bind_addr.sin6_port = ntohs(42424);

        memset(&client_addr1, 0, sizeof(client_addr1));
        client_addr1.sin_family = AF_INET;
        client_addr1.sin_port = ntohs(42424);
        client_addr1.sin_addr.s_addr = inet_addr("127.0.0.1");

        memset(&client_addr2, 0, sizeof(client_addr2));
        client_addr2.sin_family = AF_INET;
        client_addr2.sin_port = ntohs(42421);
        client_addr2.sin_addr.s_addr = inet_addr("127.0.0.1");

        memset(&unsp, 0, sizeof(unsp));
        unsp.sa_family = AF_UNSPEC;

        bind(fd, (struct sockaddr *)&bind_addr, sizeof(bind_addr));

        listen(fd, 5);

        client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        connect(client_fd, (struct sockaddr *)&client_addr1, sizeof(client_addr1));
        new_fd = accept(fd, NULL, NULL);
        close(fd);

        val = AF_INET;
        setsockopt(new_fd, SOL_IPV6, IPV6_ADDRFORM, &val, sizeof(val));

        connect(new_fd, &unsp, sizeof(unsp));

        memset(&bind_addr4, 0, sizeof(bind_addr4));
        bind_addr4.sin_family = AF_INET;
        bind_addr4.sin_port = ntohs(42421);
        bind(new_fd, (struct sockaddr *)&bind_addr4, sizeof(bind_addr4));

        listen(new_fd, 5);

        client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        connect(client_fd, (struct sockaddr *)&client_addr2, sizeof(client_addr2));

        newest_fd = accept(new_fd, NULL, NULL);
        close(new_fd);

        close(client_fd);
        close(new_fd);
}

As far as I can see, this bug has been there since the beginning of the
git-days.

Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE-2018-9568
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>

Change-Id: I4bbf2e4d714f4fc435a152ecc399488248321940
2020-01-06 08:40:36 +01:00
..
datagram.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
dev.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
dev_addr_lists.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
drop_monitor.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
dst.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
ethtool.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
fib_rules.c net: core: add UID to flows, rules, and routes 2019-08-08 15:08:49 +02:00
filter.c sk_run_filter: add BPF_S_ANC_SECCOMP_LD_W 2019-08-05 14:21:58 +02:00
flow.c
flow_dissector.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
gen_estimator.c
gen_stats.c
iovec.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
kmap_skb.h
link_watch.c
Makefile net: sockev: Initial Commit 2014-07-22 14:33:44 -06:00
neighbour.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
net-sysfs.c
net-sysfs.h
net-traces.c
net_namespace.c userns: make each net (net_ns) belong to a user_ns 2019-08-08 15:08:49 +02:00
netevent.c
netpoll.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
netprio_cgroup.c
pktgen.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
request_sock.c
rtnetlink.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
scm.c misc: Import SM-G900H kernel source code 2019-08-02 15:14:10 +02:00
secure_seq.c netfilter: ipv6: add IPv6 NAT support 2020-01-06 08:40:33 +01:00
skbuff.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
sock.c net: Set sk_prot_creator when cloning sockets to the right proto 2020-01-06 08:40:36 +01:00
sock_diag.c net: diag: Add the ability to destroy a socket. 2019-08-05 09:12:31 +02:00
sockev_nlmcast.c net: sockev: Initial Commit 2014-07-22 14:33:44 -06:00
stream.c
sysctl_net_core.c Merge tag 'v3.4.113' into lineage-16.0 2019-08-05 14:20:47 +02:00
timestamping.c
user_dma.c
utils.c net: core: add function for incremental IPv6 pseudo header checksum updates 2020-01-06 08:40:33 +01:00