netfilter: xt_owner: Add supplementary groups option 55/212955/1
authorLukasz Pawelczyk <l.pawelczyk@samsung.com>
Fri, 10 May 2019 11:46:22 +0000 (13:46 +0200)
committerRahul Dadhich <r.dadhich@samsung.com>
Wed, 28 Aug 2019 12:48:30 +0000 (12:48 +0000)
The XT_OWNER_SUPPL_GROUPS flag causes GIDs specified with XT_OWNER_GID
to be also checked in the supplementary groups of a process.

f_cred->group_info cannot be modified during its lifetime and f_cred
holds a reference to it so it's safe to use.

Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
backport from mainline to apply supplementary groups on netfilter

Change-Id: I900d03042c82b4d5f13dec7695e4b1eba7f2aa74

include/uapi/linux/netfilter/xt_owner.h
net/netfilter/xt_owner.c

index 2081761714b56cba415b413f7801ef113230407a..e7731dcc51f46f49f427ee4539b6c2259c915a4e 100644 (file)
@@ -4,9 +4,10 @@
 #include <linux/types.h>
 
 enum {
-       XT_OWNER_UID    = 1 << 0,
-       XT_OWNER_GID    = 1 << 1,
-       XT_OWNER_SOCKET = 1 << 2,
+       XT_OWNER_UID          = 1 << 0,
+       XT_OWNER_GID          = 1 << 1,
+       XT_OWNER_SOCKET       = 1 << 2,
+       XT_OWNER_SUPPL_GROUPS = 1 << 3,
 };
 
 struct xt_owner_match_info {
index 1302b475abcbe0c6c2f7c93d416635005ae9b91f..cbe64cf15304e6553a6e66d569842f2eb0f36158 100644 (file)
@@ -60,11 +60,28 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
        }
 
        if (info->match & XT_OWNER_GID) {
+               unsigned int i, match = false;
                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_OWNER_GID))
+               struct group_info *gi = filp->f_cred->group_info;
+
+               if (gid_gte(filp->f_cred->fsgid, gid_min) &&
+                   gid_lte(filp->f_cred->fsgid, gid_max))
+                       match = true;
+
+               if (!match && (info->match & XT_OWNER_SUPPL_GROUPS) && gi) {
+                       for (i = 0; i < gi->ngroups; ++i) {
+                               kgid_t group = GROUP_AT(gi, i);
+
+                               if (gid_gte(group, gid_min) &&
+                                   gid_lte(group, gid_max)) {
+                                       match = true;
+                                       break;
+                               }
+                       }
+               }
+
+               if (match ^ !(info->invert & XT_OWNER_GID))
                        return false;
        }