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.
Unified · Split
| @@ -5,9 +5,10 @@ · 4 unmodified lines | |||
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 6 | 6 | ||
| 7 | enum { | 7 | enum { |
| 8 | XT_OWNER_UID = 1 << 0, | 8 | XT_OWNER_UID = 1 << 0, |
| 9 | XT_OWNER_GID = 1 << 1, | 9 | XT_OWNER_GID = 1 << 1, |
| 10 | XT_OWNER_SOCKET = 1 << 2, | 10 | XT_OWNER_SOCKET = 1 << 2, |
| 11 | XT_OWNER_SUPPL_GROUPS = 1 << 3, | ||
| 11 | }; | 12 | }; |
| 12 | 13 | ||
| 13 | struct xt_owner_match_info { | 14 | struct xt_owner_match_info { |
| @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) · 90 unmodified lines | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | if (info->match & XT_OWNER_GID) { | 93 | if (info->match & XT_OWNER_GID) { |
| 94 | unsigned int i, match = false; | ||
| 94 | kgid_t gid_min = make_kgid(net->user_ns, info->gid_min); | 95 | kgid_t gid_min = make_kgid(net->user_ns, info->gid_min); |
| 95 | kgid_t gid_max = make_kgid(net->user_ns, info->gid_max); | 96 | kgid_t gid_max = make_kgid(net->user_ns, info->gid_max); |
| 96 | if ((gid_gte(filp->f_cred->fsgid, gid_min) && | 97 | struct group_info *gi = filp->f_cred->group_info; |
| 97 | gid_lte(filp->f_cred->fsgid, gid_max)) ^ | 98 | |
| 98 | !(info->invert & XT_OWNER_GID)) | 99 | if (gid_gte(filp->f_cred->fsgid, gid_min) && |
| 100 | gid_lte(filp->f_cred->fsgid, gid_max)) | ||
| 101 | match = true; | ||
| 102 | |||
| 103 | if (!match && (info->match & XT_OWNER_SUPPL_GROUPS) && gi) { | ||
| 104 | for (i = 0; i < gi->ngroups; ++i) { | ||
| 105 | kgid_t group = gi->gid[i]; | ||
| 106 | |||
| 107 | if (gid_gte(group, gid_min) && | ||
| 108 | gid_lte(group, gid_max)) { | ||
| 109 | match = true; | ||
| 110 | break; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | if (match ^ !(info->invert & XT_OWNER_GID)) | ||
| 99 | return false; | 116 | return false; |
| 100 | } | 117 | } |
| 101 | 118 | ||