mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
ANDROID: netfilter: xt_socket/nf_socket: fix refcount underflow and crash
nf_socket_get_sock_v[4|6]() do not always increment sock refcount, which causes confusion in xt_qtaguid module which is not aware of this fact and drops the reference whether it should have or not. Fix it by changing nf_socket_get_sock_v[4|6]() to always increment recount of returned sock. This should fix the following crash: [ 111.319523] BUG: failure at /mnt/host/source/src/third_party/kernel/v3.18/net/ipv4/inet_timewait_sock.c:90/__inet_twsk_kill()! [ 111.331192] Kernel panic - not syncing: BUG! [ 111.335468] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G U W 3.18.0-06867-g268df91 #1 [ 111.343810] Hardware name: Google Tegra210 Smaug Rev 1+ (DT) [ 111.349463] Call trace: [ 111.351917] [<ffffffc000207288>] dump_backtrace+0x0/0x10c [ 111.357314] [<ffffffc0002073a4>] show_stack+0x10/0x1c [ 111.362367] [<ffffffc000a82d1c>] dump_stack+0x74/0x94 [ 111.367414] [<ffffffc000a81824>] panic+0xec/0x238 [ 111.372116] [<ffffffc000981648>] __inet_twsk_kill+0xd0/0xf8 [ 111.377684] [<ffffffc0009817b0>] inet_twdr_do_twkill_work+0x64/0xd0 [ 111.383946] [<ffffffc000981a5c>] inet_twdr_hangman+0x2c/0xa4 [ 111.389602] [<ffffffc000271cf0>] call_timer_fn+0xac/0x160 [ 111.394995] [<ffffffc00027250c>] run_timer_softirq+0x23c/0x274 [ 111.400824] [<ffffffc000220a68>] __do_softirq+0x1a4/0x330 [ 111.406218] [<ffffffc000220e94>] irq_exit+0x70/0xd0 [ 111.411093] [<ffffffc000264e00>] __handle_domain_irq+0x84/0xa8 [ 111.416922] [<ffffffc0002003ec>] gic_handle_irq+0x4c/0x80 b/22476945 Originally reviewed at: https://chromium-review.googlesource.com/#/c/297414/ Change-Id: I51fa94a9d92a84a0bd3b58466d711e46a6892a79 Signed-off-by: Dmitry Torokhov <dtor@google.com> [jstultz: Cherry-picked and added missing local var definition] Signed-off-by: John Stultz <john.stultz@linaro.org> [AmitP: Refactored the original changes based on upstream commit, 8db4c5be88f6 ("netfilter: move socket lookup infrastructure to nf_socket_ipv{4,6}.c"), changes. Also use refcount_inc instead of atomic_inc to align with 41c6d650f653 ("net: convert sock.sk_refcnt from atomic_t to refcount_t")] Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
This commit is contained in:
parent
4921ad46f4
commit
3f0f52fbe9
@ -100,6 +100,7 @@ struct sock *nf_sk_lookup_slow_v4(struct net *net, const struct sk_buff *skb,
|
||||
__be16 uninitialized_var(dport), uninitialized_var(sport);
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct sk_buff *data_skb = NULL;
|
||||
struct sock *sk = skb->sk;
|
||||
u8 uninitialized_var(protocol);
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
enum ip_conntrack_info ctinfo;
|
||||
@ -153,8 +154,14 @@ struct sock *nf_sk_lookup_slow_v4(struct net *net, const struct sk_buff *skb,
|
||||
}
|
||||
#endif
|
||||
|
||||
return nf_socket_get_sock_v4(net, data_skb, doff, protocol, saddr,
|
||||
daddr, sport, dport, indev);
|
||||
if (sk)
|
||||
refcount_inc(&sk->sk_refcnt);
|
||||
else
|
||||
sk = nf_socket_get_sock_v4(dev_net(skb->dev), data_skb, doff,
|
||||
protocol, saddr, daddr, sport,
|
||||
dport, indev);
|
||||
|
||||
return sk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_sk_lookup_slow_v4);
|
||||
|
||||
|
@ -102,6 +102,7 @@ nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff,
|
||||
struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
|
||||
const struct net_device *indev)
|
||||
{
|
||||
struct sock *sk = skb->sk;
|
||||
__be16 uninitialized_var(dport), uninitialized_var(sport);
|
||||
const struct in6_addr *daddr = NULL, *saddr = NULL;
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
@ -141,8 +142,14 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nf_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr,
|
||||
sport, dport, indev);
|
||||
if (sk)
|
||||
refcount_inc(&sk->sk_refcnt);
|
||||
else
|
||||
sk = nf_socket_get_sock_v6(dev_net(skb->dev), data_skb, doff,
|
||||
tproto, saddr, daddr, sport, dport,
|
||||
indev);
|
||||
|
||||
return sk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_sk_lookup_slow_v6);
|
||||
|
||||
|
@ -79,8 +79,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
|
||||
transparent && sk_fullsock(sk))
|
||||
pskb->mark = sk->sk_mark;
|
||||
|
||||
if (sk != skb->sk)
|
||||
sock_gen_put(sk);
|
||||
sock_gen_put(sk);
|
||||
|
||||
if (wildcard || !transparent)
|
||||
sk = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user