Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

userns: xt_owner: Add basic user namespace support.

- Only allow adding matches from the initial user namespace
- Add the appropriate conversion functions to handle matches
against sockets in other user namespaces.

Cc: Jan Engelhardt <jengelh@medozas.de>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

+24 -7
-1
init/Kconfig
··· 943 943 944 944 # Networking 945 945 depends on NET_9P = n 946 - depends on NETFILTER_XT_MATCH_OWNER = n 947 946 depends on AF_RXRPC = n 948 947 depends on NET_KEY = n 949 948 depends on DNS_RESOLVER = n
+24 -6
net/netfilter/xt_owner.c
··· 17 17 #include <linux/netfilter/x_tables.h> 18 18 #include <linux/netfilter/xt_owner.h> 19 19 20 + static int owner_check(const struct xt_mtchk_param *par) 21 + { 22 + struct xt_owner_match_info *info = par->matchinfo; 23 + 24 + /* For now only allow adding matches from the initial user namespace */ 25 + if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) && 26 + (current_user_ns() != &init_user_ns)) 27 + return -EINVAL; 28 + return 0; 29 + } 30 + 20 31 static bool 21 32 owner_mt(const struct sk_buff *skb, struct xt_action_param *par) 22 33 { ··· 48 37 return ((info->match ^ info->invert) & 49 38 (XT_OWNER_UID | XT_OWNER_GID)) == 0; 50 39 51 - if (info->match & XT_OWNER_UID) 52 - if ((filp->f_cred->fsuid >= info->uid_min && 53 - filp->f_cred->fsuid <= info->uid_max) ^ 40 + if (info->match & XT_OWNER_UID) { 41 + kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); 42 + kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); 43 + if ((uid_gte(filp->f_cred->fsuid, uid_min) && 44 + uid_lte(filp->f_cred->fsuid, uid_max)) ^ 54 45 !(info->invert & XT_OWNER_UID)) 55 46 return false; 47 + } 56 48 57 - if (info->match & XT_OWNER_GID) 58 - if ((filp->f_cred->fsgid >= info->gid_min && 59 - filp->f_cred->fsgid <= info->gid_max) ^ 49 + if (info->match & XT_OWNER_GID) { 50 + kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); 51 + kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); 52 + if ((gid_gte(filp->f_cred->fsgid, gid_min) && 53 + gid_lte(filp->f_cred->fsgid, gid_max)) ^ 60 54 !(info->invert & XT_OWNER_GID)) 61 55 return false; 56 + } 62 57 63 58 return true; 64 59 } ··· 73 56 .name = "owner", 74 57 .revision = 1, 75 58 .family = NFPROTO_UNSPEC, 59 + .checkentry = owner_check, 76 60 .match = owner_mt, 77 61 .matchsize = sizeof(struct xt_owner_match_info), 78 62 .hooks = (1 << NF_INET_LOCAL_OUT) |