User namespace changes to the networking stack.
Subsystems (18)
cover User namespace changes to the networking stack.
This is a modest set of changes against the current networking stack to enable basic user namespace support. Allowing the code to compile with user namespaces enabled and removing the assumption that there is only the initial user namespace.
Work to relax the privilege checks in the networking stack from "capable(CAP_NET_ADMIN)" or "capable(CAP_NET_RAW)" to "ns_capable(net->user_ns, CAP_NET_ADMIN)" or "ns_capable(net->user_ns, CAP_NET_RAW)" allowing root in a user namespace to control a network namespace will come later.
David there are just enough interdependencies between the user namespace bits that I intend to merge them all through my user namespace tree. After the review is complete I will add these patches to my for-next branch of my user-namespace.git tree where I do not intend to rebase. If it make sense to pull these into net-next to avoid or reduce conflicts that should not be a problem.
A current snapshot of my development tree for people who are interested in seeing the entire picture is at:
git.kernel.org:/pub/scm/linux/kernel/git/ebiederm/user-namespace.git userns-always-map-user-v46
Eric W. Biederman (21):
userns: Convert net/core/scm.c to use kuids and kgids
userns: Convert __dev_set_promiscuity to use kuids in audit logs
userns: Convert sock_i_uid to return a kuid_t
userns: Allow USER_NS and NET simultaneously in Kconfig
userns: Make seq_file's user namespace accessible
userns: Print out socket uids in a user namespace aware fashion.
userns: Use kgids for sysctl_ping_group_range
net ip6 flowlabel: Make owner a union of struct pid * and kuid_t
pidns: Export free_pid_ns
userns: Convert net/ax25 to use kuid_t where appropriate
netlink: Make the sending netlink socket availabe in NETLINK_CB
userns: Implement sk_user_ns
userns: Teach inet_diag to work with user namespaces
userns: nfnetlink_log: Report socket uids in the log sockets user namespace net sched: Pass the skb into change so it can access NETLINK_CB
userns: Convert cls_flow to work with user namespaces enabled
userns: Convert xt_LOG to print socket kuids and kgids as uids and gids userns xt_recent: Specify the owner/group of ip_list_perms in the initial user namespace
userns: xt_owner: Add basic user namespace support.
userns: Make the airo wireless driver use kuids for proc uids and gids
userns: Convert tun/tap to use kuid and kgid where appropriate
drivers/net/tun.c | 46 ++++++++++++++++++++++++++----------- drivers/net/wireless/airo.c | 48 +++++++++++++++++++++++---------------- fs/seq_file.c | 4 +++ include/linux/inet_diag.h | 1 + include/linux/netlink.h | 1 + include/linux/seq_file.h | 14 +++++++++++ include/net/ax25.h | 4 +- include/net/ipv6.h | 5 +++- include/net/netns/ipv4.h | 3 +- include/net/sch_generic.h | 3 +- include/net/sock.h | 11 ++++++++- include/net/tcp.h | 3 +- init/Kconfig | 18 -------------- kernel/pid.c | 1 + kernel/pid_namespace.c | 2 + net/appletalk/atalk_proc.c | 3 +- net/ax25/ax25_uid.c | 21 +++++++++++----- net/core/dev.c | 7 +++-- net/core/scm.c | 31 ++++++++++++++++++------ net/core/sock.c | 10 ++++---- net/ipv4/inet_diag.c | 21 ++++++++++++----- net/ipv4/ping.c | 22 +++++++---------- net/ipv4/raw.c | 4 ++- net/ipv4/sysctl_net_ipv4.c | 42 ++++++++++++++++++++++------------ net/ipv4/tcp_ipv4.c | 6 ++-- net/ipv4/udp.c | 4 ++- net/ipv4/udp_diag.c | 5 +++- net/ipv6/ip6_flowlabel.c | 50 +++++++++++++++++++++++++++++++++++----- net/ipv6/raw.c | 3 +- net/ipv6/tcp_ipv6.c | 6 ++-- net/ipv6/udp.c | 3 +- net/ipx/ipx_proc.c | 3 +- net/key/af_key.c | 2 +- net/llc/llc_proc.c | 2 +- net/netfilter/nfnetlink_log.c | 14 ++++++++--- net/netfilter/xt_LOG.c | 16 ++++++++----- net/netfilter/xt_owner.c | 30 +++++++++++++++++++----- net/netfilter/xt_recent.c | 13 +++++++++- net/netlink/af_netlink.c | 6 +++- net/packet/af_packet.c | 2 +- net/phonet/socket.c | 6 +++- net/sched/cls_api.c | 2 +- net/sched/cls_basic.c | 3 +- net/sched/cls_cgroup.c | 3 +- net/sched/cls_flow.c | 19 +++++++++++---- net/sched/cls_fw.c | 3 +- net/sched/cls_route.c | 3 +- net/sched/cls_rsvp.h | 3 +- net/sched/cls_tcindex.c | 3 +- net/sched/cls_u32.c | 3 +- net/sctp/proc.c | 6 +++- 51 files changed, 368 insertions(+), 176 deletions(-)
Eric
PATCH 1/21 userns: Convert net/core/scm.c to use kuids and kgids
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
With the existence of kuid_t and kgid_t we can take this further and remove the usage of struct cred altogether, ensuring we
don't get cache line misses from reference counts. For now
however start simply and do a straight forward conversion I can be certain is correct.
In cred_to_ucred use from_kuid_munged and from_kgid_munged as these values are going directly to userspace and we want to use the userspace safe values not -1 when reporting a value that does not map. The earlier conversion that used from_kuid was buggy in that respect. Oops.
--- net/core/scm.c | 31 +++++++++++++++++++++++-------- net/core/sock.c | 4 ++-- 2 files changed, 25 insertions(+), 10 deletions(-)
net/core/scm.c +23 -8
@@ -45,12 +45,17 @@static __inline__int scm_check_creds (struct ucred *creds) {const struct cred *cred =current_cred (); +kuid_t uid =make_kuid (cred->user_ns, creds->uid); +kgid_t gid =make_kgid (cred->user_ns, creds->gid); + +if (!uid_valid (uid) || !gid_valid (gid)) +return -EINVAL ;if ((creds->pid ==task_tgid_vnr (current) ||capable (CAP_SYS_ADMIN )) && - ((creds->uid == cred->uid || creds->uid == cred->euid || - creds->uid == cred->suid) ||capable (CAP_SETUID )) && - ((creds->gid == cred->gid || creds->gid == cred->egid || - creds->gid == cred->sgid) ||capable (CAP_SETGID ))) { + ((uid_eq (uid, cred->uid) ||uid_eq (uid, cred->euid) || +uid_eq (uid, cred->suid)) ||capable (CAP_SETUID )) && + ((gid_eq (gid, cred->gid) ||gid_eq (gid, cred->egid) || +gid_eq (gid, cred->sgid)) ||capable (CAP_SETGID ))) {return 0 ; }return -EPERM ;
@@ -149,6 +154,9 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) goto error;break ;case SCM_CREDENTIALS : + { +kuid_t uid; +kgid_t gid;if (cmsg->cmsg_len !=CMSG_LEN (sizeof (struct ucred ))) goto error;memcpy (&p->creds,CMSG_DATA (cmsg),sizeof (struct ucred ));
@@ -166,22 +174,29 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) p->pid = pid; } + err = -EINVAL ; + uid =make_kuid (current_user_ns (), p->creds.uid); + gid =make_kgid (current_user_ns (), p->creds.gid); +if (!uid_valid (uid) || !gid_valid (gid)) + goto error; +if (!p->cred || - (p->cred->euid != p->creds.uid) || - (p->cred->egid != p->creds.gid)) { + !uid_eq (p->cred->euid, uid) || + !gid_eq (p->cred->egid, gid)) {struct cred *cred; err = -ENOMEM ; cred =prepare_creds ();if (!cred) goto error; - cred->uid = cred->euid = p->creds.uid; - cred->gid = cred->egid = p->creds.gid; + cred->uid = cred->euid = uid; + cred->gid = cred->egid = gid;if (p->cred)put_cred (p->cred); p->cred = cred; }break ; + }default : goto error; }
net/core/sock.c +2 -2
@@ -868,8 +868,8 @@ void cred_to_ucred(struct pid *pid, const struct cred *cred,if (cred) {struct user_namespace *current_ns =current_user_ns (); - ucred->uid =from_kuid (current_ns, cred->euid); - ucred->gid =from_kgid (current_ns, cred->egid); + ucred->uid =from_kuid_munged (current_ns, cred->euid); + ucred->gid =from_kgid_munged (current_ns, cred->egid); } }EXPORT_SYMBOL_GPL (cred_to_ucred);
Signature · 1 line
1.7.5.4
PATCH 2/21 userns: Convert __dev_set_promiscuity to use kuids in audit logs
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
--- net/core/dev.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
net/core/dev.c +4 -3
@@ -4492,8 +4492,8 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)static int __dev_set_promiscuity (struct net_device *dev,int inc) {unsigned int old_flags = dev->flags; -uid_t uid; -gid_t gid; +kuid_t uid; +kgid_t gid;ASSERT_RTNL ();
@@ -4525,7 +4525,8 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc) dev->name, (dev->flags &IFF_PROMISC ), (old_flags &IFF_PROMISC ),audit_get_loginuid (current), - uid, gid, +from_kuid (&init_user_ns, uid), +from_kgid (&init_user_ns, gid), audit_get_sessionid(current)); }
Signature · 1 line
1.7.5.4
PATCH 3/21 userns: Convert sock_i_uid to return a kuid_t
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
--- include/net/sock.h | 2 +- net/core/sock.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
include/net/sock.h +1 -1
@@ -1668,7 +1668,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)write_unlock_bh (&sk->sk_callback_lock); } -extern int sock_i_uid (struct sock *sk); +extern kuid_t sock_i_uid (struct sock *sk);extern unsigned long sock_i_ino (struct sock *sk); static inline struct dst_entry *
net/core/sock.c +3 -3
@@ -1526,12 +1526,12 @@ void sock_edemux(struct sk_buff *skb) }EXPORT_SYMBOL (sock_edemux); -int sock_i_uid (struct sock *sk) +kuid_t sock_i_uid (struct sock *sk) { -int uid; +kuid_t uid;read_lock_bh (&sk->sk_callback_lock); - uid = sk->sk_socket ?SOCK_INODE (sk->sk_socket)->i_uid :0 ; + uid = sk->sk_socket ?SOCK_INODE (sk->sk_socket)->i_uid :GLOBAL_ROOT_UID ;read_unlock_bh (&sk->sk_callback_lock);return uid; }
Signature · 1 line
1.7.5.4
PATCH 4/21 userns: Allow USER_NS and NET simultaneously in Kconfig
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Now that the networking core is user namespace safe allow networking and user namespaces to be built at the same time.
--- init/Kconfig | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
init/Kconfig +1 -1
@@ -942,7 +942,7 @@ config UIDGID_CONVERTED depends on PROC_EVENTS = n # Networking - depends on NET = n + depends on PACKET = n depends on NET_9P = n depends on IPX = n depends on PHONET = n
Signature · 1 line
1.7.5.4
PATCH 5/21 userns: Make seq_file's user namespace accessible
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
struct file already has a user namespace associated with it in file->f_cred->user_ns, unfortunately because struct seq_file has no struct file backpointer associated with it, it is difficult to get at the user namespace in seq_file context. Therefore add a helper function seq_user_ns to return the associated user namespace and a user_ns field to struct seq_file to be used in implementing seq_user_ns.
--- fs/seq_file.c | 4 ++++ include/linux/seq_file.h | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 0 deletions(-)
fs/seq_file.c +4 -0
@@ -9,6 +9,7 @@#include <linux/export.h> #include <linux/seq_file.h> #include <linux/slab.h> +#include <linux/cred.h> #include <asm/uaccess.h> #include <asm/page.h>
@@ -56,6 +57,9 @@ int seq_open(struct file *file, const struct seq_operations *op)memset (p,0 ,sizeof (*p));mutex_init (&p->lock); p->op = op; +#ifdef CONFIG_USER_NS + p->user_ns = file->f_cred->user_ns; +#endif /* * Wrappers around seq_open(e.g. swaps_open) need to be
include/linux/seq_file.h +14 -0
@@ -13,6 +13,7 @@ struct file;struct path ;struct inode ;struct dentry ; +struct user_namespace ;struct seq_file {char *buf;
@@ -25,6 +26,9 @@ struct seq_file {struct mutex lock;const struct seq_operations *op;int poll_event; +#ifdef CONFIG_USER_NS +struct user_namespace *user_ns; +#endif void *private; };
@@ -128,6 +132,16 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter,int seq_put_decimal_ll (struct seq_file *m,char delimiter,long long num); +static inline struct user_namespace *seq_user_ns (struct seq_file *seq) +{ +#ifdef CONFIG_USER_NS +return seq->user_ns; +#else +extern struct user_namespace init_user_ns; +return &init_user_ns; +#endif +} +#define SEQ_START_TOKEN ((void *)1)/* * Helpers for iteration over list_head-s in seq_files
Signature · 1 line
1.7.5.4
PATCH 6/21 userns: Print out socket uids in a user namespace aware fashion.
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
--- include/net/tcp.h | 3 ++- init/Kconfig | 6 ------ net/appletalk/atalk_proc.c | 3 ++- net/ipv4/ping.c | 4 +++- net/ipv4/raw.c | 4 +++- net/ipv4/tcp_ipv4.c | 6 +++--- net/ipv4/udp.c | 4 +++- net/ipv6/raw.c | 3 ++- net/ipv6/tcp_ipv6.c | 6 +++--- net/ipv6/udp.c | 3 ++- net/ipx/ipx_proc.c | 3 ++- net/key/af_key.c | 2 +- net/llc/llc_proc.c | 2 +- net/packet/af_packet.c | 2 +- net/phonet/socket.c | 6 ++++-- net/sctp/proc.c | 6 ++++-- 16 files changed, 36 insertions(+), 27 deletions(-)
include/net/tcp.h +2 -1
@@ -1509,7 +1509,8 @@ struct tcp_iter_state {sa_family_t family;enum tcp_seq_states state;struct sock *syn_wait_sk; -int bucket, offset, sbucket, num, uid; +int bucket, offset, sbucket, num; +kuid_t uid;loff_t last_pos; };
init/Kconfig +0 -6
@@ -942,10 +942,7 @@ config UIDGID_CONVERTED depends on PROC_EVENTS = n # Networking - depends on PACKET = n depends on NET_9P = n - depends on IPX = n - depends on PHONET = n depends on NET_CLS_FLOW = n depends on NETFILTER_XT_MATCH_OWNER = n depends on NETFILTER_XT_MATCH_RECENT = n
@@ -953,14 +950,11 @@ config UIDGID_CONVERTED depends on NETFILTER_NETLINK_LOG = n depends on INET = n depends on IPV6 = n - depends on IP_SCTP = n depends on AF_RXRPC = n - depends on LLC2 = n depends on NET_KEY = n depends on INET_DIAG = n depends on DNS_RESOLVER = n depends on AX25 = n - depends on ATALK = n # Filesystems depends on USB_GADGETFS = n
net/appletalk/atalk_proc.c +2 -1
@@ -183,7 +183,8 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v)ntohs (at->dest_net), at->dest_node, at->dest_port,sk_wmem_alloc_get (s),sk_rmem_alloc_get (s), - s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); + s->sk_state, + from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); out:return 0 ; }
net/ipv4/ping.c +3 -1
@@ -845,7 +845,9 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f, bucket, src, srcp, dest, destp, sp->sk_state,sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp), -0 ,0L ,0 ,sock_i_uid (sp),0 ,sock_i_ino (sp), +0 ,0L ,0 , +from_kuid_munged (seq_user_ns (f),sock_i_uid (sp)), +0 ,sock_i_ino (sp),atomic_read (&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops), len); }
net/ipv4/raw.c +3 -1
@@ -992,7 +992,9 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) i, src, srcp, dest, destp, sp->sk_state,sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp), -0 ,0L ,0 ,sock_i_uid (sp),0 ,sock_i_ino (sp), +0 ,0L ,0 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), +0 ,sock_i_ino (sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); }
net/ipv4/tcp_ipv4.c +3 -3
@@ -2382,7 +2382,7 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo)EXPORT_SYMBOL (tcp_proc_unregister);static void get_openreq4 (const struct sock *sk,const struct request_sock *req, -struct seq_file *f,int i,int uid,int *len) +struct seq_file *f,int i,kuid_t uid,int *len) {const struct inet_request_sock *ireq =inet_rsk (req);int ttd = req->expires - jiffies;
@@ -2399,7 +2399,7 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req,1 ,/* timers active (only the expire timer) */ jiffies_to_clock_t (ttd), req->retrans, - uid, +from_kuid_munged (seq_user_ns (f), uid),0 ,/* non standard timer */ 0 ,/* open_requests have no inode */ atomic_read(&sk->sk_refcnt),
@@ -2450,7 +2450,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) timer_active,jiffies_to_clock_t (timer_expires - jiffies), icsk->icsk_retransmits, -sock_i_uid (sk), +from_kuid_munged (seq_user_ns (f),sock_i_uid (sk)), icsk->icsk_probes_out,sock_i_ino (sk), atomic_read(&sk->sk_refcnt), sk,
net/ipv4/udp.c +3 -1
@@ -2110,7 +2110,9 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, bucket, src, srcp, dest, destp, sp->sk_state,sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp), -0 ,0L ,0 ,sock_i_uid (sp),0 ,sock_i_ino (sp), +0 ,0L ,0 , +from_kuid_munged (seq_user_ns (f),sock_i_uid (sp)), +0 ,sock_i_ino (sp),atomic_read (&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops), len); }
net/ipv6/raw.c +2 -1
@@ -1251,7 +1251,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp),0 ,0L ,0 , -sock_i_uid (sp),0 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), +0 ,sock_i_ino (sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); }
net/ipv6/tcp_ipv6.c +3 -3
@@ -1803,7 +1803,7 @@ static void tcp_v6_destroy_sock(struct sock *sk)#ifdef CONFIG_PROC_FS /* Proc filesystem TCPv6 sock list dumping. */ static void get_openreq6 (struct seq_file *seq, -const struct sock *sk,struct request_sock *req,int i,int uid) +const struct sock *sk,struct request_sock *req,int i,kuid_t uid) {int ttd = req->expires - jiffies;const struct in6_addr *src = &inet6_rsk (req)->loc_addr;
@@ -1827,7 +1827,7 @@ static void get_openreq6(struct seq_file *seq,1 ,/* timers active (only the expire timer) */ jiffies_to_clock_t (ttd), req->retrans, - uid, +from_kuid_munged (seq_user_ns (seq), uid),0 ,/* non standard timer */ 0 ,/* open_requests have no inode */ 0, req);
@@ -1877,7 +1877,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) timer_active,jiffies_to_clock_t (timer_expires - jiffies), icsk->icsk_retransmits, -sock_i_uid (sp), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), icsk->icsk_probes_out,sock_i_ino (sp), atomic_read(&sp->sk_refcnt), sp,
net/ipv6/udp.c +2 -1
@@ -1458,7 +1458,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucketsk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp),0 ,0L ,0 , -sock_i_uid (sp),0 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), +0 ,sock_i_ino (sp),atomic_read (&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
net/ipx/ipx_proc.c +2 -1
@@ -217,7 +217,8 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v)seq_printf (seq,"%08X %08X %02X %03d\n" ,sk_wmem_alloc_get (s),sk_rmem_alloc_get (s), - s->sk_state,SOCK_INODE (s->sk_socket)->i_uid); + s->sk_state, +from_kuid_munged (seq_user_ns (seq),sock_i_uid (s))); out:return 0 ; }
net/key/af_key.c +1 -1
@@ -3661,7 +3661,7 @@ static int pfkey_seq_show(struct seq_file *f, void *v)atomic_read (&s->sk_refcnt),sk_rmem_alloc_get (s),sk_wmem_alloc_get (s), -sock_i_uid (s), +from_kuid_munged (seq_user_ns (f),sock_i_uid (s)),sock_i_ino (s) );return 0 ;
net/llc/llc_proc.c +1 -1
@@ -151,7 +151,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)sk_wmem_alloc_get (sk),sk_rmem_alloc_get (sk) - llc->copied_seq, sk->sk_state, - sk->sk_socket ?SOCK_INODE (sk->sk_socket)->i_uid :-1 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), llc->link); out:return 0 ;
net/packet/af_packet.c +1 -1
@@ -3846,7 +3846,7 @@ static int packet_seq_show(struct seq_file *seq, void *v) po->ifindex, po->running,atomic_read (&s->sk_rmem_alloc), -sock_i_uid (s), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (s)), sock_i_ino(s)); }
net/phonet/socket.c +4 -2
@@ -612,7 +612,8 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v) sk->sk_protocol, pn->sobject, pn->dobject, pn->resource, sk->sk_state,sk_wmem_alloc_get (sk),sk_rmem_alloc_get (sk), -sock_i_uid (sk),sock_i_ino (sk), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), +sock_i_ino (sk),atomic_read (&sk->sk_refcnt), sk, atomic_read(&sk->sk_drops), &len); }
@@ -796,7 +797,8 @@ static int pn_res_seq_show(struct seq_file *seq, void *v)struct sock *sk = *psk;seq_printf (seq,"%02X %5d %lu%n" , - (int ) (psk - pnres.sk),sock_i_uid (sk), + (int ) (psk - pnres.sk), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)),sock_i_ino (sk), &len); }seq_printf (seq,"%*s\n" ,63 - len,"" );
net/sctp/proc.c +4 -2
@@ -216,7 +216,8 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)seq_printf (seq,"%8pK %8pK %-3d %-3d %-4d %-5d %5d %5lu " , ep, sk,sctp_sk (sk)->type, sk->sk_state, hash, epb->bind_addr.port, -sock_i_uid (sk),sock_i_ino (sk)); +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), +sock_i_ino (sk));sctp_seq_dump_local_addrs (seq, epb);seq_printf (seq,"\n" );
@@ -324,7 +325,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) assoc->assoc_id, assoc->sndbuf_used,atomic_read (&assoc->rmem_alloc), -sock_i_uid (sk),sock_i_ino (sk), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), +sock_i_ino (sk), epb->bind_addr.port, assoc->peer.port);seq_printf (seq," " );
Signature · 1 line
1.7.5.4
Re: [PATCH 06/21] userns: Print out socket uids in a user namespace aware fashion.
Le lundi 13 août 2012 23:18:20, vous avez écrit :
Quoted 12 lines
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Cc David Miller <davem-fT/PcQaiUtIeIZ0/[email protected]>Cc Alexey Kuznetsov <kuznet-v/[email protected]>Cc James Morris <jmorris-gx6/[email protected]>Cc Hideaki YOSHIFUJI <[email protected]>Cc Patrick McHardy <[email protected]>Cc Arnaldo Carvalho de Melo <[email protected]>Cc Vlad Yasevich <[email protected]>Cc Sridhar Samudrala <sri-r/[email protected]>Acked-by Serge Hallyn <[email protected]>
FWIW, ...
Signature · 3 lines
Rémi Denis-Courmont C/C++ software engineer looking for a job http://www.linkedin.com/in/remidenis
Re: [PATCH 06/21] userns: Print out socket uids in a user namespace aware fashion.
Quoted 14 lines · Rémi Denis-Courmont
Le lundi 13 août 2012 23:18:20, vous avez écrit :
Quoted 12 lines
From: "Eric W. Biederman" <[email protected]>
Cc David Miller <[email protected]>Cc Alexey Kuznetsov <[email protected]>Cc James Morris <[email protected]>Cc Hideaki YOSHIFUJI <[email protected]>Cc Patrick McHardy <[email protected]>Cc Arnaldo Carvalho de Melo <[email protected]>Cc Vlad Yasevich <[email protected]>Cc Sridhar Samudrala <[email protected]>Acked-by Serge Hallyn <[email protected]>Signed-off-by Eric W. Biederman <[email protected]>
Quoted 1 line
FWIW, ...
Well I will take every bit of review I can get. It can be terribly embarrassing to discover you messed up uid/gid handling and no one noticed the security hole for 3 kernel releases...
Quoted 1 line
_______________________________________________
Containers mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/containers
Re: [PATCH 06/21] userns: Print out socket uids in a user namespace aware fashion.
In reply to Eric W. BiedermanQuoted 13 lines · Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Cc David Miller <davem-fT/PcQaiUtIeIZ0/[email protected]>Cc Alexey Kuznetsov <kuznet-v/[email protected]>Cc James Morris <jmorris-gx6/[email protected]>Cc Hideaki YOSHIFUJI <[email protected]>Cc Patrick McHardy <[email protected]>Cc Remi Denis-Courmont <[email protected]>Cc Arnaldo Carvalho de Melo <[email protected]>Cc Vlad Yasevich <[email protected]>Cc Sridhar Samudrala <sri-r/[email protected]>Acked-by Serge Hallyn <[email protected]>
ACK sctp parts
Quoted 314 lines
--- include/net/tcp.h | 3 ++- init/Kconfig | 6 ------ net/appletalk/atalk_proc.c | 3 ++- net/ipv4/ping.c | 4 +++- net/ipv4/raw.c | 4 +++- net/ipv4/tcp_ipv4.c | 6 +++--- net/ipv4/udp.c | 4 +++- net/ipv6/raw.c | 3 ++- net/ipv6/tcp_ipv6.c | 6 +++--- net/ipv6/udp.c | 3 ++- net/ipx/ipx_proc.c | 3 ++- net/key/af_key.c | 2 +- net/llc/llc_proc.c | 2 +- net/packet/af_packet.c | 2 +- net/phonet/socket.c | 6 ++++-- net/sctp/proc.c | 6 ++++-- 16 files changed, 36 insertions(+), 27 deletions(-)include/net/tcp.h +2
-1@@ -1509,7 +1509,8 @@ struct tcp_iter_state {sa_family_t family;enum tcp_seq_states state;struct sock *syn_wait_sk; -int bucket, offset, sbucket, num, uid; +int bucket, offset, sbucket, num; +kuid_t uid;loff_t last_pos; };init/Kconfig +0
-6@@ -942,10 +942,7 @@ config UIDGID_CONVERTED depends on PROC_EVENTS = n # Networking - depends on PACKET = n depends on NET_9P = n - depends on IPX = n - depends on PHONET = n depends on NET_CLS_FLOW = n depends on NETFILTER_XT_MATCH_OWNER = n depends on NETFILTER_XT_MATCH_RECENT = n@@ -953,14 +950,11 @@ config UIDGID_CONVERTED depends on NETFILTER_NETLINK_LOG = n depends on INET = n depends on IPV6 = n - depends on IP_SCTP = n depends on AF_RXRPC = n - depends on LLC2 = n depends on NET_KEY = n depends on INET_DIAG = n depends on DNS_RESOLVER = n depends on AX25 = n - depends on ATALK = n # Filesystems depends on USB_GADGETFS = nnet/appletalk/atalk_proc.c +2
-1@@ -183,7 +183,8 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v)ntohs (at->dest_net), at->dest_node, at->dest_port,sk_wmem_alloc_get (s),sk_rmem_alloc_get (s), - s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); + s->sk_state, + from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); out:return 0 ; }net/ipv4/ping.c +3
-1@@ -845,7 +845,9 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f, bucket, src, srcp, dest, destp, sp->sk_state,sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp), -0 ,0L ,0 ,sock_i_uid (sp),0 ,sock_i_ino (sp), +0 ,0L ,0 , +from_kuid_munged (seq_user_ns (f),sock_i_uid (sp)), +0 ,sock_i_ino (sp),atomic_read (&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops), len); }net/ipv4/raw.c +3
-1@@ -992,7 +992,9 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) i, src, srcp, dest, destp, sp->sk_state,sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp), -0 ,0L ,0 ,sock_i_uid (sp),0 ,sock_i_ino (sp), +0 ,0L ,0 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), +0 ,sock_i_ino (sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); }net/ipv4/tcp_ipv4.c +3
-3@@ -2382,7 +2382,7 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo)EXPORT_SYMBOL (tcp_proc_unregister);static void get_openreq4 (const struct sock *sk,const struct request_sock *req, -struct seq_file *f,int i,int uid,int *len) +struct seq_file *f,int i,kuid_t uid,int *len) {const struct inet_request_sock *ireq =inet_rsk (req);int ttd = req->expires - jiffies;@@ -2399,7 +2399,7 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req,1 ,/* timers active (only the expire timer) */ jiffies_to_clock_t (ttd), req->retrans, - uid, +from_kuid_munged (seq_user_ns (f), uid),0 ,/* non standard timer */ 0 ,/* open_requests have no inode */ atomic_read(&sk->sk_refcnt),@@ -2450,7 +2450,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) timer_active,jiffies_to_clock_t (timer_expires - jiffies), icsk->icsk_retransmits, -sock_i_uid (sk), +from_kuid_munged (seq_user_ns (f),sock_i_uid (sk)), icsk->icsk_probes_out,sock_i_ino (sk), atomic_read(&sk->sk_refcnt), sk,net/ipv4/udp.c +3
-1@@ -2110,7 +2110,9 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, bucket, src, srcp, dest, destp, sp->sk_state,sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp), -0 ,0L ,0 ,sock_i_uid (sp),0 ,sock_i_ino (sp), +0 ,0L ,0 , +from_kuid_munged (seq_user_ns (f),sock_i_uid (sp)), +0 ,sock_i_ino (sp),atomic_read (&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops), len); }net/ipv6/raw.c +2
-1@@ -1251,7 +1251,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)sk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp),0 ,0L ,0 , -sock_i_uid (sp),0 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), +0 ,sock_i_ino (sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); }net/ipv6/tcp_ipv6.c +3
-3@@ -1803,7 +1803,7 @@ static void tcp_v6_destroy_sock(struct sock *sk)#ifdef CONFIG_PROC_FS /* Proc filesystem TCPv6 sock list dumping. */ static void get_openreq6 (struct seq_file *seq, -const struct sock *sk,struct request_sock *req,int i,int uid) +const struct sock *sk,struct request_sock *req,int i,kuid_t uid) {int ttd = req->expires - jiffies;const struct in6_addr *src = &inet6_rsk (req)->loc_addr;@@ -1827,7 +1827,7 @@ static void get_openreq6(struct seq_file *seq,1 ,/* timers active (only the expire timer) */ jiffies_to_clock_t (ttd), req->retrans, - uid, +from_kuid_munged (seq_user_ns (seq), uid),0 ,/* non standard timer */ 0 ,/* open_requests have no inode */ 0, req);@@ -1877,7 +1877,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) timer_active,jiffies_to_clock_t (timer_expires - jiffies), icsk->icsk_retransmits, -sock_i_uid (sp), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), icsk->icsk_probes_out,sock_i_ino (sp), atomic_read(&sp->sk_refcnt), sp,net/ipv6/udp.c +2
-1@@ -1458,7 +1458,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucketsk_wmem_alloc_get (sp),sk_rmem_alloc_get (sp),0 ,0L ,0 , -sock_i_uid (sp),0 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sp)), +0 ,sock_i_ino (sp),atomic_read (&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));net/ipx/ipx_proc.c +2
-1@@ -217,7 +217,8 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v)seq_printf (seq,"%08X %08X %02X %03d\n" ,sk_wmem_alloc_get (s),sk_rmem_alloc_get (s), - s->sk_state,SOCK_INODE (s->sk_socket)->i_uid); + s->sk_state, +from_kuid_munged (seq_user_ns (seq),sock_i_uid (s))); out:return 0 ; }net/key/af_key.c +1
-1@@ -3661,7 +3661,7 @@ static int pfkey_seq_show(struct seq_file *f, void *v)atomic_read (&s->sk_refcnt),sk_rmem_alloc_get (s),sk_wmem_alloc_get (s), -sock_i_uid (s), +from_kuid_munged (seq_user_ns (f),sock_i_uid (s)),sock_i_ino (s) );return 0 ;net/llc/llc_proc.c +1
-1@@ -151,7 +151,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)sk_wmem_alloc_get (sk),sk_rmem_alloc_get (sk) - llc->copied_seq, sk->sk_state, - sk->sk_socket ?SOCK_INODE (sk->sk_socket)->i_uid :-1 , +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), llc->link); out:return 0 ;net/packet/af_packet.c +1
-1@@ -3846,7 +3846,7 @@ static int packet_seq_show(struct seq_file *seq, void *v) po->ifindex, po->running,atomic_read (&s->sk_rmem_alloc), -sock_i_uid (s), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (s)), sock_i_ino(s)); }net/phonet/socket.c +4
-2@@ -612,7 +612,8 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v) sk->sk_protocol, pn->sobject, pn->dobject, pn->resource, sk->sk_state,sk_wmem_alloc_get (sk),sk_rmem_alloc_get (sk), -sock_i_uid (sk),sock_i_ino (sk), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), +sock_i_ino (sk),atomic_read (&sk->sk_refcnt), sk, atomic_read(&sk->sk_drops), &len); }@@ -796,7 +797,8 @@ static int pn_res_seq_show(struct seq_file *seq, void *v)struct sock *sk = *psk;seq_printf (seq,"%02X %5d %lu%n" , - (int ) (psk - pnres.sk),sock_i_uid (sk), + (int ) (psk - pnres.sk), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)),sock_i_ino (sk), &len); }seq_printf (seq,"%*s\n" ,63 - len,"" );net/sctp/proc.c +4
-2@@ -216,7 +216,8 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)seq_printf (seq,"%8pK %8pK %-3d %-3d %-4d %-5d %5d %5lu " , ep, sk,sctp_sk (sk)->type, sk->sk_state, hash, epb->bind_addr.port, -sock_i_uid (sk),sock_i_ino (sk)); +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), +sock_i_ino (sk));sctp_seq_dump_local_addrs (seq, epb);seq_printf (seq,"\n" );@@ -324,7 +325,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) assoc->assoc_id, assoc->sndbuf_used,atomic_read (&assoc->rmem_alloc), -sock_i_uid (sk),sock_i_ino (sk), +from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)), +sock_i_ino (sk), epb->bind_addr.port, assoc->peer.port);seq_printf (seq," " );
PATCH 7/21 userns: Use kgids for sysctl_ping_group_range
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
- Store sysctl_ping_group_range as a paire of kgid_t values instead of a pair of gid_t values.
- Move the kgid conversion work from ping_init_sock into ipv4_ping_group_range
- For invalid cases reset to the default disabled state.
With the kgid_t conversion made part of the original value sanitation from userspace understand how the code will react becomes clearer and it becomes possible to set the sysctl ping group range from something other than the initial user namespace.
--- include/net/netns/ipv4.h | 3 ++- init/Kconfig | 1 - net/ipv4/ping.c | 18 ++++++------------ net/ipv4/sysctl_net_ipv4.c | 42 +++++++++++++++++++++++++++--------------- 4 files changed, 35 insertions(+), 29 deletions(-)
include/net/netns/ipv4.h +2 -1
@@ -5,6 +5,7 @@#ifndef __NETNS_IPV4_H__#define __NETNS_IPV4_H__ +#include <linux/uidgid.h> #include <net/inet_frag.h> struct tcpm_hash_bucket ;
@@ -62,7 +63,7 @@ struct netns_ipv4 {int sysctl_icmp_ratemask;int sysctl_icmp_errors_use_inbound_ifaddr; -unsigned int sysctl_ping_group_range[2 ]; +kgid_t sysctl_ping_group_range[2 ];long sysctl_tcp_mem[3 ];atomic_t rt_genid;
init/Kconfig +0 -1
@@ -948,7 +948,6 @@ config UIDGID_CONVERTED depends on NETFILTER_XT_MATCH_RECENT = n depends on NETFILTER_XT_TARGET_LOG = n depends on NETFILTER_NETLINK_LOG = n - depends on INET = n depends on IPV6 = n depends on AF_RXRPC = n depends on NET_KEY = n
net/ipv4/ping.c +6 -12
@@ -185,10 +185,10 @@ exit:return sk; } -static void inet_get_ping_group_range_net (struct net *net,gid_t *low, -gid_t *high) +static void inet_get_ping_group_range_net (struct net *net,kgid_t *low, +kgid_t *high) { -gid_t *data = net->ipv4.sysctl_ping_group_range; +kgid_t *data = net->ipv4.sysctl_ping_group_range;unsigned int seq; do {
@@ -203,19 +203,13 @@ static void inet_get_ping_group_range_net(struct net *net, gid_t *low,static int ping_init_sock (struct sock *sk) {struct net *net =sock_net (sk); -gid_t group =current_egid (); -gid_t range[2 ]; +kgid_t group =current_egid ();struct group_info *group_info =get_current_groups ();int i, j, count = group_info->ngroups;kgid_t low, high; -inet_get_ping_group_range_net (net, range, range+1 ); - low =make_kgid (&init_user_ns, range[0 ]); - high =make_kgid (&init_user_ns, range[1 ]); -if (!gid_valid (low) || !gid_valid (high) ||gid_lt (high, low)) -return -EACCES ; - -if (range[0 ] <= group && group <= range[1 ]) +inet_get_ping_group_range_net (net, &low, &high); +if (gid_lte (low, group) &&gid_lte (group, high))return 0 ;for (i =0 ; i < group_info->nblocks; i++) {
net/ipv4/sysctl_net_ipv4.c +27 -15
84 lines not on this page · raw message
Signature · 1 line
1.7.5.4
Re: [PATCH 07/21] userns: Use kgids for sysctl_ping_group_range
Quoted 7 lines · Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
- Store
sysctl_ping_group_rangeas a paire ofkgid_tvalues instead of a pair ofgid_tvalues.
- Move the kgid conversion work fromping_init_sockintoipv4_ping_group_range
- For invalid cases reset to the default disabled state.
Quoted 7 lines
With the
kgid_tconversion made part of the original value sanitation from userspace understand how the code will react becomes clearer and it becomes possible to set the sysctl ping group range from something other than the initial user namespace.Cc Vasiliy Kulikov <segoon-cxoSlKxDwOJWk0Htik3J/[email protected]>
Looks good.
Thanks,
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
PATCH 8/21 net ip6 flowlabel: Make owner a union of struct pid * and kuid_t
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Correct a long standing omission and use struct pid in the owner field of struct ip6_flowlabel when the share type is IPV6_FL_S_PROCESS. This guarantees we don't have issues when pid wraparound occurs.
Use a kuid_t in the owner field of struct ip6_flowlabel when the share type is IPV6_FL_S_USER to add user namespace support.
In /proc/net/ip6_flowlabel capture the current pid namespace when opening the file and release the pid namespace when the file is closed ensuring we print the pid owner value that is meaning to the reader of the file. Similarly use from_kuid_munged to print uid values that are meaningful to the reader of the file.
This requires exporting pid_nr_ns so that ipv6 can continue to built as a module. Yoiks what silliness
--- include/net/ipv6.h | 5 +++- init/Kconfig | 1 - kernel/pid.c | 1 + net/ipv6/ip6_flowlabel.c | 50 +++++++++++++++++++++++++++++++++++++++------ 4 files changed, 48 insertions(+), 9 deletions(-)
include/net/ipv6.h +4 -1
@@ -222,7 +222,10 @@ struct ip6_flowlabel {struct ipv6_txoptions *opt;unsigned long linger;u8 share; -u32 owner; +union { +struct pid *pid; +kuid_t uid; + } owner;unsigned long lastuse;unsigned long expires;struct net *fl_net;
init/Kconfig +0 -1
@@ -948,7 +948,6 @@ config UIDGID_CONVERTED depends on NETFILTER_XT_MATCH_RECENT = n depends on NETFILTER_XT_TARGET_LOG = n depends on NETFILTER_NETLINK_LOG = n - depends on IPV6 = n depends on AF_RXRPC = n depends on NET_KEY = n depends on INET_DIAG = n
kernel/pid.c +1 -0
@@ -479,6 +479,7 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) }return nr; } +EXPORT_SYMBOL_GPL (pid_nr_ns);pid_t pid_vnr (struct pid *pid) {
net/ipv6/ip6_flowlabel.c +43 -7
106 lines not on this page · raw message
Signature · 1 line
1.7.5.4
PATCH 9/21 pidns: Export free_pid_ns
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
There is a least one modular user so export free_pid_ns so modules can capture and use the pid namespace on the very rare occasion when it makes sense.
--- kernel/pid_namespace.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
kernel/pid_namespace.c +2 -0
@@ -16,6 +16,7 @@#include <linux/slab.h> #include <linux/proc_fs.h> #include <linux/reboot.h> +#include <linux/export.h> #define BITS_PER_PAGE (PAGE_SIZE*8)
@@ -144,6 +145,7 @@ void free_pid_ns(struct kref *kref)if (parent !=NULL )put_pid_ns (parent); } +EXPORT_SYMBOL_GPL (free_pid_ns);void zap_pid_ns_processes (struct pid_namespace *pid_ns) {
Signature · 1 line
1.7.5.4
A message that is not in the archive (sent off-list or not yet received): 1344889115-21610-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]
PATCH 10/21 userns: Convert net/ax25 to use kuid_t where appropriate
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
--- include/net/ax25.h | 4 ++-- init/Kconfig | 1 - net/ax25/ax25_uid.c | 21 ++++++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-)
include/net/ax25.h +2 -2
@@ -157,7 +157,7 @@ enum {typedef struct ax25_uid_assoc {struct hlist_node uid_node;atomic_t refcount; -uid_t uid; +kuid_t uid;ax25_address call; }ax25_uid_assoc ;
@@ -434,7 +434,7 @@ extern unsigned long ax25_display_timer(struct timer_list *);/* ax25_uid.c */ extern int ax25_uid_policy; -extern ax25_uid_assoc *ax25_findbyuid (uid_t ); +extern ax25_uid_assoc *ax25_findbyuid (kuid_t );extern int __must_check ax25_uid_ioctl (int ,struct sockaddr_ax25 *);extern const struct file_operations ax25_uid_fops;extern void ax25_uid_free (void );
init/Kconfig +0 -1
@@ -952,7 +952,6 @@ config UIDGID_CONVERTED depends on NET_KEY = n depends on INET_DIAG = n depends on DNS_RESOLVER = n - depends on AX25 = n # Filesystems depends on USB_GADGETFS = n
net/ax25/ax25_uid.c +14 -7
@@ -51,14 +51,14 @@ int ax25_uid_policy;EXPORT_SYMBOL (ax25_uid_policy); -ax25_uid_assoc *ax25_findbyuid (uid_t uid) +ax25_uid_assoc *ax25_findbyuid (kuid_t uid) {ax25_uid_assoc *ax25_uid, *res =NULL ;struct hlist_node *node;read_lock (&ax25_uid_lock);ax25_uid_for_each (ax25_uid, node, &ax25_uid_list) { -if (ax25_uid->uid == uid) { +if (uid_eq (ax25_uid->uid, uid)) {ax25_uid_hold (ax25_uid); res = ax25_uid;break ;
@@ -84,7 +84,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)read_lock (&ax25_uid_lock);ax25_uid_for_each (ax25_uid, node, &ax25_uid_list) {if (ax25cmp (&sax->sax25_call, &ax25_uid->call) ==0 ) { - res = ax25_uid->uid; + res =from_kuid_munged (current_user_ns (), ax25_uid->uid);break ; } }
@@ -93,9 +93,14 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)return res;case SIOCAX25ADDUID : + { +kuid_t sax25_kuid;if (!capable (CAP_NET_ADMIN ))return -EPERM ; - user =ax25_findbyuid (sax->sax25_uid); + sax25_kuid =make_kuid (current_user_ns (), sax->sax25_uid); +if (!uid_valid (sax25_kuid)) +return -EINVAL ; + user =ax25_findbyuid (sax25_kuid);if (user) {ax25_uid_put (user);return -EEXIST ;
@@ -106,7 +111,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)return -ENOMEM ;atomic_set (&ax25_uid->refcount,1 ); - ax25_uid->uid = sax->sax25_uid; + ax25_uid->uid = sax25_kuid; ax25_uid->call = sax->sax25_call;write_lock (&ax25_uid_lock);
@@ -114,7 +119,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)write_unlock (&ax25_uid_lock);return 0 ; - + }case SIOCAX25DELUID :if (!capable (CAP_NET_ADMIN ))return -EPERM ;
@@ -172,7 +177,9 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v)struct ax25_uid_assoc *pt; pt = hlist_entry(v, struct ax25_uid_assoc, uid_node); -seq_printf (seq,"%6d %s\n" , pt->uid,ax2asc (buf, &pt->call)); +seq_printf (seq,"%6d %s\n" , +from_kuid_munged (seq_user_ns (seq), pt->uid), +ax2asc (buf, &pt->call)); }return 0 ; }
Signature · 1 line
1.7.5.4
PATCH 10/21 userns: Convert net/ax25 to use kuid_t where appropriate
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <[email protected]>
--- include/net/ax25.h | 4 ++-- init/Kconfig | 1 - net/ax25/ax25_uid.c | 21 ++++++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-)
include/net/ax25.h +2 -2
@@ -157,7 +157,7 @@ enum {typedef struct ax25_uid_assoc {struct hlist_node uid_node;atomic_t refcount; -uid_t uid; +kuid_t uid;ax25_address call; }ax25_uid_assoc ;
@@ -434,7 +434,7 @@ extern unsigned long ax25_display_timer(struct timer_list *);/* ax25_uid.c */ extern int ax25_uid_policy; -extern ax25_uid_assoc *ax25_findbyuid (uid_t ); +extern ax25_uid_assoc *ax25_findbyuid (kuid_t );extern int __must_check ax25_uid_ioctl (int ,struct sockaddr_ax25 *);extern const struct file_operations ax25_uid_fops;extern void ax25_uid_free (void );
init/Kconfig +0 -1
@@ -952,7 +952,6 @@ config UIDGID_CONVERTED depends on NET_KEY = n depends on INET_DIAG = n depends on DNS_RESOLVER = n - depends on AX25 = n # Filesystems depends on USB_GADGETFS = n
net/ax25/ax25_uid.c +14 -7
@@ -51,14 +51,14 @@ int ax25_uid_policy;EXPORT_SYMBOL (ax25_uid_policy); -ax25_uid_assoc *ax25_findbyuid (uid_t uid) +ax25_uid_assoc *ax25_findbyuid (kuid_t uid) {ax25_uid_assoc *ax25_uid, *res =NULL ;struct hlist_node *node;read_lock (&ax25_uid_lock);ax25_uid_for_each (ax25_uid, node, &ax25_uid_list) { -if (ax25_uid->uid == uid) { +if (uid_eq (ax25_uid->uid, uid)) {ax25_uid_hold (ax25_uid); res = ax25_uid;break ;
@@ -84,7 +84,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)read_lock (&ax25_uid_lock);ax25_uid_for_each (ax25_uid, node, &ax25_uid_list) {if (ax25cmp (&sax->sax25_call, &ax25_uid->call) ==0 ) { - res = ax25_uid->uid; + res =from_kuid_munged (current_user_ns (), ax25_uid->uid);break ; } }
@@ -93,9 +93,14 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)return res;case SIOCAX25ADDUID : + { +kuid_t sax25_kuid;if (!capable (CAP_NET_ADMIN ))return -EPERM ; - user =ax25_findbyuid (sax->sax25_uid); + sax25_kuid =make_kuid (current_user_ns (), sax->sax25_uid); +if (!uid_valid (sax25_kuid)) +return -EINVAL ; + user =ax25_findbyuid (sax25_kuid);if (user) {ax25_uid_put (user);return -EEXIST ;
@@ -106,7 +111,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)return -ENOMEM ;atomic_set (&ax25_uid->refcount,1 ); - ax25_uid->uid = sax->sax25_uid; + ax25_uid->uid = sax25_kuid; ax25_uid->call = sax->sax25_call;write_lock (&ax25_uid_lock);
@@ -114,7 +119,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)write_unlock (&ax25_uid_lock);return 0 ; - + }case SIOCAX25DELUID :if (!capable (CAP_NET_ADMIN ))return -EPERM ;
@@ -172,7 +177,9 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v)struct ax25_uid_assoc *pt; pt = hlist_entry(v, struct ax25_uid_assoc, uid_node); -seq_printf (seq,"%6d %s\n" , pt->uid,ax2asc (buf, &pt->call)); +seq_printf (seq,"%6d %s\n" , +from_kuid_munged (seq_user_ns (seq), pt->uid), +ax2asc (buf, &pt->call)); }return 0 ; }
Signature · 1 line
1.7.5.4
PATCH 11/21 netlink: Make the sending netlink socket availabe in NETLINK_CB
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
The sending socket of an skb is already available by it's port id in the NETLINK_CB. If you want to know more like to examine the credentials on the sending socket you have to look up the sending socket by it's port id and all of the needed functions and data structures are static inside of af_netlink.c. So do the simple thing and pass the sending socket to the receivers in the NETLINK_CB.
I intend to use this to get the user namespace of the sending socket in inet_diag so that I can report uids in the context of the process who opened the socket, the same way I report uids in the contect of the process who opens files.
--- include/linux/netlink.h | 1 + net/netlink/af_netlink.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-)
include/linux/netlink.h +1 -0
@@ -165,6 +165,7 @@ struct netlink_skb_parms {struct ucred creds;/* Skb credentials */ __u32 pid;__u32 dst_group; +struct sock *ssk; };#define NETLINK_CB (skb) (*(struct netlink_skb_parms*)&((skb)->cb))
net/netlink/af_netlink.c +4 -2
@@ -912,7 +912,8 @@ static void netlink_rcv_wake(struct sock *sk)wake_up_interruptible (&nlk->wait); } -static int netlink_unicast_kernel (struct sock *sk,struct sk_buff *skb) +static int netlink_unicast_kernel (struct sock *sk,struct sk_buff *skb, +struct sock *ssk) {int ret;struct netlink_sock *nlk =nlk_sk (sk);
@@ -921,6 +922,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb)if (nlk->netlink_rcv !=NULL ) { ret = skb->len;skb_set_owner_r (skb, sk); +NETLINK_CB (skb).ssk = ssk; nlk->netlink_rcv (skb);consume_skb (skb); }else {
@@ -947,7 +949,7 @@ retry:return PTR_ERR (sk); }if (netlink_is_kernel (sk)) -return netlink_unicast_kernel (sk, skb); +return netlink_unicast_kernel (sk, skb, ssk);if (sk_filter (sk, skb)) { err = skb->len;
Signature · 1 line
1.7.5.4
PATCH 12/21 userns: Implement sk_user_ns
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Add a helper sk_user_ns to make it easy to find the user namespace of the process that opened a socket.
--- include/net/sock.h | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
include/net/sock.h +9 -0
@@ -604,6 +604,15 @@ static inline void sk_add_bind_node(struct sock *sk,#define sk_for_each_bound (__sk, node, list) \ hlist_for_each_entry(__sk, node, list, sk_bind_node) +static inline struct user_namespace *sk_user_ns (struct sock *sk) +{ +/* Careful only use this in a context where these parameters +* can not change and must all be valid, such as recvmsg from +* userspace. +*/ +return sk->sk_socket->file->f_cred->user_ns; +} +/* Sock flags */ enum sock_flags {SOCK_DEAD ,
Signature · 1 line
1.7.5.4
PATCH 13/21 userns: Teach inet_diag to work with user namespaces
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Compute the user namespace of the socket that we are replying to and translate the kuids of reported sockets into that user namespace.
--- include/linux/inet_diag.h | 1 + init/Kconfig | 1 - net/ipv4/inet_diag.c | 21 +++++++++++++++------ net/ipv4/udp_diag.c | 5 ++++- 4 files changed, 20 insertions(+), 8 deletions(-)
include/linux/inet_diag.h +1 -0
@@ -159,6 +159,7 @@ struct inet_diag_handler {struct inet_connection_sock ;int inet_sk_diag_fill (struct sock *sk,struct inet_connection_sock *icsk,struct sk_buff *skb,struct inet_diag_req_v2 *req, +struct user_namespace *user_ns,u32 pid,u32 seq,u16 nlmsg_flags,const struct nlmsghdr *unlh); void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb,
init/Kconfig +0 -1
@@ -950,7 +950,6 @@ config UIDGID_CONVERTED depends on NETFILTER_NETLINK_LOG = n depends on AF_RXRPC = n depends on NET_KEY = n - depends on INET_DIAG = n depends on DNS_RESOLVER = n # Filesystems
net/ipv4/inet_diag.c +15 -6
@@ -69,6 +69,7 @@ static inline void inet_diag_unlock_handler(int inet_sk_diag_fill (struct sock *sk,struct inet_connection_sock *icsk,struct sk_buff *skb,struct inet_diag_req_v2 *req, +struct user_namespace *user_ns,u32 pid,u32 seq,u16 nlmsg_flags,const struct nlmsghdr *unlh) {
@@ -124,7 +125,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, }#endif - r->idiag_uid =sock_i_uid (sk); + r->idiag_uid =from_kuid_munged (user_ns,sock_i_uid (sk)); r->idiag_inode =sock_i_ino (sk);if (ext & (1 << (INET_DIAG_MEMINFO -1 ))) {
@@ -199,11 +200,12 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill);static int inet_csk_diag_fill (struct sock *sk,struct sk_buff *skb,struct inet_diag_req_v2 *req, +struct user_namespace *user_ns,u32 pid,u32 seq,u16 nlmsg_flags,const struct nlmsghdr *unlh) {return inet_sk_diag_fill (sk,inet_csk (sk), - skb, req, pid, seq, nlmsg_flags, unlh); + skb, req, user_ns, pid, seq, nlmsg_flags, unlh); } static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
@@ -256,14 +258,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, }static int sk_diag_fill (struct sock *sk,struct sk_buff *skb, -struct inet_diag_req_v2 *r,u32 pid,u32 seq,u16 nlmsg_flags, +struct inet_diag_req_v2 *r, +struct user_namespace *user_ns, +u32 pid,u32 seq,u16 nlmsg_flags,const struct nlmsghdr *unlh) {if (sk->sk_state ==TCP_TIME_WAIT )return inet_twsk_diag_fill ((struct inet_timewait_sock *)sk, skb, r, pid, seq, nlmsg_flags, unlh); -return inet_csk_diag_fill (sk, skb, r, pid, seq, nlmsg_flags, unlh); +return inet_csk_diag_fill (sk, skb, r, user_ns, pid, seq, nlmsg_flags, unlh); } int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
@@ -311,6 +315,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s } err =sk_diag_fill (sk, rep, req, +sk_user_ns (NETLINK_CB (in_skb).ssk),NETLINK_CB (in_skb).pid, nlh->nlmsg_seq,0 , nlh);if (err <0 ) {
@@ -551,6 +556,7 @@ static int inet_csk_diag_dump(struct sock *sk,return 0 ;return inet_csk_diag_fill (sk, skb, r, +sk_user_ns (NETLINK_CB (cb->skb).ssk),NETLINK_CB (cb->skb).pid, cb->nlh->nlmsg_seq,NLM_F_MULTI , cb->nlh); }
@@ -591,7 +597,9 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, }static int inet_diag_fill_req (struct sk_buff *skb,struct sock *sk, -struct request_sock *req,u32 pid,u32 seq, +struct request_sock *req, +struct user_namespace *user_ns, +u32 pid,u32 seq,const struct nlmsghdr *unlh) {const struct inet_request_sock *ireq =inet_rsk (req);
@@ -625,7 +633,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, r->idiag_expires =jiffies_to_msecs (tmo); r->idiag_rqueue =0 ; r->idiag_wqueue =0 ; - r->idiag_uid =sock_i_uid (sk); + r->idiag_uid =from_kuid_munged (user_ns,sock_i_uid (sk)); r->idiag_inode =0 ;#if IS_ENABLED (CONFIG_IPV6 )if (r->idiag_family ==AF_INET6 ) {
@@ -702,6 +710,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, } err =inet_diag_fill_req (skb, sk, req, +sk_user_ns (NETLINK_CB (cb->skb).ssk),NETLINK_CB (cb->skb).pid, cb->nlh->nlmsg_seq, cb->nlh);if (err <0 ) {
net/ipv4/udp_diag.c +4 -1
@@ -24,7 +24,9 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,if (!inet_diag_bc_sk (bc, sk))return 0 ; -return inet_sk_diag_fill (sk,NULL , skb, req,NETLINK_CB (cb->skb).pid, +return inet_sk_diag_fill (sk,NULL , skb, req, +sk_user_ns (NETLINK_CB (cb->skb).ssk), +NETLINK_CB (cb->skb).pid, cb->nlh->nlmsg_seq,NLM_F_MULTI , cb->nlh); }
@@ -69,6 +71,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, goto out; err =inet_sk_diag_fill (sk,NULL , rep, req, +sk_user_ns (NETLINK_CB (in_skb).ssk),NETLINK_CB (in_skb).pid, nlh->nlmsg_seq,0 , nlh);if (err <0 ) {
Signature · 1 line
1.7.5.4
Re: [PATCH 13/21] userns: Teach inet_diag to work with user namespaces
Quoted 9 lines · Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Compute the user namespace of the socket that we are replying to and translate the kuids of reported sockets into that user namespace.
Cc Andrew Vagin <[email protected]>Cc Pavel Emelyanov <[email protected]>Acked-by Serge Hallyn <[email protected]>
PATCH 14/21 userns: nfnetlink_log: Report socket uids in the log sockets user namespace
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
At logging instance creation capture the peer netlink socket's user namespace. Use the captured peer user namespace when reporting socket uids to the peer.
The peer socket's user namespace is guaranateed to be valid until the user closes the netlink socket. nfnetlink_log removes instances during the final close of a socket. __build_packet_message does not get called after an
instance is destroyed. Therefore it is safe to let the peer netlink socket
take care of the user namespace reference counting for us.
--- init/Kconfig | 1 - net/netfilter/nfnetlink_log.c | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-)
init/Kconfig +0 -1
@@ -947,7 +947,6 @@ config UIDGID_CONVERTED depends on NETFILTER_XT_MATCH_OWNER = n depends on NETFILTER_XT_MATCH_RECENT = n depends on NETFILTER_XT_TARGET_LOG = n - depends on NETFILTER_NETLINK_LOG = n depends on AF_RXRPC = n depends on NET_KEY = n depends on DNS_RESOLVER = n
net/netfilter/nfnetlink_log.c +10 -4
@@ -55,6 +55,7 @@ struct nfulnl_instance {unsigned int qlen;/* number of nlmsgs in skb */ struct sk_buff *skb;/* pre-allocatd skb */ struct timer_list timer; +struct user_namespace *peer_user_ns;/* User namespace of the peer process */ int peer_pid;/* PID of the peer process */ /* configurable parameters */
@@ -132,7 +133,7 @@ instance_put(struct nfulnl_instance *inst)static void nfulnl_timer (unsigned long data);static struct nfulnl_instance * -instance_create (u_int16_t group_num,int pid) +instance_create (u_int16_t group_num,int pid,struct user_namespace *user_ns) {struct nfulnl_instance *inst;int err;
@@ -162,6 +163,7 @@ instance_create(u_int16_t group_num, int pid)setup_timer (&inst->timer, nfulnl_timer, (unsigned long )inst); + inst->peer_user_ns = user_ns; inst->peer_pid = pid; inst->group_num = group_num;
@@ -503,8 +505,11 @@ __build_packet_message(struct nfulnl_instance *inst,read_lock_bh (&skb->sk->sk_callback_lock);if (skb->sk->sk_socket && skb->sk->sk_socket->file) {struct file *file = skb->sk->sk_socket->file; -__be32 uid =htonl (file->f_cred->fsuid); -__be32 gid =htonl (file->f_cred->fsgid); +__be32 uid =htonl (from_kuid_munged (inst->peer_user_ns, + file->f_cred->fsuid)); +__be32 gid =htonl (from_kgid_munged (inst->peer_user_ns, + file->f_cred->fsgid)); +/* need to unlock here since NLA_PUT may goto */ read_unlock_bh (&skb->sk->sk_callback_lock);if (nla_put_be32 (inst->skb,NFULA_UID , uid) ||nla_put_be32 (inst->skb,NFULA_GID , gid))
@@ -783,7 +788,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } inst =instance_create (group_num, -NETLINK_CB (skb).pid); +NETLINK_CB (skb).pid, +sk_user_ns (NETLINK_CB (skb).ssk));if (IS_ERR (inst)) { ret =PTR_ERR (inst); goto out;
Signature · 1 line
1.7.5.4
PATCH 15/21 net sched: Pass the skb into change so it can access NETLINK_CB
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
cls_flow.c plays with uids and gids. Unless I misread that code it is possible for classifiers to depend on the specific uid and gid values. Therefore I need to know the user namespace of the netlink socket that is installing the packet classifiers. Pass in the rtnetlink skb so I can access the NETLINK_CB of the passed packet. In particular I want access to sk_user_ns(NETLINK_CB(in_skb).ssk).
Pass in not the user namespace but the incomming rtnetlink skb into the the classifier change routines as that is generally the more useful parameter.
--- include/net/sch_generic.h | 3 ++- net/sched/cls_api.c | 2 +- net/sched/cls_basic.c | 3 ++- net/sched/cls_cgroup.c | 3 ++- net/sched/cls_flow.c | 3 ++- net/sched/cls_fw.c | 3 ++- net/sched/cls_route.c | 3 ++- net/sched/cls_rsvp.h | 3 ++- net/sched/cls_tcindex.c | 3 ++- net/sched/cls_u32.c | 3 ++- 10 files changed, 19 insertions(+), 10 deletions(-)
include/net/sch_generic.h +2 -1
@@ -188,7 +188,8 @@ struct tcf_proto_ops {unsigned long (*get)(struct tcf_proto *,u32 handle);void (*put)(struct tcf_proto *,unsigned long ); -int (*change)(struct tcf_proto *,unsigned long , +int (*change)(struct sk_buff *, +struct tcf_proto *,unsigned long ,u32 handle,struct nlattr **,unsigned long *);int (*delete)(struct tcf_proto *,unsigned long );
net/sched/cls_api.c +1 -1
@@ -319,7 +319,7 @@ replay: } } - err = tp->ops->change (tp, cl, t->tcm_handle, tca, &fh); + err = tp->ops->change (skb, tp, cl, t->tcm_handle, tca, &fh);if (err ==0 ) {if (tp_created) {spin_lock_bh (root_lock);
net/sched/cls_basic.c +2 -1
@@ -162,7 +162,8 @@ errout:return err; } -static int basic_change (struct tcf_proto *tp,unsigned long base,u32 handle, +static int basic_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg) {int err;
net/sched/cls_cgroup.c +2 -1
@@ -151,7 +151,8 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = { [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, }; -static int cls_cgroup_change (struct tcf_proto *tp,unsigned long base, +static int cls_cgroup_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg) {
net/sched/cls_flow.c +2 -1
@@ -347,7 +347,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) {
net/sched/cls_fw.c +2 -1
@@ -233,7 +233,8 @@ errout:return err; } -static int fw_change (struct tcf_proto *tp,unsigned long base, +static int fw_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg)
net/sched/cls_route.c +2 -1
@@ -427,7 +427,8 @@ errout:return err; } -static int route4_change (struct tcf_proto *tp,unsigned long base, +static int route4_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg)
net/sched/cls_rsvp.h +2 -1
@@ -416,7 +416,8 @@ static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, }; -static int rsvp_change (struct tcf_proto *tp,unsigned long base, +static int rsvp_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg)
net/sched/cls_tcindex.c +2 -1
@@ -332,7 +332,8 @@ errout: }static int -tcindex_change (struct tcf_proto *tp,unsigned long base,u32 handle, +tcindex_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg) {struct nlattr *opt = tca[TCA_OPTIONS ];
net/sched/cls_u32.c +2 -1
@@ -544,7 +544,8 @@ errout:return err; } -static int u32_change (struct tcf_proto *tp,unsigned long base,u32 handle, +static int u32_change (struct sk_buff *in_skb, +struct tcf_proto *tp,unsigned long base,u32 handle,struct nlattr **tca,unsigned long *arg) {
Signature · 1 line
1.7.5.4
Re: [PATCH 15/21] net sched: Pass the skb into change so it can access NETLINK_CB
Quoted 9 lines · Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
cls_flow.cplays with uids and gids. Unless I misread that code it is possible for classifiers to depend on the specific uid and gid values. Therefore I need to know the user namespace of the netlink socket that is installing the packet classifiers. Pass in the rtnetlink skb so I can access theNETLINK_CBof the passed packet. In particular I want access to sk_user_ns(NETLINK_CB(in_skb).ssk).
Quoted 7 lines
Pass in not the user namespace but the incomming rtnetlink skb into the the classifier change routines as that is generally the more useful parameter.
Cc Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/[email protected]>Acked-by Serge Hallyn <[email protected]>
cheers,
jamal
PATCH 16/21 userns: Convert cls_flow to work with user namespaces enabled
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
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.
--- init/Kconfig | 1 - net/sched/cls_flow.c | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-)
init/Kconfig +0 -1
@@ -943,7 +943,6 @@ config UIDGID_CONVERTED # Networking depends on NET_9P = n - depends on NET_CLS_FLOW = n depends on NETFILTER_XT_MATCH_OWNER = n depends on NETFILTER_XT_MATCH_RECENT = n depends on NETFILTER_XT_TARGET_LOG = n
net/sched/cls_flow.c +12 -4
@@ -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 ; }
@@ -387,6 +391,10 @@ static int flow_change(struct sk_buff *in_skb,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);
Signature · 1 line
1.7.5.4
PATCH 17/21 userns: Convert xt_LOG to print socket kuids and kgids as uids and gids
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
xt_LOG always writes messages via sb_add via printk. Therefore when xt_LOG logs the uid and gid of a socket a packet came from the values should be converted to be in the initial user namespace.
Thus making xt_LOG as user namespace safe as possible.
--- init/Kconfig | 1 - net/netfilter/xt_LOG.c | 16 ++++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-)
init/Kconfig +0 -1
@@ -945,7 +945,6 @@ config UIDGID_CONVERTED depends on NET_9P = n depends on NETFILTER_XT_MATCH_OWNER = n depends on NETFILTER_XT_MATCH_RECENT = n - depends on NETFILTER_XT_TARGET_LOG = n depends on AF_RXRPC = n depends on NET_KEY = n depends on DNS_RESOLVER = n
net/netfilter/xt_LOG.c +10 -6
@@ -363,10 +363,12 @@ static void dump_ipv4_packet(struct sbuff *m,/* Max length: 15 "UID=4294967295 " */ if ((logflags &XT_LOG_UID ) && !iphoff && skb->sk) {read_lock_bh (&skb->sk->sk_callback_lock); -if (skb->sk->sk_socket && skb->sk->sk_socket->file) +if (skb->sk->sk_socket && skb->sk->sk_socket->file) { +const struct cred *cred = skb->sk->sk_socket->file->f_cred;sb_add (m,"UID=%u GID=%u " , - skb->sk->sk_socket->file->f_cred->fsuid, - skb->sk->sk_socket->file->f_cred->fsgid); +from_kuid_munged (&init_user_ns, cred->fsuid), +from_kgid_munged (&init_user_ns, cred->fsgid)); + }read_unlock_bh (&skb->sk->sk_callback_lock); }
@@ -719,10 +721,12 @@ static void dump_ipv6_packet(struct sbuff *m,/* Max length: 15 "UID=4294967295 " */ if ((logflags &XT_LOG_UID ) && recurse && skb->sk) {read_lock_bh (&skb->sk->sk_callback_lock); -if (skb->sk->sk_socket && skb->sk->sk_socket->file) +if (skb->sk->sk_socket && skb->sk->sk_socket->file) { +const struct cred *cred = skb->sk->sk_socket->file->f_cred;sb_add (m,"UID=%u GID=%u " , - skb->sk->sk_socket->file->f_cred->fsuid, - skb->sk->sk_socket->file->f_cred->fsgid); +from_kuid_munged (&init_user_ns, cred->fsuid), +from_kgid_munged (&init_user_ns, cred->fsgid)); + }read_unlock_bh (&skb->sk->sk_callback_lock); }
Signature · 1 line
1.7.5.4
PATCH 18/21 userns xt_recent: Specify the owner/group of ip_list_perms in the initial user namespace
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
xt_recent creates a bunch of proc files and initializes their uid and gids to the values of ip_list_uid and ip_list_gid. When initialize those proc files convert those values to kuids so they can continue to reside on the /proc inode.
--- init/Kconfig | 1 - net/netfilter/xt_recent.c | 13 +++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-)
init/Kconfig +0 -1
@@ -944,7 +944,6 @@ config UIDGID_CONVERTED # Networking depends on NET_9P = n depends on NETFILTER_XT_MATCH_OWNER = n - depends on NETFILTER_XT_MATCH_RECENT = n depends on AF_RXRPC = n depends on NET_KEY = n depends on DNS_RESOLVER = n
net/netfilter/xt_recent.c +11 -2
@@ -317,6 +317,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par,struct recent_table *t;#ifdef CONFIG_PROC_FS struct proc_dir_entry *pde; +kuid_t uid; +kgid_t gid;#endif unsigned int i;int ret = -EINVAL ;
@@ -372,6 +374,13 @@ static int recent_mt_check(const struct xt_mtchk_param *par,for (i =0 ; i < ip_list_hash_size; i++)INIT_LIST_HEAD (&t->iphash[i]);#ifdef CONFIG_PROC_FS + uid =make_kuid (&init_user_ns, ip_list_uid); + gid =make_kgid (&init_user_ns, ip_list_gid); +if (!uid_valid (uid) || !gid_valid (gid)) { +kfree (t); + ret = -EINVAL ; + goto out; + } pde =proc_create_data (t->name, ip_list_perms, recent_net->xt_recent, &recent_mt_fops, t);if (pde ==NULL ) {
@@ -379,8 +388,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ret = -ENOMEM ; goto out; } - pde->uid = ip_list_uid; - pde->gid = ip_list_gid; + pde->uid = uid; + pde->gid = gid;#endif spin_lock_bh (&recent_lock);list_add_tail (&t->list, &recent_net->tables);
Signature · 1 line
1.7.5.4
PATCH 19/21 userns: xt_owner: Add basic user namespace support.
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
- Only allow adding matches from the initial user namespace
- Add the appropriate conversion functions to handle matches against sockets in other user namespaces.
--- init/Kconfig | 1 - net/netfilter/xt_owner.c | 30 ++++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-)
init/Kconfig +0 -1
@@ -943,7 +943,6 @@ config UIDGID_CONVERTED # Networking depends on NET_9P = n - depends on NETFILTER_XT_MATCH_OWNER = n depends on AF_RXRPC = n depends on NET_KEY = n depends on DNS_RESOLVER = n
net/netfilter/xt_owner.c +24 -6
@@ -17,6 +17,17 @@#include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_owner.h> +static int owner_check (const struct xt_mtchk_param *par) +{ +struct xt_owner_match_info *info = par->matchinfo; + +/* For now only allow adding matches from the initial user namespace */ +if ((info->match & (XT_OWNER_UID |XT_OWNER_GID )) && + (current_user_ns () != &init_user_ns)) +return -EINVAL ; +return 0 ; +} +static bool owner_mt (const struct sk_buff *skb,struct xt_action_param *par) {
@@ -37,17 +48,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)return ((info->match ^ info->invert) & (XT_OWNER_UID |XT_OWNER_GID )) ==0 ; -if (info->match &XT_OWNER_UID ) -if ((filp->f_cred->fsuid >= info->uid_min && - filp->f_cred->fsuid <= info->uid_max) ^ +if (info->match &XT_OWNER_UID ) { +kuid_t uid_min =make_kuid (&init_user_ns, info->uid_min); +kuid_t uid_max =make_kuid (&init_user_ns, info->uid_max); +if ((uid_gte (filp->f_cred->fsuid, uid_min) && +uid_lte (filp->f_cred->fsuid, uid_max)) ^ !(info->invert &XT_OWNER_UID ))return false; + } -if (info->match &XT_OWNER_GID ) -if ((filp->f_cred->fsgid >= info->gid_min && - filp->f_cred->fsgid <= info->gid_max) ^ +if (info->match &XT_OWNER_GID ) { +kgid_t gid_min =make_kgid (&init_user_ns, info->gid_min); +kgid_t gid_max =make_kgid (&init_user_ns, info->gid_max); +if ((gid_gte (filp->f_cred->fsgid, gid_min) && +gid_lte (filp->f_cred->fsgid, gid_max)) ^ !(info->invert &XT_OWNER_GID ))return false; + }return true; }
@@ -56,6 +73,7 @@ static struct xt_match owner_mt_reg __read_mostly = { .name = "owner", .revision = 1, .family = NFPROTO_UNSPEC, + .checkentry = owner_check, .match = owner_mt, .matchsize = sizeof(struct xt_owner_match_info), .hooks = (1 << NF_INET_LOCAL_OUT) |
Signature · 1 line
1.7.5.4
PATCH 20/21 userns: Make the airo wireless driver use kuids for proc uids and gids
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
--- drivers/net/wireless/airo.c | 48 +++++++++++++++++++++++++----------------- init/Kconfig | 2 - 2 files changed, 28 insertions(+), 22 deletions(-)
drivers/net/wireless/airo.c +28 -20
@@ -232,8 +232,10 @@ static int adhoc;static int probe =1 ; +static kuid_t proc_kuid;static int proc_uid/* = 0 */ ; +static kgid_t proc_kgid;static int proc_gid/* = 0 */ ;static int airo_perm =0555 ;
@@ -4499,78 +4501,79 @@ struct proc_data {static int setup_proc_entry (struct net_device *dev,struct airo_info *apriv ) {struct proc_dir_entry *entry; +/* First setup the device directory */ strcpy (apriv->proc_name,dev->name); apriv->proc_entry =proc_mkdir_mode (apriv->proc_name, airo_perm, airo_entry);if (!apriv->proc_entry) goto fail; - apriv->proc_entry->uid = proc_uid; - apriv->proc_entry->gid = proc_gid; + apriv->proc_entry->uid = proc_kuid; + apriv->proc_entry->gid = proc_kgid;/* Setup the StatsDelta */ entry =proc_create_data ("StatsDelta" ,S_IRUGO & proc_perm, apriv->proc_entry, &proc_statsdelta_ops, dev);if (!entry) goto fail_stats_delta; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the Stats */ entry =proc_create_data ("Stats" ,S_IRUGO & proc_perm, apriv->proc_entry, &proc_stats_ops, dev);if (!entry) goto fail_stats; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the Status */ entry =proc_create_data ("Status" ,S_IRUGO & proc_perm, apriv->proc_entry, &proc_status_ops, dev);if (!entry) goto fail_status; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the Config */ entry =proc_create_data ("Config" , proc_perm, apriv->proc_entry, &proc_config_ops, dev);if (!entry) goto fail_config; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the SSID */ entry =proc_create_data ("SSID" , proc_perm, apriv->proc_entry, &proc_SSID_ops, dev);if (!entry) goto fail_ssid; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the APList */ entry =proc_create_data ("APList" , proc_perm, apriv->proc_entry, &proc_APList_ops, dev);if (!entry) goto fail_aplist; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the BSSList */ entry =proc_create_data ("BSSList" , proc_perm, apriv->proc_entry, &proc_BSSList_ops, dev);if (!entry) goto fail_bsslist; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;/* Setup the WepKey */ entry =proc_create_data ("WepKey" , proc_perm, apriv->proc_entry, &proc_wepkey_ops, dev);if (!entry) goto fail_wepkey; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_kuid; + entry->gid = proc_kgid;return 0 ;
@@ -5697,11 +5700,16 @@ static int __init airo_init_module( void ) {int i; + proc_kuid =make_kuid (&init_user_ns, proc_uid); + proc_kgid =make_kgid (&init_user_ns, proc_gid); +if (!uid_valid (proc_kuid) || !gid_valid (proc_kgid)) +return -EINVAL ; + airo_entry =proc_mkdir_mode ("driver/aironet" , airo_perm,NULL );if (airo_entry) { - airo_entry->uid = proc_uid; - airo_entry->gid = proc_gid; + airo_entry->uid = proc_kuid; + airo_entry->gid = proc_kgid; }for (i =0 ; i <4 && io[i] && irq[i]; i++) {
init/Kconfig +0 -2
@@ -1003,8 +1003,6 @@ config UIDGID_CONVERTED depends on !UML || HOSTFS = n # The rare drivers that won't build - depends on AIRO = n - depends on AIRO_CS = n depends on TUN = n depends on INFINIBAND_QIB = n depends on BLK_DEV_LOOP = n
Signature · 1 line
1.7.5.4
PATCH 21/21 userns: Convert tun/tap to use kuid and kgid where appropriate
In reply to Eric W. BiedermanFrom: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
--- drivers/net/tun.c | 46 ++++++++++++++++++++++++++++++++-------------- init/Kconfig | 1 - 2 files changed, 32 insertions(+), 15 deletions(-)
drivers/net/tun.c +32 -14
@@ -120,8 +120,8 @@ struct tun_sock;struct tun_struct {struct tun_file *tfile;unsigned int flags; -uid_t owner; -gid_t group; +kuid_t owner; +kgid_t group;struct net_device *dev;netdev_features_t set_features;
@@ -1032,8 +1032,8 @@ static void tun_setup(struct net_device *dev) {struct tun_struct *tun =netdev_priv (dev); - tun->owner =-1 ; - tun->group =-1 ; + tun->owner =INVALID_UID ; + tun->group =INVALID_GID ; dev->ethtool_ops = &tun_ethtool_ops; dev->destructor = tun_free_netdev;
@@ -1156,14 +1156,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, char *buf) {struct tun_struct *tun =netdev_priv (to_net_dev (dev)); -return sprintf (buf,"%d\n" , tun->owner); +return uid_valid (tun->owner)? +sprintf (buf,"%u\n" , +from_kuid_munged (current_user_ns (), tun->owner)): +sprintf (buf,"-1\n" ); }static ssize_t tun_show_group (struct device *dev,struct device_attribute *attr,char *buf) {struct tun_struct *tun =netdev_priv (to_net_dev (dev)); -return sprintf (buf,"%d\n" , tun->group); +return gid_valid (tun->group) ? +sprintf (buf,"%u\n" , +from_kgid_munged (current_user_ns (), tun->group)): +sprintf (buf,"-1\n" ); } static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL);
@@ -1190,8 +1196,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)else return -EINVAL ; -if (((tun->owner !=-1 && cred->euid != tun->owner) || - (tun->group !=-1 && !in_egroup_p (tun->group))) && +if (((uid_valid (tun->owner) && !uid_eq (cred->euid, tun->owner)) || + (gid_valid (tun->group) && !in_egroup_p (tun->group))) && !capable (CAP_NET_ADMIN ))return -EPERM ; err =security_tun_dev_attach (tun->socket.sk);
@@ -1375,6 +1381,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,void __user * argp = (void __user *)arg;struct sock_fprog fprog;struct ifreq ifr; +kuid_t owner; +kgid_t group;int sndbuf;int vnet_hdr_sz;int ret;
@@ -1448,16 +1456,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,case TUNSETOWNER :/* Set owner of the device */ - tun->owner = (uid_t ) arg; - -tun_debug (KERN_INFO , tun,"owner set to %d\n" , tun->owner); + owner =make_kuid (current_user_ns (), arg); +if (!uid_valid (owner)) { + ret = -EINVAL ; +break ; + } + tun->owner = owner; +tun_debug (KERN_INFO , tun,"owner set to %d\n" , +from_kuid (&init_user_ns, tun->owner));break ;case TUNSETGROUP :/* Set group of the device */ - tun->group= (gid_t ) arg; - -tun_debug (KERN_INFO , tun,"group set to %d\n" , tun->group); + group =make_kgid (current_user_ns (), arg); +if (!gid_valid (group)) { + ret = -EINVAL ; +break ; + } + tun->group = group; +tun_debug (KERN_INFO , tun,"group set to %d\n" , +from_kgid (&init_user_ns, tun->group));break ;case TUNSETLINK :
init/Kconfig +0 -1
@@ -1003,7 +1003,6 @@ config UIDGID_CONVERTED depends on !UML || HOSTFS = n # The rare drivers that won't build - depends on TUN = n depends on INFINIBAND_QIB = n depends on BLK_DEV_LOOP = n depends on ANDROID_BINDER_IPC = n
Signature · 1 line
1.7.5.4
A message that is not in the archive (sent off-list or not yet received): 87ehnav9n5.fsf-aS9lmoZGLiVWk0Htik3J/[email protected]
David Miller
Acked-byFrom: ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected] (Eric W. Biederman)
Date: Mon, 13 Aug 2012 13:07:10 -0700
Quoted 12 lines
This is a modest set of changes against the current networking stack to enable basic user namespace support. Allowing the code to compile with user namespaces enabled and removing the assumption that there is only the initial user namespace.
Work to relax the privilege checks in the networking stack from "
capable(CAP_NET_ADMIN)" or "capable(CAP_NET_RAW)" to "ns_capable(net->user_ns, CAP_NET_ADMIN)" or "ns_capable(net->user_ns, CAP_NET_RAW)" allowing root in a user namespace to control a network namespace will come later.
Quoted 6 lines
David there are just enough interdependencies between the user namespace bits that I intend to merge them all through my user namespace tree. After the review is complete I will add these patches to my for-next branch of my user-namespace.git tree where I do not intend to rebase. If it make sense to pull these into net-next to avoid or reduce conflicts that should not be a problem.
Looks fine to me, you can add:
to all of this stuff. Let me know when something is stable in your tree, and I can therefore pull from it into net-next.
A message that is not in the archive (sent off-list or not yet received): 20120814.171203.1784557890475348401.davem-fT/PcQaiUtIeIZ0/[email protected]
Quoted 22 lines · David Miller
From: ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected] (Eric W. Biederman)
Date: Mon, 13 Aug 2012 13:07:10 -0700Quoted 12 lines
This is a modest set of changes against the current networking stack to enable basic user namespace support. Allowing the code to compile with user namespaces enabled and removing the assumption that there is only the initial user namespace.
Work to relax the privilege checks in the networking stack from "
capable(CAP_NET_ADMIN)" or "capable(CAP_NET_RAW)" to "ns_capable(net->user_ns, CAP_NET_ADMIN)" or "ns_capable(net->user_ns, CAP_NET_RAW)" allowing root in a user namespace to control a network namespace will come later.Quoted 6 lines
David there are just enough interdependencies between the user namespace bits that I intend to merge them all through my user namespace tree. After the review is complete I will add these patches to my for-next branch of my user-namespace.git tree where I do not intend to rebase. If it make sense to pull these into net-next to avoid or reduce conflicts that should not be a problem.
Quoted 6 lines
Looks fine to me, you can add:
to all of this stuff. Let me know when something is stable in your tree, and I can therefore pull from it into net-next.
Will do. It doesn't look like anyone has any problems with this stuff, so that should be shortly.
Eric
Quoted 22 lines · David Miller
From: ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected] (Eric W. Biederman)
Date: Mon, 13 Aug 2012 13:07:10 -0700Quoted 12 lines
This is a modest set of changes against the current networking stack to enable basic user namespace support. Allowing the code to compile with user namespaces enabled and removing the assumption that there is only the initial user namespace.
Work to relax the privilege checks in the networking stack from "
capable(CAP_NET_ADMIN)" or "capable(CAP_NET_RAW)" to "ns_capable(net->user_ns, CAP_NET_ADMIN)" or "ns_capable(net->user_ns, CAP_NET_RAW)" allowing root in a user namespace to control a network namespace will come later.Quoted 6 lines
David there are just enough interdependencies between the user namespace bits that I intend to merge them all through my user namespace tree. After the review is complete I will add these patches to my for-next branch of my user-namespace.git tree where I do not intend to rebase. If it make sense to pull these into net-next to avoid or reduce conflicts that should not be a problem.
Quoted 6 lines
Looks fine to me, you can add:
to all of this stuff. Let me know when something is stable in your tree, and I can therefore pull from it into net-next.
All of these patches + 2 others trivial userns bug fixes are now in my for-next branch at:
git.kernel.org:/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-next
I won't be rebasing that branch so feel free to merge it into net-next if you are so inclined. It will be a day or two before I get my next chunk of patches posted, reviewed and ready to join my for-next branch.
Eric
A message that is not in the archive (sent off-list or not yet received): 87boicfyo9.fsf-aS9lmoZGLiVWk0Htik3J/[email protected]
From: ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected] (Eric W. Biederman)
Date: Tue, 14 Aug 2012 23:37:42 -0700
Quoted 28 lines
Quoted 26 lines · David Miller
From: ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected] (Eric W. Biederman)
Date: Mon, 13 Aug 2012 13:07:10 -0700Quoted 12 lines
This is a modest set of changes against the current networking stack to enable basic user namespace support. Allowing the code to compile with user namespaces enabled and removing the assumption that there is only the initial user namespace.
Work to relax the privilege checks in the networking stack from "
capable(CAP_NET_ADMIN)" or "capable(CAP_NET_RAW)" to "ns_capable(net->user_ns, CAP_NET_ADMIN)" or "ns_capable(net->user_ns, CAP_NET_RAW)" allowing root in a user namespace to control a network namespace will come later.Quoted 6 lines
David there are just enough interdependencies between the user namespace bits that I intend to merge them all through my user namespace tree. After the review is complete I will add these patches to my for-next branch of my user-namespace.git tree where I do not intend to rebase. If it make sense to pull these into net-next to avoid or reduce conflicts that should not be a problem.
Looks fine to me, you can add:
Quoted 7 lines
Quoted 2 lines
to all of this stuff. Let me know when something is stable in your tree, and I can therefore pull from it into net-next.
All of these patches + 2 others trivial userns bug fixes are now in my for-next branch at:
git.kernel.org:/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-next
Ok I finally got around to pushing this into net-next, thanks.
A message that is not in the archive (sent off-list or not yet received): 20120824.214237.2157641321364380276.davem-fT/PcQaiUtIeIZ0/[email protected]
Quoted 6 lines · David Miller
Quoted 4 lines
All of these patches + 2 others trivial userns bug fixes are now in my for-next branch at:
git.kernel.org:/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-next
Ok I finally got around to pushing this into net-next, thanks.
Your timing is excellent.
I am just starting the ball rolling to get a bunch more changes in.
Eric
Quoted 22 lines · David Miller
From: [email protected] (Eric W. Biederman)
Date: Mon, 13 Aug 2012 13:07:10 -0700Quoted 12 lines
This is a modest set of changes against the current networking stack to enable basic user namespace support. Allowing the code to compile with user namespaces enabled and removing the assumption that there is only the initial user namespace.
Work to relax the privilege checks in the networking stack from "
capable(CAP_NET_ADMIN)" or "capable(CAP_NET_RAW)" to "ns_capable(net->user_ns, CAP_NET_ADMIN)" or "ns_capable(net->user_ns, CAP_NET_RAW)" allowing root in a user namespace to control a network namespace will come later.Quoted 6 lines
David there are just enough interdependencies between the user namespace bits that I intend to merge them all through my user namespace tree. After the review is complete I will add these patches to my for-next branch of my user-namespace.git tree where I do not intend to rebase. If it make sense to pull these into net-next to avoid or reduce conflicts that should not be a problem.
Quoted 6 lines
Looks fine to me, you can add:
Acked-by David S. Miller <[email protected]>to all of this stuff. Let me know when something is stable in your tree, and I can therefore pull from it into net-next.
Will do. It doesn't look like anyone has any problems with this stuff, so that should be shortly.
Eric