aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-08-24 18:54:37 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-24 18:54:37 -0400
commite6acb384807406c1a6ad3ddc91191f7658e63b7a (patch)
tree7906d1bb402ac30e4efaa1bc6451b1c7a4b6e768 /net/ipv6
parent255e87657a84e21986e5d9070f3dee4aa8d1d531 (diff)
parent898132ae76d1aeb52301f10e8795c34fbb54e853 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
This is an initial merge in of Eric Biederman's work to start adding user namespace support to the networking. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_flowlabel.c47
-rw-r--r--net/ipv6/raw.c3
-rw-r--r--net/ipv6/tcp_ipv6.c6
-rw-r--r--net/ipv6/udp.c3
4 files changed, 47 insertions, 12 deletions
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 9772fbd8a3f5..90bbefb57943 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/pid_namespace.h>
25 26
26#include <net/net_namespace.h> 27#include <net/net_namespace.h>
27#include <net/sock.h> 28#include <net/sock.h>
@@ -91,6 +92,8 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label)
91static void fl_free(struct ip6_flowlabel *fl) 92static void fl_free(struct ip6_flowlabel *fl)
92{ 93{
93 if (fl) { 94 if (fl) {
95 if (fl->share == IPV6_FL_S_PROCESS)
96 put_pid(fl->owner.pid);
94 release_net(fl->fl_net); 97 release_net(fl->fl_net);
95 kfree(fl->opt); 98 kfree(fl->opt);
96 } 99 }
@@ -394,10 +397,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
394 case IPV6_FL_S_ANY: 397 case IPV6_FL_S_ANY:
395 break; 398 break;
396 case IPV6_FL_S_PROCESS: 399 case IPV6_FL_S_PROCESS:
397 fl->owner = current->pid; 400 fl->owner.pid = get_task_pid(current, PIDTYPE_PID);
398 break; 401 break;
399 case IPV6_FL_S_USER: 402 case IPV6_FL_S_USER:
400 fl->owner = current_euid(); 403 fl->owner.uid = current_euid();
401 break; 404 break;
402 default: 405 default:
403 err = -EINVAL; 406 err = -EINVAL;
@@ -561,7 +564,10 @@ recheck:
561 err = -EPERM; 564 err = -EPERM;
562 if (fl1->share == IPV6_FL_S_EXCL || 565 if (fl1->share == IPV6_FL_S_EXCL ||
563 fl1->share != fl->share || 566 fl1->share != fl->share ||
564 fl1->owner != fl->owner) 567 ((fl1->share == IPV6_FL_S_PROCESS) &&
568 (fl1->owner.pid == fl->owner.pid)) ||
569 ((fl1->share == IPV6_FL_S_USER) &&
570 uid_eq(fl1->owner.uid, fl->owner.uid)))
565 goto release; 571 goto release;
566 572
567 err = -EINVAL; 573 err = -EINVAL;
@@ -621,6 +627,7 @@ done:
621 627
622struct ip6fl_iter_state { 628struct ip6fl_iter_state {
623 struct seq_net_private p; 629 struct seq_net_private p;
630 struct pid_namespace *pid_ns;
624 int bucket; 631 int bucket;
625}; 632};
626 633
@@ -699,6 +706,7 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v)
699 706
700static int ip6fl_seq_show(struct seq_file *seq, void *v) 707static int ip6fl_seq_show(struct seq_file *seq, void *v)
701{ 708{
709 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
702 if (v == SEQ_START_TOKEN) 710 if (v == SEQ_START_TOKEN)
703 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", 711 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
704 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); 712 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
@@ -708,7 +716,11 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
708 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", 716 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
709 (unsigned int)ntohl(fl->label), 717 (unsigned int)ntohl(fl->label),
710 fl->share, 718 fl->share,
711 (int)fl->owner, 719 ((fl->share == IPV6_FL_S_PROCESS) ?
720 pid_nr_ns(fl->owner.pid, state->pid_ns) :
721 ((fl->share == IPV6_FL_S_USER) ?
722 from_kuid_munged(seq_user_ns(seq), fl->owner.uid) :
723 0)),
712 atomic_read(&fl->users), 724 atomic_read(&fl->users),
713 fl->linger/HZ, 725 fl->linger/HZ,
714 (long)(fl->expires - jiffies)/HZ, 726 (long)(fl->expires - jiffies)/HZ,
@@ -727,8 +739,29 @@ static const struct seq_operations ip6fl_seq_ops = {
727 739
728static int ip6fl_seq_open(struct inode *inode, struct file *file) 740static int ip6fl_seq_open(struct inode *inode, struct file *file)
729{ 741{
730 return seq_open_net(inode, file, &ip6fl_seq_ops, 742 struct seq_file *seq;
731 sizeof(struct ip6fl_iter_state)); 743 struct ip6fl_iter_state *state;
744 int err;
745
746 err = seq_open_net(inode, file, &ip6fl_seq_ops,
747 sizeof(struct ip6fl_iter_state));
748
749 if (!err) {
750 seq = file->private_data;
751 state = ip6fl_seq_private(seq);
752 rcu_read_lock();
753 state->pid_ns = get_pid_ns(task_active_pid_ns(current));
754 rcu_read_unlock();
755 }
756 return err;
757}
758
759static int ip6fl_seq_release(struct inode *inode, struct file *file)
760{
761 struct seq_file *seq = file->private_data;
762 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
763 put_pid_ns(state->pid_ns);
764 return seq_release_net(inode, file);
732} 765}
733 766
734static const struct file_operations ip6fl_seq_fops = { 767static const struct file_operations ip6fl_seq_fops = {
@@ -736,7 +769,7 @@ static const struct file_operations ip6fl_seq_fops = {
736 .open = ip6fl_seq_open, 769 .open = ip6fl_seq_open,
737 .read = seq_read, 770 .read = seq_read,
738 .llseek = seq_lseek, 771 .llseek = seq_lseek,
739 .release = seq_release_net, 772 .release = ip6fl_seq_release,
740}; 773};
741 774
742static int __net_init ip6_flowlabel_proc_init(struct net *net) 775static int __net_init ip6_flowlabel_proc_init(struct net *net)
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ef0579d5bca6..7af88ef01657 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1251,7 +1251,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1251 sk_wmem_alloc_get(sp), 1251 sk_wmem_alloc_get(sp),
1252 sk_rmem_alloc_get(sp), 1252 sk_rmem_alloc_get(sp),
1253 0, 0L, 0, 1253 0, 0L, 0,
1254 sock_i_uid(sp), 0, 1254 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1255 0,
1255 sock_i_ino(sp), 1256 sock_i_ino(sp),
1256 atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); 1257 atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
1257} 1258}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index cd49de3678fb..f99b81d53cca 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1828,7 +1828,7 @@ static void tcp_v6_destroy_sock(struct sock *sk)
1828#ifdef CONFIG_PROC_FS 1828#ifdef CONFIG_PROC_FS
1829/* Proc filesystem TCPv6 sock list dumping. */ 1829/* Proc filesystem TCPv6 sock list dumping. */
1830static void get_openreq6(struct seq_file *seq, 1830static void get_openreq6(struct seq_file *seq,
1831 const struct sock *sk, struct request_sock *req, int i, int uid) 1831 const struct sock *sk, struct request_sock *req, int i, kuid_t uid)
1832{ 1832{
1833 int ttd = req->expires - jiffies; 1833 int ttd = req->expires - jiffies;
1834 const struct in6_addr *src = &inet6_rsk(req)->loc_addr; 1834 const struct in6_addr *src = &inet6_rsk(req)->loc_addr;
@@ -1852,7 +1852,7 @@ static void get_openreq6(struct seq_file *seq,
1852 1, /* timers active (only the expire timer) */ 1852 1, /* timers active (only the expire timer) */
1853 jiffies_to_clock_t(ttd), 1853 jiffies_to_clock_t(ttd),
1854 req->retrans, 1854 req->retrans,
1855 uid, 1855 from_kuid_munged(seq_user_ns(seq), uid),
1856 0, /* non standard timer */ 1856 0, /* non standard timer */
1857 0, /* open_requests have no inode */ 1857 0, /* open_requests have no inode */
1858 0, req); 1858 0, req);
@@ -1902,7 +1902,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1902 timer_active, 1902 timer_active,
1903 jiffies_delta_to_clock_t(timer_expires - jiffies), 1903 jiffies_delta_to_clock_t(timer_expires - jiffies),
1904 icsk->icsk_retransmits, 1904 icsk->icsk_retransmits,
1905 sock_i_uid(sp), 1905 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1906 icsk->icsk_probes_out, 1906 icsk->icsk_probes_out,
1907 sock_i_ino(sp), 1907 sock_i_ino(sp),
1908 atomic_read(&sp->sk_refcnt), sp, 1908 atomic_read(&sp->sk_refcnt), sp,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 99d0077b56b8..bbdff07eebe1 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1458,7 +1458,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
1458 sk_wmem_alloc_get(sp), 1458 sk_wmem_alloc_get(sp),
1459 sk_rmem_alloc_get(sp), 1459 sk_rmem_alloc_get(sp),
1460 0, 0L, 0, 1460 0, 0L, 0,
1461 sock_i_uid(sp), 0, 1461 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1462 0,
1462 sock_i_ino(sp), 1463 sock_i_ino(sp),
1463 atomic_read(&sp->sk_refcnt), sp, 1464 atomic_read(&sp->sk_refcnt), sp,
1464 atomic_read(&sp->sk_drops)); 1465 atomic_read(&sp->sk_drops));