remarkable-linux/net/netfilter
Patrick McHardy b0cdb1d9a9 netfilter: nf_nat: fix oops when unloading protocol modules
When unloading a protocol module nf_ct_iterate_cleanup() is used to
remove all conntracks using the protocol from the bysource hash and
clean their NAT sections. Since the conntrack isn't actually killed,
the NAT callback is invoked twice, once for each direction, which
causes an oops when trying to delete it from the bysource hash for
the second time.

The same oops can also happen when removing both an L3 and L4 protocol
since the cleanup function doesn't check whether the conntrack has
already been cleaned up.

Pid: 4052, comm: modprobe Not tainted 3.6.0-rc3-test-nat-unload-fix+ #32 Red Hat KVM
RIP: 0010:[<ffffffffa002c303>]  [<ffffffffa002c303>] nf_nat_proto_clean+0x73/0xd0 [nf_nat]
RSP: 0018:ffff88007808fe18  EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff8800728550c0 RCX: ffff8800756288b0
RDX: dead000000200200 RSI: ffff88007808fe88 RDI: ffffffffa002f208
RBP: ffff88007808fe28 R08: ffff88007808e000 R09: 0000000000000000
R10: dead000000200200 R11: dead000000100100 R12: ffffffff81c6dc00
R13: ffff8800787582b8 R14: ffff880078758278 R15: ffff88007808fe88
FS:  00007f515985d700(0000) GS:ffff88007cd00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007f515986a000 CR3: 000000007867a000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process modprobe (pid: 4052, threadinfo ffff88007808e000, task ffff8800756288b0)
Stack:
 ffff88007808fe68 ffffffffa002c290 ffff88007808fe78 ffffffff815614e3
 ffffffff00000000 00000aeb00000246 ffff88007808fe68 ffffffff81c6dc00
 ffff88007808fe88 ffffffffa00358a0 0000000000000000 000000000040f5b0
Call Trace:
 [<ffffffffa002c290>] ? nf_nat_net_exit+0x50/0x50 [nf_nat]
 [<ffffffff815614e3>] nf_ct_iterate_cleanup+0xc3/0x170
 [<ffffffffa002c55a>] nf_nat_l3proto_unregister+0x8a/0x100 [nf_nat]
 [<ffffffff812a0303>] ? compat_prepare_timeout+0x13/0xb0
 [<ffffffffa0035848>] nf_nat_l3proto_ipv4_exit+0x10/0x23 [nf_nat_ipv4]
 ...

To fix this,

- check whether the conntrack has already been cleaned up in
  nf_nat_proto_clean

- change nf_ct_iterate_cleanup() to only invoke the callback function
  once for each conntrack (IP_CT_DIR_ORIGINAL).

The second change doesn't affect other callers since when conntracks are
actually killed, both directions are removed from the hash immediately
and the callback is already only invoked once. If it is not killed, the
second callback invocation will always return the same decision not to
kill it.

Reported-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2012-09-21 11:35:18 +02:00
..
ipset netlink: Rename pid to portid to avoid confusion 2012-09-10 15:30:41 -04:00
ipvs Merge branch 'master' of git://1984.lsi.us.es/nf-next 2012-09-13 14:24:31 -04:00
core.c netfilter: pass 'nf_hook_ops' instead of 'list_head' to nf_queue() 2012-09-03 13:52:54 +02:00
Kconfig netfilter: remove xt_NOTRACK 2012-09-03 13:36:40 +02:00
Makefile netfilter: fix crash during boot if NAT has been compiled built-in 2012-09-05 18:35:51 +02:00
nf_conntrack_acct.c
nf_conntrack_amanda.c netfilter: nf_nat: support IPv6 in amanda NAT helper 2012-08-30 03:00:21 +02:00
nf_conntrack_broadcast.c
nf_conntrack_core.c netfilter: nf_nat: fix oops when unloading protocol modules 2012-09-21 11:35:18 +02:00
nf_conntrack_ecache.c netlink: Rename pid to portid to avoid confusion 2012-09-10 15:30:41 -04:00
nf_conntrack_expect.c netfilter: nf_ct_expect: fix possible access to uninitialized timer 2012-08-16 11:49:53 +02:00
nf_conntrack_extend.c netfilter: nf_ct_ext: support variable length extensions 2012-06-16 15:08:49 +02:00
nf_conntrack_ftp.c netfilter: nf_nat: support IPv6 in FTP NAT helper 2012-08-30 03:00:20 +02:00
nf_conntrack_h323_asn1.c
nf_conntrack_h323_main.c netfilter: nf_nat: add protoff argument to packet mangling functions 2012-08-30 03:00:13 +02:00
nf_conntrack_h323_types.c
nf_conntrack_helper.c netfilter: nf_ct_helper: disable automatic helper re-assignment of different type 2012-06-19 01:24:52 +02:00
nf_conntrack_irc.c netfilter: nf_nat: support IPv6 in IRC NAT helper 2012-08-30 03:00:23 +02:00
nf_conntrack_l3proto_generic.c
nf_conntrack_netbios_ns.c
nf_conntrack_netlink.c Merge branch 'master' of git://1984.lsi.us.es/nf-next 2012-09-13 14:24:31 -04:00
nf_conntrack_pptp.c netfilter: nf_nat: add protoff argument to packet mangling functions 2012-08-30 03:00:13 +02:00
nf_conntrack_proto.c netfilter: nf_conntrack: remove unnecessary RTNL locking 2012-08-20 12:46:29 +02:00
nf_conntrack_proto_dccp.c netfilter: nf_ct_dccp: add dccp_kmemdup_sysctl_table function 2012-06-27 19:14:31 +02:00
nf_conntrack_proto_generic.c netfilter: nf_conntrack: generalize nf_ct_l4proto_net 2012-07-04 19:37:22 +02:00
nf_conntrack_proto_gre.c netfilter: nf_conntrack: prepare l4proto->init_net cleanup 2012-06-27 18:31:14 +02:00
nf_conntrack_proto_sctp.c netfilter: nf_ct_sctp: merge sctpv[4,6]_net_init into sctp_net_init 2012-06-27 19:13:31 +02:00
nf_conntrack_proto_tcp.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-09-15 11:43:53 -04:00
nf_conntrack_proto_udp.c netfilter: nf_conntrack: generalize nf_ct_l4proto_net 2012-07-04 19:37:22 +02:00
nf_conntrack_proto_udplite.c netfilter: nf_ct_udplite: add udplite_kmemdup_sysctl_table function 2012-06-27 19:12:52 +02:00
nf_conntrack_sane.c netfilter: nf_ct_helper: implement variable length helper private data 2012-06-16 15:08:55 +02:00
nf_conntrack_sip.c netfilter: nf_nat: support IPv6 in SIP NAT helper 2012-08-30 03:00:22 +02:00
nf_conntrack_snmp.c
nf_conntrack_standalone.c
nf_conntrack_tftp.c netfilter: nf_nat: support IPv6 in TFTP NAT helper 2012-08-30 03:00:24 +02:00
nf_conntrack_timeout.c
nf_conntrack_timestamp.c
nf_internals.h netfilter: pass 'nf_hook_ops' instead of 'list_head' to nf_queue() 2012-09-03 13:52:54 +02:00
nf_log.c
nf_nat_amanda.c netfilter: nf_nat: support IPv6 in amanda NAT helper 2012-08-30 03:00:21 +02:00
nf_nat_core.c netfilter: nf_nat: fix oops when unloading protocol modules 2012-09-21 11:35:18 +02:00
nf_nat_ftp.c netfilter: nf_nat: support IPv6 in FTP NAT helper 2012-08-30 03:00:20 +02:00
nf_nat_helper.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_irc.c netfilter: nf_nat: support IPv6 in IRC NAT helper 2012-08-30 03:00:23 +02:00
nf_nat_proto_common.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_proto_dccp.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_proto_sctp.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_proto_tcp.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_proto_udp.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_proto_udplite.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_proto_unknown.c netfilter: add protocol independent NAT core 2012-08-30 03:00:14 +02:00
nf_nat_sip.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-09-03 15:34:51 +02:00
nf_nat_tftp.c netfilter: nf_nat: support IPv6 in TFTP NAT helper 2012-08-30 03:00:24 +02:00
nf_queue.c netfilter: pass 'nf_hook_ops' instead of 'list_head' to nf_queue() 2012-09-03 13:52:54 +02:00
nf_sockopt.c
nf_tproxy_core.c
nfnetlink.c netlink: hide struct module parameter in netlink_kernel_create 2012-09-08 18:46:30 -04:00
nfnetlink_acct.c netlink: Rename pid to portid to avoid confusion 2012-09-10 15:30:41 -04:00
nfnetlink_cthelper.c netlink: Rename pid to portid to avoid confusion 2012-09-10 15:30:41 -04:00
nfnetlink_cttimeout.c netlink: Rename pid to portid to avoid confusion 2012-09-10 15:30:41 -04:00
nfnetlink_log.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-09-15 11:43:53 -04:00
nfnetlink_queue_core.c Merge branch 'master' of git://1984.lsi.us.es/nf-next 2012-09-13 14:24:31 -04:00
nfnetlink_queue_ct.c netfilter: nfnetlink_queue: fix sparse warning due to missing include 2012-06-23 02:13:38 +02:00
x_tables.c
xt_addrtype.c
xt_AUDIT.c
xt_CHECKSUM.c
xt_CLASSIFY.c
xt_cluster.c
xt_comment.c
xt_connbytes.c
xt_connlimit.c netfilter: xt_connlimit: remove revision 0 2012-06-07 14:58:39 +02:00
xt_connmark.c
xt_CONNSECMARK.c
xt_conntrack.c
xt_cpu.c
xt_CT.c netfilter: xt_CT: refactorize xt_ct_tg_check 2012-09-03 13:32:48 +02:00
xt_dccp.c
xt_devgroup.c
xt_dscp.c
xt_DSCP.c
xt_ecn.c
xt_esp.c
xt_hashlimit.c netfilter: xt_hashlimit: use _ALL macro to reject unknown flag bits 2012-05-17 00:56:31 +02:00
xt_helper.c
xt_HL.c
xt_hl.c
xt_HMARK.c netfilter: xt_HMARK: fix endianness and provide consistent hashing 2012-06-07 14:53:01 +02:00
xt_IDLETIMER.c
xt_iprange.c
xt_ipvs.c
xt_LED.c
xt_length.c
xt_limit.c netfilter: limit, hashlimit: avoid duplicated inline 2012-05-09 12:54:06 +02:00
xt_LOG.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-09-15 11:43:53 -04:00
xt_mac.c netfilter: Convert compare_ether_addr to ether_addr_equal 2012-05-09 20:49:18 -04:00
xt_mark.c
xt_multiport.c
xt_nat.c netfilter: ipv6: add IPv6 NAT support 2012-08-30 03:00:17 +02:00
xt_nfacct.c
xt_NFLOG.c
xt_NFQUEUE.c netfilter: sparse endian fixes 2012-08-20 12:45:57 +02:00
xt_osf.c netfilter: sparse endian fixes 2012-08-20 12:45:57 +02:00
xt_owner.c userns: xt_owner: Add basic user namespace support. 2012-08-14 21:55:30 -07:00
xt_physdev.c
xt_pkttype.c
xt_policy.c
xt_quota.c
xt_rateest.c
xt_RATEEST.c
xt_realm.c
xt_recent.c userns xt_recent: Specify the owner/group of ip_list_perms in the initial user namespace 2012-08-14 21:55:29 -07:00
xt_repldata.h
xt_sctp.c
xt_SECMARK.c
xt_set.c netfilter: ipset: timeout fixing bug broke SET target special timeout value 2012-07-09 10:53:04 +02:00
xt_socket.c netfilter: xt_socket: fix compilation warnings with gcc 4.7 2012-09-03 13:31:39 +02:00
xt_state.c
xt_statistic.c
xt_string.c
xt_TCPMSS.c net: Convert net_ratelimit uses to net_<level>_ratelimited 2012-05-15 13:45:03 -04:00
xt_tcpmss.c
xt_TCPOPTSTRIP.c
xt_tcpudp.c
xt_TEE.c net: replace percpu_xxx funcs with this_cpu_xxx or __this_cpu_xxx 2012-05-14 14:15:31 -07:00
xt_time.c
xt_TPROXY.c net: Fix (nearly-)kernel-doc comments for various functions 2012-07-10 23:13:45 -07:00
xt_TRACE.c
xt_u32.c