diff options
Diffstat (limited to 'net/sched/cls_flow.c')
-rw-r--r-- | net/sched/cls_flow.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index ccd08c8dc6a7..ce82d0cb1b47 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c | |||
@@ -193,15 +193,19 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb) | |||
193 | 193 | ||
194 | static u32 flow_get_skuid(const struct sk_buff *skb) | 194 | static u32 flow_get_skuid(const struct sk_buff *skb) |
195 | { | 195 | { |
196 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) | 196 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { |
197 | return skb->sk->sk_socket->file->f_cred->fsuid; | 197 | kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid; |
198 | return from_kuid(&init_user_ns, skuid); | ||
199 | } | ||
198 | return 0; | 200 | return 0; |
199 | } | 201 | } |
200 | 202 | ||
201 | static u32 flow_get_skgid(const struct sk_buff *skb) | 203 | static u32 flow_get_skgid(const struct sk_buff *skb) |
202 | { | 204 | { |
203 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) | 205 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { |
204 | return skb->sk->sk_socket->file->f_cred->fsgid; | 206 | kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid; |
207 | return from_kgid(&init_user_ns, skgid); | ||
208 | } | ||
205 | return 0; | 209 | return 0; |
206 | } | 210 | } |
207 | 211 | ||
@@ -347,7 +351,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { | |||
347 | [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, | 351 | [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, |
348 | }; | 352 | }; |
349 | 353 | ||
350 | static int flow_change(struct tcf_proto *tp, unsigned long base, | 354 | static int flow_change(struct sk_buff *in_skb, |
355 | struct tcf_proto *tp, unsigned long base, | ||
351 | u32 handle, struct nlattr **tca, | 356 | u32 handle, struct nlattr **tca, |
352 | unsigned long *arg) | 357 | unsigned long *arg) |
353 | { | 358 | { |
@@ -386,6 +391,10 @@ static int flow_change(struct tcf_proto *tp, unsigned long base, | |||
386 | 391 | ||
387 | if (fls(keymask) - 1 > FLOW_KEY_MAX) | 392 | if (fls(keymask) - 1 > FLOW_KEY_MAX) |
388 | return -EOPNOTSUPP; | 393 | return -EOPNOTSUPP; |
394 | |||
395 | if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && | ||
396 | sk_user_ns(NETLINK_CB(in_skb).ssk) != &init_user_ns) | ||
397 | return -EOPNOTSUPP; | ||
389 | } | 398 | } |
390 | 399 | ||
391 | err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); | 400 | err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); |