Skip to content

Commit

Permalink
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…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 <[email protected]>
  • Loading branch information
davem330 committed Aug 24, 2012
2 parents 255e876 + 898132a commit e6acb38
Show file tree
Hide file tree
Showing 52 changed files with 368 additions and 180 deletions.
46 changes: 32 additions & 14 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1031,8 +1031,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;
Expand Down Expand Up @@ -1155,14 +1155,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);
Expand All @@ -1189,8 +1195,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);
Expand Down Expand Up @@ -1374,6 +1380,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;
Expand Down Expand Up @@ -1447,16 +1455,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:
Expand Down
48 changes: 28 additions & 20 deletions drivers/net/wireless/airo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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++) {
Expand Down
6 changes: 3 additions & 3 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd)

/* Allowed if owner and follower match. */
inode = link->dentry->d_inode;
if (current_cred()->fsuid == inode->i_uid)
if (uid_eq(current_cred()->fsuid, inode->i_uid))
return 0;

/* Allowed if parent directory not sticky and world-writable. */
Expand All @@ -687,7 +687,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd)
return 0;

/* Allowed if parent directory and link owner match. */
if (parent->i_uid == inode->i_uid)
if (uid_eq(parent->i_uid, inode->i_uid))
return 0;

path_put_conditional(link, nd);
Expand Down Expand Up @@ -757,7 +757,7 @@ static int may_linkat(struct path *link)
/* Source inode owner (or CAP_FOWNER) can hardlink all they like,
* otherwise, it must be a safe source.
*/
if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) ||
if (uid_eq(cred->fsuid, inode->i_uid) || safe_hardlink_source(inode) ||
capable(CAP_FOWNER))
return 0;

Expand Down
4 changes: 4 additions & 0 deletions fs/seq_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/linux/inet_diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions include/linux/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
14 changes: 14 additions & 0 deletions include/linux/seq_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct file;
struct path;
struct inode;
struct dentry;
struct user_namespace;

struct seq_file {
char *buf;
Expand All @@ -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;
};

Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions include/net/ax25.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,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
3 changes: 2 additions & 1 deletion include/net/netns/ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion include/net/sch_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit e6acb38

Please sign in to comment.