aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-05-25 15:49:36 -0400
committerEric W. Biederman <ebiederm@xmission.com>2012-08-15 00:55:28 -0400
commita6c6796c7127de55cfa9bb0cfbb082ec0acd4eab (patch)
tree6723b8c4c3c2ca58e1988e72191468e51299f2a1 /net/sched
parentaf4c6641f5ad445fe6d0832da42406dbd9a37ce4 (diff)
userns: Convert cls_flow to work with user namespaces enabled
The flow classifier can use uids and gids of the sockets that are transmitting packets and do insert those uids and gids into the packet classification calcuation. I don't fully understand the details but it appears that we can depend on specific uids and gids when making traffic classification decisions. To work with user namespaces enabled map from kuids and kgids into uids and gids in the initial user namespace giving raw integer values the code can play with and depend on. To avoid issues of userspace depending on uids and gids in packet classifiers installed from other user namespaces and getting confused deny all packet classifiers that use uids or gids that are not comming from a netlink socket in the initial user namespace. Cc: Patrick McHardy <kaber@trash.net> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Jamal Hadi Salim <jhs@mojatatu.com> Cc: Changli Gao <xiaosuo@gmail.com> 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>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/cls_flow.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index ae854f3434b0..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
194static u32 flow_get_skuid(const struct sk_buff *skb) 194static 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
201static u32 flow_get_skgid(const struct sk_buff *skb) 203static 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
@@ -387,6 +391,10 @@ static int flow_change(struct sk_buff *in_skb,
387 391
388 if (fls(keymask) - 1 > FLOW_KEY_MAX) 392 if (fls(keymask) - 1 > FLOW_KEY_MAX)
389 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;
390 } 398 }
391 399
392 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);