aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h5
-rw-r--r--init/Kconfig1
-rw-r--r--kernel/pid.c1
-rw-r--r--net/ipv6/ip6_flowlabel.c50
4 files changed, 48 insertions, 9 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 01c34b363a34..c8a202436e01 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -222,7 +222,10 @@ struct ip6_flowlabel {
222 struct ipv6_txoptions *opt; 222 struct ipv6_txoptions *opt;
223 unsigned long linger; 223 unsigned long linger;
224 u8 share; 224 u8 share;
225 u32 owner; 225 union {
226 struct pid *pid;
227 kuid_t uid;
228 } owner;
226 unsigned long lastuse; 229 unsigned long lastuse;
227 unsigned long expires; 230 unsigned long expires;
228 struct net *fl_net; 231 struct net *fl_net;
diff --git a/init/Kconfig b/init/Kconfig
index f857f97bcef3..64ff9ce59443 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -948,7 +948,6 @@ config UIDGID_CONVERTED
948 depends on NETFILTER_XT_MATCH_RECENT = n 948 depends on NETFILTER_XT_MATCH_RECENT = n
949 depends on NETFILTER_XT_TARGET_LOG = n 949 depends on NETFILTER_XT_TARGET_LOG = n
950 depends on NETFILTER_NETLINK_LOG = n 950 depends on NETFILTER_NETLINK_LOG = n
951 depends on IPV6 = n
952 depends on AF_RXRPC = n 951 depends on AF_RXRPC = n
953 depends on NET_KEY = n 952 depends on NET_KEY = n
954 depends on INET_DIAG = n 953 depends on INET_DIAG = n
diff --git a/kernel/pid.c b/kernel/pid.c
index e86b291ad834..aebd4f5aaf41 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -479,6 +479,7 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
479 } 479 }
480 return nr; 480 return nr;
481} 481}
482EXPORT_SYMBOL_GPL(pid_nr_ns);
482 483
483pid_t pid_vnr(struct pid *pid) 484pid_t pid_vnr(struct pid *pid)
484{ 485{
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 9772fbd8a3f5..c836a6a20a34 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>
@@ -90,6 +91,11 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label)
90 91
91static void fl_free(struct ip6_flowlabel *fl) 92static void fl_free(struct ip6_flowlabel *fl)
92{ 93{
94 switch (fl->share) {
95 case IPV6_FL_S_PROCESS:
96 put_pid(fl->owner.pid);
97 break;
98 }
93 if (fl) { 99 if (fl) {
94 release_net(fl->fl_net); 100 release_net(fl->fl_net);
95 kfree(fl->opt); 101 kfree(fl->opt);
@@ -394,10 +400,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
394 case IPV6_FL_S_ANY: 400 case IPV6_FL_S_ANY:
395 break; 401 break;
396 case IPV6_FL_S_PROCESS: 402 case IPV6_FL_S_PROCESS:
397 fl->owner = current->pid; 403 fl->owner.pid = get_task_pid(current, PIDTYPE_PID);
398 break; 404 break;
399 case IPV6_FL_S_USER: 405 case IPV6_FL_S_USER:
400 fl->owner = current_euid(); 406 fl->owner.uid = current_euid();
401 break; 407 break;
402 default: 408 default:
403 err = -EINVAL; 409 err = -EINVAL;
@@ -561,7 +567,10 @@ recheck:
561 err = -EPERM; 567 err = -EPERM;
562 if (fl1->share == IPV6_FL_S_EXCL || 568 if (fl1->share == IPV6_FL_S_EXCL ||
563 fl1->share != fl->share || 569 fl1->share != fl->share ||
564 fl1->owner != fl->owner) 570 ((fl1->share == IPV6_FL_S_PROCESS) &&
571 (fl1->owner.pid == fl->owner.pid)) ||
572 ((fl1->share == IPV6_FL_S_USER) &&
573 uid_eq(fl1->owner.uid, fl->owner.uid)))
565 goto release; 574 goto release;
566 575
567 err = -EINVAL; 576 err = -EINVAL;
@@ -621,6 +630,7 @@ done:
621 630
622struct ip6fl_iter_state { 631struct ip6fl_iter_state {
623 struct seq_net_private p; 632 struct seq_net_private p;
633 struct pid_namespace *pid_ns;
624 int bucket; 634 int bucket;
625}; 635};
626 636
@@ -699,6 +709,7 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v)
699 709
700static int ip6fl_seq_show(struct seq_file *seq, void *v) 710static int ip6fl_seq_show(struct seq_file *seq, void *v)
701{ 711{
712 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
702 if (v == SEQ_START_TOKEN) 713 if (v == SEQ_START_TOKEN)
703 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", 714 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
704 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); 715 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
@@ -708,7 +719,11 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
708 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", 719 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
709 (unsigned int)ntohl(fl->label), 720 (unsigned int)ntohl(fl->label),
710 fl->share, 721 fl->share,
711 (int)fl->owner, 722 ((fl->share == IPV6_FL_S_PROCESS) ?
723 pid_nr_ns(fl->owner.pid, state->pid_ns) :
724 ((fl->share == IPV6_FL_S_USER) ?
725 from_kuid_munged(seq_user_ns(seq), fl->owner.uid) :
726 0)),
712 atomic_read(&fl->users), 727 atomic_read(&fl->users),
713 fl->linger/HZ, 728 fl->linger/HZ,
714 (long)(fl->expires - jiffies)/HZ, 729 (long)(fl->expires - jiffies)/HZ,
@@ -727,8 +742,29 @@ static const struct seq_operations ip6fl_seq_ops = {
727 742
728static int ip6fl_seq_open(struct inode *inode, struct file *file) 743static int ip6fl_seq_open(struct inode *inode, struct file *file)
729{ 744{
730 return seq_open_net(inode, file, &ip6fl_seq_ops, 745 struct seq_file *seq;
731 sizeof(struct ip6fl_iter_state)); 746 struct ip6fl_iter_state *state;
747 int err;
748
749 err = seq_open_net(inode, file, &ip6fl_seq_ops,
750 sizeof(struct ip6fl_iter_state));
751
752 if (!err) {
753 seq = file->private_data;
754 state = ip6fl_seq_private(seq);
755 rcu_read_lock();
756 state->pid_ns = get_pid_ns(task_active_pid_ns(current));
757 rcu_read_unlock();
758 }
759 return err;
760}
761
762static int ip6fl_seq_release(struct inode *inode, struct file *file)
763{
764 struct seq_file *seq = file->private_data;
765 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
766 put_pid_ns(state->pid_ns);
767 return seq_release_net(inode, file);
732} 768}
733 769
734static const struct file_operations ip6fl_seq_fops = { 770static const struct file_operations ip6fl_seq_fops = {
@@ -736,7 +772,7 @@ static const struct file_operations ip6fl_seq_fops = {
736 .open = ip6fl_seq_open, 772 .open = ip6fl_seq_open,
737 .read = seq_read, 773 .read = seq_read,
738 .llseek = seq_lseek, 774 .llseek = seq_lseek,
739 .release = seq_release_net, 775 .release = ip6fl_seq_release,
740}; 776};
741 777
742static int __net_init ip6_flowlabel_proc_init(struct net *net) 778static int __net_init ip6_flowlabel_proc_init(struct net *net)