From: John Stultz Date: Fri, 28 Mar 2014 23:23:48 +0000 (-0700) Subject: ANDROID: netfilter: Build fixups - kuid/kguid changes & xt_socket_get/put_sk X-Git-Tag: android-x86-7.1-r1~142^2~1027 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=bd1bca4efb8e5146ebe5f486cc78092da8a18827;p=android-x86%2Fkernel.git ANDROID: netfilter: Build fixups - kuid/kguid changes & xt_socket_get/put_sk Fix up build kuid/kguid build issues in netfilter code. Also re-add the xt_socket_get/put_sk interfaces needed by xt_qtaguid. Change-Id: I7027fb840e109785bddffe8ea717b8d018b26d82 Signed-off-by: John Stultz --- diff --git a/include/uapi/linux/netfilter/xt_socket.h b/include/uapi/linux/netfilter/xt_socket.h index 87644f832494..8f4da12ca571 100644 --- a/include/uapi/linux/netfilter/xt_socket.h +++ b/include/uapi/linux/netfilter/xt_socket.h @@ -26,4 +26,10 @@ struct xt_socket_mtinfo3 { | XT_SOCKET_NOWILDCARD \ | XT_SOCKET_RESTORESKMARK) +void xt_socket_put_sk(struct sock *sk); +struct sock *xt_socket_get4_sk(const struct sk_buff *skb, + struct xt_action_param *par); +struct sock *xt_socket_get6_sk(const struct sk_buff *skb, + struct xt_action_param *par); + #endif /* _XT_SOCKET_H */ diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 7c9be1706533..0ad8d7a896cf 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -145,22 +145,22 @@ static bool can_manipulate_uids(void) { /* root pwnd */ return in_egroup_p(xt_qtaguid_ctrl_file->gid) - || unlikely(!current_fsuid()) || unlikely(!proc_ctrl_write_limited) - || unlikely(current_fsuid() == xt_qtaguid_ctrl_file->uid); + || unlikely(!from_kuid(&init_user_ns, current_fsuid())) || unlikely(!proc_ctrl_write_limited) + || unlikely(uid_eq(current_fsuid(), xt_qtaguid_ctrl_file->uid)); } -static bool can_impersonate_uid(uid_t uid) +static bool can_impersonate_uid(kuid_t uid) { - return uid == current_fsuid() || can_manipulate_uids(); + return uid_eq(uid, current_fsuid()) || can_manipulate_uids(); } -static bool can_read_other_uid_stats(uid_t uid) +static bool can_read_other_uid_stats(kuid_t uid) { /* root pwnd */ return in_egroup_p(xt_qtaguid_stats_file->gid) - || unlikely(!current_fsuid()) || uid == current_fsuid() + || unlikely(!from_kuid(&init_user_ns, current_fsuid())) || uid_eq(uid, current_fsuid()) || unlikely(!proc_stats_readall_limited) - || unlikely(current_fsuid() == xt_qtaguid_ctrl_file->uid); + || unlikely(uid_eq(current_fsuid(), xt_qtaguid_ctrl_file->uid)); } static inline void dc_add_byte_packets(struct data_counters *counters, int set, @@ -542,7 +542,7 @@ static void put_utd_entry(struct uid_tag_data *utd_entry) "erase utd_entry=%p uid=%u " "by pid=%u tgid=%u uid=%u\n", __func__, utd_entry, utd_entry->uid, - current->pid, current->tgid, current_fsuid()); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); BUG_ON(utd_entry->num_active_tags); rb_erase(&utd_entry->node, &uid_tag_data_tree); kfree(utd_entry); @@ -744,7 +744,7 @@ static int iface_stat_fmt_proc_show(struct seq_file *m, void *v) CT_DEBUG("qtaguid:proc iface_stat_fmt pid=%u tgid=%u uid=%u\n", - current->pid, current->tgid, current_fsuid()); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); iface_entry = list_entry(v, struct iface_stat, list); @@ -1656,7 +1656,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par) const struct file *filp; bool got_sock = false; struct sock *sk; - uid_t sock_uid; + kuid_t sock_uid; bool res; if (unlikely(module_passive)) @@ -1720,7 +1720,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par) 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 ? filp->f_cred->fsuid : -1); + par->hooknum, filp ? from_kuid(&init_user_ns, filp->f_cred->fsuid) : -1); } if (sk == NULL || sk->sk_socket == NULL) { @@ -1761,7 +1761,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par) * For now we only do iface stats when the uid-owner is not requested */ if (!(info->match & XT_QTAGUID_UID)) - account_for_uid(skb, sk, sock_uid, par); + account_for_uid(skb, sk, from_kuid(&init_user_ns, sock_uid), par); /* * The following two tests fail the match when: @@ -1769,25 +1769,32 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par) * or id in range AND inverted condition requested * Thus (!a && b) || (a && !b) == a ^ b */ - if (info->match & XT_QTAGUID_UID) - if ((filp->f_cred->fsuid >= info->uid_min && - filp->f_cred->fsuid <= info->uid_max) ^ + if (info->match & XT_QTAGUID_UID) { + kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); + kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); + + if (uid_gte(filp->f_cred->fsuid, uid_min) && + uid_lte(filp->f_cred->fsuid, uid_max) ^ !(info->invert & XT_QTAGUID_UID)) { MT_DEBUG("qtaguid[%d]: leaving uid not matching\n", par->hooknum); res = false; goto put_sock_ret_res; } - if (info->match & XT_QTAGUID_GID) - if ((filp->f_cred->fsgid >= info->gid_min && - filp->f_cred->fsgid <= info->gid_max) ^ + } + if (info->match & XT_QTAGUID_GID) { + kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); + kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); + + if (gid_gte(filp->f_cred->fsgid, gid_min) && + gid_lte(filp->f_cred->fsgid, gid_max) ^ !(info->invert & XT_QTAGUID_GID)) { MT_DEBUG("qtaguid[%d]: leaving gid not matching\n", par->hooknum); res = false; goto put_sock_ret_res; } - + } MT_DEBUG("qtaguid[%d]: leaving matched\n", par->hooknum); res = true; @@ -1919,7 +1926,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v) long f_count; CT_DEBUG("qtaguid: proc ctrl pid=%u tgid=%u uid=%u\n", - current->pid, current->tgid, current_fsuid()); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); if (sock_tag_entry != SEQ_START_TOKEN) { uid = get_uid_from_tag(sock_tag_entry->tag); @@ -1977,7 +1984,8 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v) static int ctrl_cmd_delete(const char *input) { char cmd; - uid_t uid; + int uid_int; + kuid_t uid; uid_t entry_uid; tag_t acct_tag; tag_t tag; @@ -1991,10 +1999,11 @@ static int ctrl_cmd_delete(const char *input) struct tag_ref *tr_entry; struct uid_tag_data *utd_entry; - argc = sscanf(input, "%c %llu %u", &cmd, &acct_tag, &uid); + argc = sscanf(input, "%c %llu %u", &cmd, &acct_tag, &uid_int); + uid = make_kuid(&init_user_ns, uid_int); CT_DEBUG("qtaguid: ctrl_delete(%s): argc=%d cmd=%c " "user_tag=0x%llx uid=%u\n", input, argc, cmd, - acct_tag, uid); + acct_tag, uid_int); if (argc < 2) { res = -EINVAL; goto err; @@ -2006,18 +2015,19 @@ static int ctrl_cmd_delete(const char *input) } if (argc < 3) { uid = current_fsuid(); + uid_int = from_kuid(&init_user_ns, uid); } else if (!can_impersonate_uid(uid)) { pr_info("qtaguid: ctrl_delete(%s): " "insufficient priv from pid=%u tgid=%u uid=%u\n", - input, current->pid, current->tgid, current_fsuid()); + input, current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); res = -EPERM; goto err; } - tag = combine_atag_with_uid(acct_tag, uid); + tag = combine_atag_with_uid(acct_tag, uid_int); CT_DEBUG("qtaguid: ctrl_delete(%s): " "looking for tag=0x%llx (uid=%u)\n", - input, tag, uid); + input, tag, uid_int); /* Delete socket tags */ spin_lock_bh(&sock_tag_list_lock); @@ -2026,7 +2036,7 @@ static int ctrl_cmd_delete(const char *input) st_entry = rb_entry(node, struct sock_tag, sock_node); entry_uid = get_uid_from_tag(st_entry->tag); node = rb_next(node); - if (entry_uid != uid) + if (entry_uid != uid_int) continue; CT_DEBUG("qtaguid: ctrl_delete(%s): st tag=0x%llx (uid=%u)\n", @@ -2087,7 +2097,7 @@ static int ctrl_cmd_delete(const char *input) "ts tag=0x%llx (uid=%u)\n", input, ts_entry->tn.tag, entry_uid); - if (entry_uid != uid) + if (entry_uid != uid_int) continue; if (!acct_tag || ts_entry->tn.tag == tag) { CT_DEBUG("qtaguid: ctrl_delete(%s): " @@ -2116,7 +2126,7 @@ static int ctrl_cmd_delete(const char *input) "utd uid=%u\n", input, entry_uid); - if (entry_uid != uid) + if (entry_uid != uid_int) continue; /* * Go over the tag_refs, and those that don't have @@ -2160,7 +2170,7 @@ static int ctrl_cmd_counter_set(const char *input) if (!can_manipulate_uids()) { pr_info("qtaguid: ctrl_counterset(%s): " "insufficient priv from pid=%u tgid=%u uid=%u\n", - input, current->pid, current->tgid, current_fsuid()); + input, current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); res = -EPERM; goto err; } @@ -2197,7 +2207,8 @@ static int ctrl_cmd_tag(const char *input) { char cmd; int sock_fd = 0; - uid_t uid = 0; + kuid_t uid; + unsigned int uid_int = 0; tag_t acct_tag = make_atag_from_value(0); tag_t full_tag; struct socket *el_socket; @@ -2208,10 +2219,11 @@ static int ctrl_cmd_tag(const char *input) struct proc_qtu_data *pqd_entry; /* Unassigned args will get defaulted later. */ - argc = sscanf(input, "%c %d %llu %u", &cmd, &sock_fd, &acct_tag, &uid); + argc = sscanf(input, "%c %d %llu %u", &cmd, &sock_fd, &acct_tag, &uid_int); + uid = make_kuid(&init_user_ns, uid_int); CT_DEBUG("qtaguid: ctrl_tag(%s): argc=%d cmd=%c sock_fd=%d " "acct_tag=0x%llx uid=%u\n", input, argc, cmd, sock_fd, - acct_tag, uid); + acct_tag, uid_int); if (argc < 2) { res = -EINVAL; goto err; @@ -2221,7 +2233,7 @@ static int ctrl_cmd_tag(const char *input) pr_info("qtaguid: ctrl_tag(%s): failed to lookup" " sock_fd=%d err=%d pid=%u tgid=%u uid=%u\n", input, sock_fd, res, current->pid, current->tgid, - current_fsuid()); + from_kuid(&init_user_ns, current_fsuid())); goto err; } CT_DEBUG("qtaguid: ctrl_tag(%s): socket->...->f_count=%ld ->sk=%p\n", @@ -2237,21 +2249,24 @@ static int ctrl_cmd_tag(const char *input) CT_DEBUG("qtaguid: ctrl_tag(%s): " "pid=%u tgid=%u uid=%u euid=%u fsuid=%u " "ctrl.gid=%u in_group()=%d in_egroup()=%d\n", - input, current->pid, current->tgid, current_uid(), - current_euid(), current_fsuid(), - xt_qtaguid_ctrl_file->gid, + input, current->pid, current->tgid, + from_kuid(&init_user_ns, current_uid()), + from_kuid(&init_user_ns, current_euid()), + from_kuid(&init_user_ns, current_fsuid()), + from_kgid(&init_user_ns, xt_qtaguid_ctrl_file->gid), in_group_p(xt_qtaguid_ctrl_file->gid), in_egroup_p(xt_qtaguid_ctrl_file->gid)); if (argc < 4) { uid = current_fsuid(); + uid_int = from_kuid(&init_user_ns, uid); } else if (!can_impersonate_uid(uid)) { pr_info("qtaguid: ctrl_tag(%s): " "insufficient priv from pid=%u tgid=%u uid=%u\n", - input, current->pid, current->tgid, current_fsuid()); + input, current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); res = -EPERM; goto err_put; } - full_tag = combine_atag_with_uid(acct_tag, uid); + full_tag = combine_atag_with_uid(acct_tag, uid_int); spin_lock_bh(&sock_tag_list_lock); sock_tag_entry = get_sock_stat_nl(el_socket->sk); @@ -2298,8 +2313,7 @@ static int ctrl_cmd_tag(const char *input) sock_tag_entry->sk = el_socket->sk; sock_tag_entry->socket = el_socket; sock_tag_entry->pid = current->tgid; - sock_tag_entry->tag = combine_atag_with_uid(acct_tag, - uid); + sock_tag_entry->tag = combine_atag_with_uid(acct_tag, uid_int); spin_lock_bh(&uid_tag_data_tree_lock); pqd_entry = proc_qtu_data_tree_search( &proc_qtu_data_tree, current->tgid); @@ -2314,7 +2328,7 @@ static int ctrl_cmd_tag(const char *input) "User space forgot to open /dev/xt_qtaguid? " "pid=%u tgid=%u uid=%u\n", __func__, current->pid, current->tgid, - current_fsuid()); + from_kuid(&init_user_ns, current_fsuid())); else list_add(&sock_tag_entry->list, &pqd_entry->sock_tag_list); @@ -2369,7 +2383,7 @@ static int ctrl_cmd_untag(const char *input) pr_info("qtaguid: ctrl_untag(%s): failed to lookup" " sock_fd=%d err=%d pid=%u tgid=%u uid=%u\n", input, sock_fd, res, current->pid, current->tgid, - current_fsuid()); + from_kuid(&init_user_ns, current_fsuid())); goto err; } CT_DEBUG("qtaguid: ctrl_untag(%s): socket->...->f_count=%ld ->sk=%p\n", @@ -2403,7 +2417,7 @@ static int ctrl_cmd_untag(const char *input) pr_warn_once("qtaguid: %s(): " "User space forgot to open /dev/xt_qtaguid? " "pid=%u tgid=%u uid=%u\n", __func__, - current->pid, current->tgid, current_fsuid()); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); else list_del(&sock_tag_entry->list); spin_unlock_bh(&uid_tag_data_tree_lock); @@ -2446,7 +2460,7 @@ static ssize_t qtaguid_ctrl_parse(const char *input, size_t count) ssize_t res; CT_DEBUG("qtaguid: ctrl(%s): pid=%u tgid=%u uid=%u\n", - input, current->pid, current->tgid, current_fsuid()); + input, current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); cmd = input[0]; /* Collect params for commands */ @@ -2528,14 +2542,15 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry, uid_t stat_uid = get_uid_from_tag(tag); struct proc_print_info *ppi = m->private; /* Detailed tags are not available to everybody */ - if (get_atag_from_tag(tag) && !can_read_other_uid_stats(stat_uid)) { + if (get_atag_from_tag(tag) && !can_read_other_uid_stats( + make_kuid(&init_user_ns,stat_uid))) { CT_DEBUG("qtaguid: stats line: " "%s 0x%llx %u: insufficient priv " "from pid=%u tgid=%u uid=%u stats.gid=%u\n", ppi->iface_entry->ifname, get_atag_from_tag(tag), stat_uid, - current->pid, current->tgid, current_fsuid(), - xt_qtaguid_stats_file->gid); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid()), + from_kgid(&init_user_ns,xt_qtaguid_stats_file->gid)); return 0; } ppi->item_index++; @@ -2737,12 +2752,12 @@ static int qtudev_open(struct inode *inode, struct file *file) return 0; DR_DEBUG("qtaguid: qtudev_open(): pid=%u tgid=%u uid=%u\n", - current->pid, current->tgid, current_fsuid()); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); spin_lock_bh(&uid_tag_data_tree_lock); /* Look for existing uid data, or alloc one. */ - utd_entry = get_uid_data(current_fsuid(), &utd_entry_found); + utd_entry = get_uid_data(from_kuid(&init_user_ns, current_fsuid()), &utd_entry_found); if (IS_ERR_OR_NULL(utd_entry)) { res = PTR_ERR(utd_entry); goto err_unlock; @@ -2754,7 +2769,7 @@ static int qtudev_open(struct inode *inode, struct file *file) if (pqd_entry) { pr_err("qtaguid: qtudev_open(): %u/%u %u " "%s already opened\n", - current->pid, current->tgid, current_fsuid(), + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid()), QTU_DEV_NAME); res = -EBUSY; goto err_unlock_free_utd; @@ -2764,7 +2779,7 @@ static int qtudev_open(struct inode *inode, struct file *file) if (!new_pqd_entry) { pr_err("qtaguid: qtudev_open(): %u/%u %u: " "proc data alloc failed\n", - current->pid, current->tgid, current_fsuid()); + current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid())); res = -ENOMEM; goto err_unlock_free_utd; } @@ -2778,7 +2793,7 @@ static int qtudev_open(struct inode *inode, struct file *file) spin_unlock_bh(&uid_tag_data_tree_lock); DR_DEBUG("qtaguid: tracking data for uid=%u in pqd=%p\n", - current_fsuid(), new_pqd_entry); + from_kuid(&init_user_ns, current_fsuid()), new_pqd_entry); file->private_data = new_pqd_entry; return 0; diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index b10ade272b50..45346438b250 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c @@ -35,6 +35,16 @@ #include #endif +void +xt_socket_put_sk(struct sock *sk) +{ + if (sk->sk_state == TCP_TIME_WAIT) + inet_twsk_put(inet_twsk(sk)); + else + sock_put(sk); +} +EXPORT_SYMBOL(xt_socket_put_sk); + static int extract_icmp4_fields(const struct sk_buff *skb, u8 *protocol, @@ -144,7 +154,7 @@ static bool xt_socket_sk_is_transparent(struct sock *sk) } } -static struct sock *xt_socket_lookup_slow_v4(struct net *net, +struct sock *xt_socket_lookup_slow_v4(struct net *net, const struct sk_buff *skb, const struct net_device *indev) { @@ -208,6 +218,7 @@ static struct sock *xt_socket_lookup_slow_v4(struct net *net, return xt_socket_get_sock_v4(net, data_skb, doff, protocol, saddr, daddr, sport, dport, indev); } +EXPORT_SYMBOL(xt_socket_lookup_slow_v4); static bool socket_match(const struct sk_buff *skb, struct xt_action_param *par, @@ -344,7 +355,7 @@ xt_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, return NULL; } -static struct sock *xt_socket_lookup_slow_v6(struct net *net, +struct sock *xt_socket_lookup_slow_v6(struct net *net, const struct sk_buff *skb, const struct net_device *indev) { @@ -390,6 +401,7 @@ static struct sock *xt_socket_lookup_slow_v6(struct net *net, return xt_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr, sport, dport, indev); } +EXPORT_SYMBOL(xt_socket_lookup_slow_v6); static bool socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par)