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 ccd08c8dc6a..ce82d0cb1b4 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)  static u32 flow_get_skuid(const struct sk_buff *skb)  { -	if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) -		return skb->sk->sk_socket->file->f_cred->fsuid; +	if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { +		kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid; +		return from_kuid(&init_user_ns, skuid); +	}  	return 0;  }  static u32 flow_get_skgid(const struct sk_buff *skb)  { -	if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) -		return skb->sk->sk_socket->file->f_cred->fsgid; +	if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { +		kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid; +		return from_kgid(&init_user_ns, skgid); +	}  	return 0;  } @@ -347,7 +351,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {  	[TCA_FLOW_PERTURB]	= { .type = NLA_U32 },  }; -static int flow_change(struct tcf_proto *tp, unsigned long base, +static int flow_change(struct sk_buff *in_skb,  +		       struct tcf_proto *tp, unsigned long base,  		       u32 handle, struct nlattr **tca,  		       unsigned long *arg)  { @@ -386,6 +391,10 @@ static int flow_change(struct tcf_proto *tp, unsigned long base,  		if (fls(keymask) - 1 > FLOW_KEY_MAX)  			return -EOPNOTSUPP; + +		if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && +		    sk_user_ns(NETLINK_CB(in_skb).ssk) != &init_user_ns) +			return -EOPNOTSUPP;  	}  	err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map);  |