Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24416c29 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan Committed by Gerrit - the friendly Code Review server
Browse files

netfilter: Unlock xt_table later



This ensures that two concurrent writers through iptables-restore
cannot overwrite each other. Fixes the following-

<6> Unable to handle kernel paging request at
    virtual address 006b6b6b6b6b6bc5
<6> [006b6b6b6b6b6bc5] address between user
    and kernel address ranges
<2> pc : ipt_do_table+0x3b8/0x660
<2> lr : ipt_do_table+0x31c/0x660
<2> Call trace:
<2>  ipt_do_table+0x3b8/0x660
<2>  iptable_mangle_hook+0x58/0xf8
<2>  nf_hook_slow+0x48/0xd8
<2>  __ip_local_out+0xf4/0x138
<2>  __ip_queue_xmit+0x348/0x3a0
<2>  ip_queue_xmit+0x10/0x18
<2>  __tcp_transmit_skb+0x734/0xaa8
<2>  __tcp_retransmit_skb+0x5b8/0x930
<2>  tcp_send_loss_probe+0x19c/0x300
<2>  tcp_write_timer_handler+0x14c/0x238
<2>  tcp_write_timer+0x74/0xa0
<2>  call_timer_fn+0xc0/0x1c0
<2>  run_timer_softirq+0x2f8/0xa30
<2>  __do_softirq+0x1dc/0x384

This enforces the cleanup of the old entries under the xt_table lock.

CRs-fixed: 2612021
Change-Id: If721ceb7891e58847eae5c1ad9c5e9aea4c569e3
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 4cf5de75
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -921,8 +921,6 @@ static int __do_replace(struct net *net, const char *name,
	    (newinfo->number <= oldinfo->initial_entries))
		module_put(t->me);

	xt_table_unlock(t);

	get_old_counters(oldinfo, counters);

	/* Decrease module usage counts and free resource */
@@ -937,6 +935,7 @@ static int __do_replace(struct net *net, const char *name,
		net_warn_ratelimited("arptables: counters copy to user failed while replacing table\n");
	}
	vfree(counters);
	xt_table_unlock(t);
	return ret;

 put_module:
+1 −2
Original line number Diff line number Diff line
@@ -1076,8 +1076,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
	    (newinfo->number <= oldinfo->initial_entries))
		module_put(t->me);

	xt_table_unlock(t);

	get_old_counters(oldinfo, counters);

	/* Decrease module usage counts and free resource */
@@ -1091,6 +1089,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
		net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n");
	}
	vfree(counters);
	xt_table_unlock(t);
	return ret;

 put_module:
+1 −2
Original line number Diff line number Diff line
@@ -1093,8 +1093,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
	    (newinfo->number <= oldinfo->initial_entries))
		module_put(t->me);

	xt_table_unlock(t);

	get_old_counters(oldinfo, counters);

	/* Decrease module usage counts and free resource */
@@ -1108,6 +1106,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
		net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
	}
	vfree(counters);
	xt_table_unlock(t);
	return ret;

 put_module: