/* * netsniff-ng - the packet sniffing beast * Copyright 2009, 2010 Daniel Borkmann. * Subject to the GPL, version 2. */ #include #include #include #include /* for ntohs() */ #include #include "proto.h" #include "protos.h" #include "dissector_eth.h" #include "built_in.h" #include "pkt_buff.h" struct tcphdr { uint16_t source; uint16_t dest; uint32_t seq; uint32_t ack_seq; #if defined(__LITTLE_ENDIAN_BITFIELD) __extension__ uint16_t res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; #elif defined(__BIG_ENDIAN_BITFIELD) __extension__ uint16_t doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; #else # error "Adjust your defines" #endif uint16_t window; uint16_t check; uint16_t urg_ptr; } __packed; static void tcp(struct pkt_buff *pkt) { struct tcphdr *tcp = (struct tcphdr *) pkt_pull(pkt, sizeof(*tcp)); uint16_t src, dest; char *src_name, *dest_name; if (tcp == NULL) return; src = ntohs(tcp->source); dest = ntohs(tcp->dest); src_name = lookup_port_tcp(src); dest_name = lookup_port_tcp(dest); tprintf(" [ TCP "); tprintf("Port (%u", src); if (src_name) tprintf(" (%s%s%s)", colorize_start(bold), src_name, colorize_end()); tprintf(" => %u", dest); if (dest_name) tprintf(" (%s%s%s)", colorize_start(bold), dest_name, colorize_end()); tprintf("), "); tprintf("SN (0x%x), ", ntohl(tcp->seq)); tprintf("AN (0x%x), ", ntohl(tcp->ack_seq)); tprintf("DataOff (%u), ", tcp->doff); tprintf("Res (%u), ", tcp->res1); tprintf("Flags ("); if (tcp->fin) tprintf("FIN "); if (tcp->syn) tprintf("SYN "); if (tcp->rst) tprintf("RST "); if (tcp->psh) tprintf("PSH "); if (tcp->ack) tprintf("ACK "); if (tcp->urg) tprintf("URG "); if (tcp->ece) tprintf("ECE "); if (tcp->cwr) tprintf("CWR "); tprintf("), "); tprintf("Window (%u), ", ntohs(tcp->window)); tprintf("CSum (0x%.4x), ", ntohs(tcp->check)); tprintf("UrgPtr (%u)", ntohs(tcp->urg_ptr)); tprintf(" ]\n"); } static void tcp_less(struct pkt_buff *pkt) { struct tcphdr *tcp = (struct tcphdr *) pkt_pull(pkt, sizeof(*tcp)); uint16_t src, dest; char *src_name, *dest_name; if (tcp == NULL) return; src = ntohs(tcp->source); dest = ntohs(tcp->dest); src_name = lookup_port_tcp(src); dest_name = lookup_port_tcp(dest); tprintf(" TCP %u", src); if(src_name) tprintf("(%s%s%s)", colorize_start(bold), src_name, colorize_end()); tprintf("/%u", dest); if(dest_name) tprintf("(%s%s%s)", colorize_start(bold), dest_name, colorize_end()); tprintf(" F%s",colorize_start(bold)); if (tcp->fin) tprintf(" FIN"); if (tcp->syn) tprintf(" SYN"); if (tcp->rst) tprintf(" RST"); if (tcp->psh) tprintf(" PSH"); if (tcp->ack) tprintf(" ACK"); if (tcp->urg) tprintf(" URG"); if (tcp->ece) tprintf(" ECE"); if (tcp->cwr) tprintf(" CWR"); tprintf("%s Win %u S/A 0x%x/0x%x", colorize_end(), ntohs(tcp->window), ntohl(tcp->seq), ntohl(tcp->ack_seq)); } struct protocol tcp_ops = { .key = 0x06, .print_full = tcp, .print_less = tcp_less, }; ue='8'>8space:mode:
authorWANG Cong <xiyou.wangcong@gmail.com>2017-02-08 10:02:13 -0800
committerDavid S. Miller <davem@davemloft.net>2017-02-08 13:12:22 -0500
commitd7426c69a1942b2b9b709bf66b944ff09f561484 (patch)
treef32d0d878d78b43106a831b4b8f510c8a4b4d673
parent2bd137de531367fb573d90150d1872cb2a2095f7 (diff)
sit: fix a double free on error path
Dmitry reported a double free in sit_init_net(): kernel BUG at mm/percpu.c:689! invalid opcode: 0000 [#1] SMP KASAN Dumping ftrace buffer: (ftrace buffer empty) Modules linked in: CPU: 0 PID: 15692 Comm: syz-executor1 Not tainted 4.10.0-rc6-next-20170206 #1 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 task: ffff8801c9cc27c0 task.stack: ffff88017d1d8000 RIP: 0010:pcpu_free_area+0x68b/0x810 mm/percpu.c:689 RSP: 0018:ffff88017d1df488 EFLAGS: 00010046 RAX: 0000000000010000 RBX: 00000000000007c0 RCX: ffffc90002829000 RDX: 0000000000010000 RSI: ffffffff81940efb RDI: ffff8801db841d94 RBP: ffff88017d1df590 R08: dffffc0000000000 R09: 1ffffffff0bb3bdd R10: dffffc0000000000 R11: 00000000000135dd R12: ffff8801db841d80 R13: 0000000000038e40 R14: 00000000000007c0 R15: 00000000000007c0 FS: 00007f6ea608f700(0000) GS:ffff8801dbe00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000002000aff8 CR3: 00000001c8d44000 CR4: 00000000001426f0 DR0: 0000000020000000 DR1: 0000000020000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600 Call Trace: free_percpu+0x212/0x520 mm/percpu.c:1264 ipip6_dev_free+0x43/0x60 net/ipv6/sit.c:1335 sit_init_net+0x3cb/0xa10 net/ipv6/sit.c:1831 ops_init+0x10a/0x530 net/core/net_namespace.c:115 setup_net+0x2ed/0x690 net/core/net_namespace.c:291 copy_net_ns+0x26c/0x530 net/core/net_namespace.c:396 create_new_namespaces+0x409/0x860 kernel/nsproxy.c:106 unshare_nsproxy_namespaces+0xae/0x1e0 kernel/nsproxy.c:205 SYSC_unshare kernel/fork.c:2281 [inline] SyS_unshare+0x64e/0xfc0 kernel/fork.c:2231 entry_SYSCALL_64_fastpath+0x1f/0xc2 This is because when tunnel->dst_cache init fails, we free dev->tstats once in ipip6_tunnel_init() and twice in sit_init_net(). This looks redundant but its ndo_uinit() does not seem enough to clean up everything here. So avoid this by setting dev->tstats to NULL after the first free, at least for -net. Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/sit.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c