xt_qtaguid: Use sk_callback_lock read locks before reading sk->sk_socket
authorMohamad Ayyash <mkayyash@google.com>
Wed, 14 Jan 2015 03:20:44 +0000 (19:20 -0800)
committerMohamad Ayyash <mkayyash@google.com>
Wed, 28 Jan 2015 20:18:37 +0000 (12:18 -0800)
It prevents a kernel panic when accessing sk->sk_socket fields due to NULLing sk->sk_socket when sock_orphan is called through
sk_common_release.

Change-Id: I4aa46b4e2d8600e4d4ef8dcdd363aa4e6e5f8433
Signed-off-by: Mohamad Ayyash <mkayyash@google.com>
(cherry picked from commit cdea0ebcb8bcfe57688f6cb692b49e550ebd9796)

net/netfilter/xt_qtaguid.c

index 9128933a5b212feebe4591d0b3a624831e022f10..bcc622e64b16ba80e8d6c6850c4aa4c99051ccb6 100644 (file)
@@ -1658,6 +1658,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
        struct sock *sk;
        uid_t sock_uid;
        bool res;
+       bool set_sk_callback_lock = false;
 
        if (unlikely(module_passive))
                return (info->match ^ info->invert) == 0;
@@ -1715,6 +1716,8 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
        MT_DEBUG("qtaguid[%d]: sk=%p got_sock=%d fam=%d proto=%d\n",
                 par->hooknum, sk, got_sock, par->family, ipx_proto(skb, par));
        if (sk != NULL) {
+               set_sk_callback_lock = true;
+               read_lock_bh(&sk->sk_callback_lock);
                MT_DEBUG("qtaguid[%d]: sk=%p->sk_socket=%p->file=%p\n",
                        par->hooknum, sk, sk->sk_socket,
                        sk->sk_socket ? sk->sk_socket->file : (void *)-1LL);
@@ -1794,6 +1797,8 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
 put_sock_ret_res:
        if (got_sock)
                xt_socket_put_sk(sk);
+       if (set_sk_callback_lock)
+               read_unlock_bh(&sk->sk_callback_lock);
 ret_res:
        MT_DEBUG("qtaguid[%d]: left %d\n", par->hooknum, res);
        return res;