Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 327226
b: refs/heads/master
c: 4f82f45
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman committed Aug 15, 2012
1 parent dd32346 commit efebeab
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7064d16e162adf8199f0288b694e6af823ed5431
refs/heads/master: 4f82f45730c68fdaf9b0472495a965188404866e
5 changes: 4 additions & 1 deletion trunk/include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion trunk/init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
50 changes: 43 additions & 7 deletions trunk/net/ipv6/ip6_flowlabel.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/pid_namespace.h>

#include <net/net_namespace.h>
#include <net/sock.h>
Expand Down Expand Up @@ -90,6 +91,11 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label)

static void fl_free(struct ip6_flowlabel *fl)
{
switch (fl->share) {
case IPV6_FL_S_PROCESS:
put_pid(fl->owner.pid);
break;
}
if (fl) {
release_net(fl->fl_net);
kfree(fl->opt);
Expand Down Expand Up @@ -394,10 +400,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
case IPV6_FL_S_ANY:
break;
case IPV6_FL_S_PROCESS:
fl->owner = current->pid;
fl->owner.pid = get_task_pid(current, PIDTYPE_PID);
break;
case IPV6_FL_S_USER:
fl->owner = current_euid();
fl->owner.uid = current_euid();
break;
default:
err = -EINVAL;
Expand Down Expand Up @@ -561,7 +567,10 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
err = -EPERM;
if (fl1->share == IPV6_FL_S_EXCL ||
fl1->share != fl->share ||
fl1->owner != fl->owner)
((fl1->share == IPV6_FL_S_PROCESS) &&
(fl1->owner.pid == fl->owner.pid)) ||
((fl1->share == IPV6_FL_S_USER) &&
uid_eq(fl1->owner.uid, fl->owner.uid)))
goto release;

err = -EINVAL;
Expand Down Expand Up @@ -621,6 +630,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)

struct ip6fl_iter_state {
struct seq_net_private p;
struct pid_namespace *pid_ns;
int bucket;
};

Expand Down Expand Up @@ -699,6 +709,7 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v)

static int ip6fl_seq_show(struct seq_file *seq, void *v)
{
struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
if (v == SEQ_START_TOKEN)
seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
"Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
Expand All @@ -708,7 +719,11 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
"%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
(unsigned int)ntohl(fl->label),
fl->share,
(int)fl->owner,
((fl->share == IPV6_FL_S_PROCESS) ?
pid_nr_ns(fl->owner.pid, state->pid_ns) :
((fl->share == IPV6_FL_S_USER) ?
from_kuid_munged(seq_user_ns(seq), fl->owner.uid) :
0)),
atomic_read(&fl->users),
fl->linger/HZ,
(long)(fl->expires - jiffies)/HZ,
Expand All @@ -727,16 +742,37 @@ static const struct seq_operations ip6fl_seq_ops = {

static int ip6fl_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &ip6fl_seq_ops,
sizeof(struct ip6fl_iter_state));
struct seq_file *seq;
struct ip6fl_iter_state *state;
int err;

err = seq_open_net(inode, file, &ip6fl_seq_ops,
sizeof(struct ip6fl_iter_state));

if (!err) {
seq = file->private_data;
state = ip6fl_seq_private(seq);
rcu_read_lock();
state->pid_ns = get_pid_ns(task_active_pid_ns(current));
rcu_read_unlock();
}
return err;
}

static int ip6fl_seq_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = file->private_data;
struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
put_pid_ns(state->pid_ns);
return seq_release_net(inode, file);
}

static const struct file_operations ip6fl_seq_fops = {
.owner = THIS_MODULE,
.open = ip6fl_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
.release = ip6fl_seq_release,
};

static int __net_init ip6_flowlabel_proc_init(struct net *net)
Expand Down

0 comments on commit efebeab

Please sign in to comment.