diff options
| author | Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | 2016-11-02 11:56:40 -0600 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2017-03-03 10:47:56 -0800 |
| commit | 33af4c0c5faa2ae101db8701d1000512a27dfdb7 (patch) | |
| tree | af194d6a380cb1cc583638f1dc81e629b67348f5 /net | |
| parent | 16f66bfe88211599834fa7109117553835ab4690 (diff) | |
nf: IDLETIMER: Use fullsock when querying uid
sock_i_uid() acquires the sk_callback_lock which does not exist for
sockets in TCP_NEW_SYN_RECV state. This results in errors showing up
as spinlock bad magic. Fix this by looking for the full sock as
suggested by Eric.
Callstack for reference -
-003|rwlock_bug
-004|arch_read_lock
-004|do_raw_read_lock
-005|raw_read_lock_bh
-006|sock_i_uid
-007|from_kuid_munged(inline)
-007|reset_timer
-008|idletimer_tg_target
-009|ipt_do_table
-010|iptable_mangle_hook
-011|nf_iterate
-012|nf_hook_slow
-013|NF_HOOK_COND(inline)
-013|ip_output
-014|ip_local_out
-015|ip_build_and_send_pkt
-016|tcp_v4_send_synack
-017|atomic_sub_return(inline)
-017|reqsk_put(inline)
-017|tcp_conn_request
-018|tcp_v4_conn_request
-019|tcp_rcv_state_process
-020|tcp_v4_do_rcv
-021|tcp_v4_rcv
-022|ip_local_deliver_finish
-023|NF_HOOK_THRESH(inline)
-023|NF_HOOK(inline)
-023|ip_local_deliver
-024|ip_rcv_finish
-025|NF_HOOK_THRESH(inline)
-025|NF_HOOK(inline)
-025|ip_rcv
-026|deliver_skb(inline)
-026|deliver_ptype_list_skb(inline)
-026|__netif_receive_skb_core
-027|__netif_receive_skb
-028|netif_receive_skb_internal
-029|netif_receive_skb
Change-Id: Ic8f3a3d2d7af31434d1163b03971994e2125d552
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Cc: Eric Dumazet <edumazet@google.com>
Diffstat (limited to 'net')
| -rw-r--r-- | net/netfilter/xt_IDLETIMER.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index ada5a304e61e..f11aa28b96ce 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -49,6 +49,7 @@ #include <linux/notifier.h> #include <net/net_namespace.h> #include <net/sock.h> +#include <net/inet_sock.h> struct idletimer_tg_attr { struct attribute attr; @@ -355,7 +356,7 @@ static void reset_timer(const struct idletimer_tg_info *info, /* Stores the uid resposible for waking up the radio */ if (skb && (skb->sk)) { timer->uid = from_kuid_munged(current_user_ns(), - sock_i_uid(skb->sk)); + sock_i_uid(skb_to_full_sk(skb))); } /* checks if there is a pending inactive notification*/ |
