ANDROID: Use sk_uid to replace uid get from socket file

Retrieve socket uid from the sk_uid field added to struct sk instead of
read it from sk->socket->file. It prevent the packet been dropped when
the socket file doesn't exist.

Bug: 37524657
Signed-off-by: Chenbo Feng <fengc@google.com>
Change-Id: Ic58239c1f9aa7e0eb1d4d1c09d40b845fd4e8e57
This commit is contained in:
Chenbo Feng 2017-04-20 18:54:13 -07:00
parent 5ce41fd1a0
commit 1e07bd20e4
2 changed files with 26 additions and 33 deletions

View file

@ -1713,18 +1713,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", 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)); 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);
filp = sk->sk_socket ? sk->sk_socket->file : NULL;
MT_DEBUG("qtaguid[%d]: filp...uid=%u\n",
par->hooknum, filp ? from_kuid(&init_user_ns, filp->f_cred->fsuid) : -1);
}
if (sk == NULL || sk->sk_socket == NULL) { if (!sk) {
/* /*
* Here, the qtaguid_find_sk() using connection tracking * Here, the qtaguid_find_sk() using connection tracking
* couldn't find the owner, so for now we just count them * couldn't find the owner, so for now we just count them
@ -1732,9 +1722,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
*/ */
if (do_tag_stat) if (do_tag_stat)
account_for_uid(skb, sk, 0, par); account_for_uid(skb, sk, 0, par);
MT_DEBUG("qtaguid[%d]: leaving (sk?sk->sk_socket)=%p\n", MT_DEBUG("qtaguid[%d]: leaving (sk=NULL)\n", par->hooknum);
par->hooknum,
sk ? sk->sk_socket : NULL);
res = (info->match ^ info->invert) == 0; res = (info->match ^ info->invert) == 0;
atomic64_inc(&qtu_events.match_no_sk); atomic64_inc(&qtu_events.match_no_sk);
goto put_sock_ret_res; goto put_sock_ret_res;
@ -1742,19 +1730,10 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
res = false; res = false;
goto put_sock_ret_res; goto put_sock_ret_res;
} }
filp = sk->sk_socket->file; sock_uid = sk->sk_uid;
if (filp == NULL) {
MT_DEBUG("qtaguid[%d]: leaving filp=NULL\n", par->hooknum);
if (do_tag_stat) if (do_tag_stat)
account_for_uid(skb, sk, 0, par); account_for_uid(skb, sk, from_kuid(&init_user_ns, sock_uid),
res = ((info->match ^ info->invert) & par);
(XT_QTAGUID_UID | XT_QTAGUID_GID)) == 0;
atomic64_inc(&qtu_events.match_no_sk_file);
goto put_sock_ret_res;
}
sock_uid = filp->f_cred->fsuid;
if (do_tag_stat)
account_for_uid(skb, sk, from_kuid(&init_user_ns, sock_uid), par);
/* /*
* The following two tests fail the match when: * The following two tests fail the match when:
@ -1766,8 +1745,8 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min);
kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max);
if ((uid_gte(filp->f_cred->fsuid, uid_min) && if ((uid_gte(sock_uid, uid_min) &&
uid_lte(filp->f_cred->fsuid, uid_max)) ^ uid_lte(sock_uid, uid_max)) ^
!(info->invert & XT_QTAGUID_UID)) { !(info->invert & XT_QTAGUID_UID)) {
MT_DEBUG("qtaguid[%d]: leaving uid not matching\n", MT_DEBUG("qtaguid[%d]: leaving uid not matching\n",
par->hooknum); par->hooknum);
@ -1778,7 +1757,21 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
if (info->match & XT_QTAGUID_GID) { if (info->match & XT_QTAGUID_GID) {
kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min);
kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max);
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);
filp = sk->sk_socket ? sk->sk_socket->file : NULL;
if (!filp) {
res = ((info->match ^ info->invert) &
XT_QTAGUID_GID) == 0;
atomic64_inc(&qtu_events.match_no_sk_gid);
goto put_sock_ret_res;
}
MT_DEBUG("qtaguid[%d]: filp...uid=%u\n",
par->hooknum, filp ?
from_kuid(&init_user_ns, filp->f_cred->fsuid) : -1);
if ((gid_gte(filp->f_cred->fsgid, gid_min) && if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
gid_lte(filp->f_cred->fsgid, gid_max)) ^ gid_lte(filp->f_cred->fsgid, gid_max)) ^
!(info->invert & XT_QTAGUID_GID)) { !(info->invert & XT_QTAGUID_GID)) {
@ -1950,7 +1943,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v)
"match_found_sk_in_ct=%llu " "match_found_sk_in_ct=%llu "
"match_found_no_sk_in_ct=%llu " "match_found_no_sk_in_ct=%llu "
"match_no_sk=%llu " "match_no_sk=%llu "
"match_no_sk_file=%llu\n", "match_no_sk_gid=%llu\n",
(u64)atomic64_read(&qtu_events.sockets_tagged), (u64)atomic64_read(&qtu_events.sockets_tagged),
(u64)atomic64_read(&qtu_events.sockets_untagged), (u64)atomic64_read(&qtu_events.sockets_untagged),
(u64)atomic64_read(&qtu_events.counter_set_changes), (u64)atomic64_read(&qtu_events.counter_set_changes),
@ -1962,7 +1955,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v)
(u64)atomic64_read(&qtu_events.match_found_sk_in_ct), (u64)atomic64_read(&qtu_events.match_found_sk_in_ct),
(u64)atomic64_read(&qtu_events.match_found_no_sk_in_ct), (u64)atomic64_read(&qtu_events.match_found_no_sk_in_ct),
(u64)atomic64_read(&qtu_events.match_no_sk), (u64)atomic64_read(&qtu_events.match_no_sk),
(u64)atomic64_read(&qtu_events.match_no_sk_file)); (u64)atomic64_read(&qtu_events.match_no_sk_gid));
/* Count the following as part of the last item_index. No need /* Count the following as part of the last item_index. No need
* to lock the sock_tag_list here since it is already locked when * to lock the sock_tag_list here since it is already locked when

View file

@ -289,10 +289,10 @@ struct qtaguid_event_counts {
*/ */
atomic64_t match_no_sk; atomic64_t match_no_sk;
/* /*
* The file ptr in the sk_socket wasn't there. * The file ptr in the sk_socket wasn't there and we couldn't get GID.
* This might happen for traffic while the socket is being closed. * This might happen for traffic while the socket is being closed.
*/ */
atomic64_t match_no_sk_file; atomic64_t match_no_sk_gid;
}; };
/* Track the set active_set for the given tag. */ /* Track the set active_set for the given tag. */