ANDROID: xt_qtaguid: handle properly request sockets

To match rules related to uid/gid for syn recv packets
we need to get the full socket from request_sock struct.

Bug: 63917742
Change-Id: I03acb2251319fd800d0e36a6dde30fc1fbb7d1b0
Signed-off-by: Simon Dubray <simonx.dubray@intel.com>
This commit is contained in:
Simon Dubray
2017-08-01 18:22:47 +02:00
committed by Chenbo Feng
parent e6b0c64f6f
commit ce863f8af4

View File

@@ -1597,14 +1597,6 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
if (sk) {
MT_DEBUG("qtaguid: %p->sk_proto=%u "
"->sk_state=%d\n", sk, sk->sk_protocol, sk->sk_state);
/*
* When in TCP_TIME_WAIT the sk is not a "struct sock" but
* "struct inet_timewait_sock" which is missing fields.
*/
if (!sk_fullsock(sk) || sk->sk_state == TCP_TIME_WAIT) {
sock_gen_put(sk);
sk = NULL;
}
}
return sk;
}
@@ -1697,10 +1689,25 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
*/
sk = qtaguid_find_sk(skb, par);
/*
* If we got the socket from the find_sk(), we will need to put
* it back, as nf_tproxy_get_sock_v4() got it.
* TCP_NEW_SYN_RECV are not "struct sock" but "struct request_sock"
* where we can get a pointer to a full socket to retrieve uid/gid.
* When in TCP_TIME_WAIT, sk is a struct inet_timewait_sock
* which is missing fields and does not contain any reference
* to a full socket, so just ignore the socket.
*/
got_sock = sk;
if (sk && sk->sk_state == TCP_NEW_SYN_RECV) {
sock_gen_put(sk);
sk = sk_to_full_sk(sk);
} else if (sk && (!sk_fullsock(sk) || sk->sk_state == TCP_TIME_WAIT)) {
sock_gen_put(sk);
sk = NULL;
} else {
/*
* If we got the socket from the find_sk(), we will need to put
* it back, as nf_tproxy_get_sock_v4() got it.
*/
got_sock = sk;
}
if (sk)
atomic64_inc(&qtu_events.match_found_sk_in_ct);
else