Patchwork net: Allow tc changes in user namespaces

login
register
mail settings
Submitter Stéphane Graber
Date May 8, 2014, 11:19 p.m.
Message ID <1399591198-3837-1-git-send-email-stgraber@ubuntu.com>
Download mbox | patch
Permalink /patch/347276/
State New
Headers show

Comments

Stéphane Graber - May 8, 2014, 11:19 p.m.
This switches a few remaining capable(CAP_NET_ADMIN) to ns_capable so
that root in a user namespace may set tc rules inside that namespace.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: "David S. Miller" <davem@davemloft.net>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stéphane Graber - May 8, 2014, 11:21 p.m.
Hey there,

The patch below allows tc to work in unprivileged containers.

I'd ideally like to see this applied to trusty and utopic. It's
currently sitting in net-next and so should get merged into linus' tree
with the next pull.

Thanks!

On Thu, May 08, 2014 at 06:19:58PM -0500, Stéphane Graber wrote:
> This switches a few remaining capable(CAP_NET_ADMIN) to ns_capable so
> that root in a user namespace may set tc rules inside that namespace.
> 
> Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Acked-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> 
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index a481bbe..1a4a202 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -134,7 +134,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
>  	int err;
>  	int tp_created = 0;
>  
> -	if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN))
> +	if ((n->nlmsg_type != RTM_GETTFILTER) &&
> +	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>  		return -EPERM;
>  
>  replay:
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index a0b84e0..86f8edf 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -1084,7 +1084,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
>  	struct Qdisc *p = NULL;
>  	int err;
>  
> -	if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN))
> +	if ((n->nlmsg_type != RTM_GETQDISC) &&
> +	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>  		return -EPERM;
>  
>  	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
> @@ -1151,7 +1152,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
>  	struct Qdisc *q, *p;
>  	int err;
>  
> -	if (!capable(CAP_NET_ADMIN))
> +	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
>  		return -EPERM;
>  
>  replay:
> @@ -1490,7 +1491,8 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n)
>  	u32 qid;
>  	int err;
>  
> -	if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN))
> +	if ((n->nlmsg_type != RTM_GETTCLASS) &&
> +	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>  		return -EPERM;
>  
>  	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
> -- 
> cgit v0.10.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Tim Gardner - May 9, 2014, 1:13 a.m.
On 05/08/2014 06:19 PM, Stéphane Graber wrote:
> This switches a few remaining capable(CAP_NET_ADMIN) to ns_capable so
> that root in a user namespace may set tc rules inside that namespace.
>
> Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Acked-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index a481bbe..1a4a202 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -134,7 +134,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
>   	int err;
>   	int tp_created = 0;
>
> -	if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN))
> +	if ((n->nlmsg_type != RTM_GETTFILTER) &&
> +	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>   		return -EPERM;
>
>   replay:
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index a0b84e0..86f8edf 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -1084,7 +1084,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
>   	struct Qdisc *p = NULL;
>   	int err;
>
> -	if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN))
> +	if ((n->nlmsg_type != RTM_GETQDISC) &&
> +	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>   		return -EPERM;
>
>   	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
> @@ -1151,7 +1152,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
>   	struct Qdisc *q, *p;
>   	int err;
>
> -	if (!capable(CAP_NET_ADMIN))
> +	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
>   		return -EPERM;
>
>   replay:
> @@ -1490,7 +1491,8 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n)
>   	u32 qid;
>   	int err;
>
> -	if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN))
> +	if ((n->nlmsg_type != RTM_GETTCLASS) &&
> +	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>   		return -EPERM;
>
>   	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
>

This looks like it should get merged next week. We'll until until then 
'cause it won't make this SRU cycle anyway.

rtg

Patch

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index a481bbe..1a4a202 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -134,7 +134,8 @@  static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
 	int err;
 	int tp_created = 0;
 
-	if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN))
+	if ((n->nlmsg_type != RTM_GETTFILTER) &&
+	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
 replay:
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index a0b84e0..86f8edf 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1084,7 +1084,8 @@  static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
 	struct Qdisc *p = NULL;
 	int err;
 
-	if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN))
+	if ((n->nlmsg_type != RTM_GETQDISC) &&
+	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
 	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1151,7 +1152,7 @@  static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
 	struct Qdisc *q, *p;
 	int err;
 
-	if (!capable(CAP_NET_ADMIN))
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
 replay:
@@ -1490,7 +1491,8 @@  static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n)
 	u32 qid;
 	int err;
 
-	if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN))
+	if ((n->nlmsg_type != RTM_GETTCLASS) &&
+	    !ns_capable(net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
 	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);