summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/devtmpfs.c4
-rw-r--r--drivers/block/loop.c4
-rw-r--r--drivers/connector/cn_proc.c18
-rw-r--r--drivers/gpu/drm/drm_fops.c3
-rw-r--r--drivers/gpu/drm/drm_info.c5
-rw-r--r--drivers/gpu/drm/drm_ioctl.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c4
-rw-r--r--drivers/net/tun.c46
-rw-r--r--drivers/net/wireless/airo.c48
-rw-r--r--drivers/staging/android/binder.c14
-rw-r--r--drivers/tty/tty_audit.c17
-rw-r--r--drivers/usb/gadget/f_fs.c23
-rw-r--r--drivers/usb/gadget/inode.c4
-rw-r--r--drivers/xen/xenfs/super.c3
14 files changed, 124 insertions, 73 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index deb4a456cf83..147d1a4dd269 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -309,8 +309,8 @@ static int handle_remove(const char *nodename, struct device *dev)
* before unlinking this node, reset permissions
* of possible references like hardlinks
*/
- newattrs.ia_uid = 0;
- newattrs.ia_gid = 0;
+ newattrs.ia_uid = GLOBAL_ROOT_UID;
+ newattrs.ia_gid = GLOBAL_ROOT_GID;
newattrs.ia_mode = stat.mode & ~0777;
newattrs.ia_valid =
ATTR_UID|ATTR_GID|ATTR_MODE;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 3bba65510d23..e9d594fd12cb 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1038,10 +1038,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
{
int err;
struct loop_func_table *xfer;
- uid_t uid = current_uid();
+ kuid_t uid = current_uid();
if (lo->lo_encrypt_key_size &&
- lo->lo_key_owner != uid &&
+ !uid_eq(lo->lo_key_owner, uid) &&
!capable(CAP_SYS_ADMIN))
return -EPERM;
if (lo->lo_state != Lo_bound)
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 3e92b7d3fcd2..fce2000eec31 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -30,6 +30,7 @@
#include <linux/gfp.h>
#include <linux/ptrace.h>
#include <linux/atomic.h>
+#include <linux/pid_namespace.h>
#include <asm/unaligned.h>
@@ -127,11 +128,11 @@ void proc_id_connector(struct task_struct *task, int which_id)
rcu_read_lock();
cred = __task_cred(task);
if (which_id == PROC_EVENT_UID) {
- ev->event_data.id.r.ruid = cred->uid;
- ev->event_data.id.e.euid = cred->euid;
+ ev->event_data.id.r.ruid = from_kuid_munged(&init_user_ns, cred->uid);
+ ev->event_data.id.e.euid = from_kuid_munged(&init_user_ns, cred->euid);
} else if (which_id == PROC_EVENT_GID) {
- ev->event_data.id.r.rgid = cred->gid;
- ev->event_data.id.e.egid = cred->egid;
+ ev->event_data.id.r.rgid = from_kgid_munged(&init_user_ns, cred->gid);
+ ev->event_data.id.e.egid = from_kgid_munged(&init_user_ns, cred->egid);
} else {
rcu_read_unlock();
return;
@@ -303,6 +304,15 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
if (msg->len != sizeof(*mc_op))
return;
+ /*
+ * Events are reported with respect to the initial pid
+ * and user namespaces so ignore requestors from
+ * other namespaces.
+ */
+ if ((current_user_ns() != &init_user_ns) ||
+ (task_active_pid_ns(current) != &init_pid_ns))
+ return;
+
mc_op = (enum proc_cn_mcast_op *)msg->data;
switch (*mc_op) {
case PROC_CN_MCAST_LISTEN:
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 5062eec673f1..433d2fad1fe6 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -251,7 +251,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
filp->private_data = priv;
priv->filp = filp;
priv->uid = current_euid();
- priv->pid = task_pid_nr(current);
+ priv->pid = get_pid(task_pid(current));
priv->minor = idr_find(&drm_minors_idr, minor_id);
priv->ioctl_count = 0;
/* for compatibility root is always authenticated */
@@ -524,6 +524,7 @@ int drm_release(struct inode *inode, struct file *filp)
if (drm_core_check_feature(dev, DRIVER_PRIME))
drm_prime_destroy_file_private(&file_priv->prime);
+ put_pid(file_priv->pid);
kfree(file_priv);
/* ========================================================
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 8928edbb94c7..eb0af393e6e2 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -191,8 +191,9 @@ int drm_clients_info(struct seq_file *m, void *data)
seq_printf(m, "%c %3d %5d %5d %10u %10lu\n",
priv->authenticated ? 'y' : 'n',
priv->minor->index,
- priv->pid,
- priv->uid, priv->magic, priv->ioctl_count);
+ pid_vnr(priv->pid),
+ from_kuid_munged(seq_user_ns(m), priv->uid),
+ priv->magic, priv->ioctl_count);
}
mutex_unlock(&dev->struct_mutex);
return 0;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 64a62c697313..39a43834cef9 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -215,8 +215,8 @@ int drm_getclient(struct drm_device *dev, void *data,
list_for_each_entry(pt, &dev->filelist, lhead) {
if (i++ >= idx) {
client->auth = pt->authenticated;
- client->pid = pt->pid;
- client->uid = pt->uid;
+ client->pid = pid_vnr(pt->pid);
+ client->uid = from_kuid_munged(current_user_ns(), pt->uid);
client->magic = pt->magic;
client->iocs = pt->ioctl_count;
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
index cff8a6c32161..65a2a23f6f8a 100644
--- a/drivers/infiniband/hw/qib/qib_fs.c
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -61,8 +61,8 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
inode->i_ino = get_next_ino();
inode->i_mode = mode;
- inode->i_uid = 0;
- inode->i_gid = 0;
+ inode->i_uid = GLOBAL_ROOT_UID;
+ inode->i_gid = GLOBAL_ROOT_GID;
inode->i_blocks = 0;
inode->i_atime = CURRENT_TIME;
inode->i_mtime = inode->i_atime;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 9336b829cc81..0873cdcf39be 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -121,8 +121,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:
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index f9f15bb3f03a..c586f78c307f 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -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++) {
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index a807129c7b5a..b1937ca13575 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -47,7 +47,7 @@ static HLIST_HEAD(binder_dead_nodes);
static struct dentry *binder_debugfs_dir_entry_root;
static struct dentry *binder_debugfs_dir_entry_proc;
static struct binder_node *binder_context_mgr_node;
-static uid_t binder_context_mgr_uid = -1;
+static kuid_t binder_context_mgr_uid = INVALID_UID;
static int binder_last_id;
static struct workqueue_struct *binder_deferred_workqueue;
@@ -356,7 +356,7 @@ struct binder_transaction {
unsigned int flags;
long priority;
long saved_priority;
- uid_t sender_euid;
+ kuid_t sender_euid;
};
static void
@@ -2427,7 +2427,7 @@ retry:
}
tr.code = t->code;
tr.flags = t->flags;
- tr.sender_euid = t->sender_euid;
+ tr.sender_euid = from_kuid(current_user_ns(), t->sender_euid);
if (t->from) {
struct task_struct *sender = t->from->proc->tsk;
@@ -2705,12 +2705,12 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
ret = -EBUSY;
goto err;
}
- if (binder_context_mgr_uid != -1) {
- if (binder_context_mgr_uid != current->cred->euid) {
+ if (uid_valid(binder_context_mgr_uid)) {
+ if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) {
pr_err("binder: BINDER_SET_"
"CONTEXT_MGR bad uid %d != %d\n",
- current->cred->euid,
- binder_context_mgr_uid);
+ from_kuid(&init_user_ns, current->cred->euid),
+ from_kuid(&init_user_ns, binder_context_mgr_uid));
ret = -EPERM;
goto err;
}
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index 7c5866920622..b0b39b823ccf 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -61,7 +61,7 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
}
static void tty_audit_log(const char *description, struct task_struct *tsk,
- uid_t loginuid, unsigned sessionid, int major,
+ kuid_t loginuid, unsigned sessionid, int major,
int minor, unsigned char *data, size_t size)
{
struct audit_buffer *ab;
@@ -69,11 +69,14 @@ static void tty_audit_log(const char *description, struct task_struct *tsk,
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
if (ab) {
char name[sizeof(tsk->comm)];
- uid_t uid = task_uid(tsk);
+ kuid_t uid = task_uid(tsk);
audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
"major=%d minor=%d comm=", description,
- tsk->pid, uid, loginuid, sessionid,
+ tsk->pid,
+ from_kuid(&init_user_ns, uid),
+ from_kuid(&init_user_ns, loginuid),
+ sessionid,
major, minor);
get_task_comm(name, tsk);
audit_log_untrustedstring(ab, name);
@@ -89,7 +92,7 @@ static void tty_audit_log(const char *description, struct task_struct *tsk,
* Generate an audit message from the contents of @buf, which is owned by
* @tsk with @loginuid. @buf->mutex must be locked.
*/
-static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
+static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid,
unsigned int sessionid,
struct tty_audit_buf *buf)
{
@@ -112,7 +115,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
*/
static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
{
- uid_t auid = audit_get_loginuid(current);
+ kuid_t auid = audit_get_loginuid(current);
unsigned int sessionid = audit_get_sessionid(current);
tty_audit_buf_push(current, auid, sessionid, buf);
}
@@ -179,7 +182,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
}
if (should_audit && audit_enabled) {
- uid_t auid;
+ kuid_t auid;
unsigned int sessionid;
auid = audit_get_loginuid(current);
@@ -199,7 +202,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
* reference to the tty audit buffer if available.
* Flush the buffer or return an appropriate error code.
*/
-int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
+int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid)
{
struct tty_audit_buf *buf = ERR_PTR(-EPERM);
unsigned long flags;
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 829aba75a6df..a26c43a151fd 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -224,8 +224,8 @@ struct ffs_data {
/* File permissions, written once when fs is mounted */
struct ffs_file_perms {
umode_t mode;
- uid_t uid;
- gid_t gid;
+ kuid_t uid;
+ kgid_t gid;
} file_perms;
/*
@@ -1147,10 +1147,19 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
break;
case 3:
- if (!memcmp(opts, "uid", 3))
- data->perms.uid = value;
+ if (!memcmp(opts, "uid", 3)) {
+ data->perms.uid = make_kuid(current_user_ns(), value);
+ if (!uid_valid(data->perms.uid)) {
+ pr_err("%s: unmapped value: %lu\n", opts, value);
+ return -EINVAL;
+ }
+ }
else if (!memcmp(opts, "gid", 3))
- data->perms.gid = value;
+ data->perms.gid = make_kgid(current_user_ns(), value);
+ if (!gid_valid(data->perms.gid)) {
+ pr_err("%s: unmapped value: %lu\n", opts, value);
+ return -EINVAL;
+ }
else
goto invalid;
break;
@@ -1179,8 +1188,8 @@ ffs_fs_mount(struct file_system_type *t, int flags,
struct ffs_sb_fill_data data = {
.perms = {
.mode = S_IFREG | 0600,
- .uid = 0,
- .gid = 0
+ .uid = GLOBAL_ROOT_UID,
+ .gid = GLOBAL_ROOT_GID,
},
.root_mode = S_IFDIR | 0500,
};
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 4bb6d53f2de3..76494cabf4e4 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1985,8 +1985,8 @@ gadgetfs_make_inode (struct super_block *sb,
if (inode) {
inode->i_ino = get_next_ino();
inode->i_mode = mode;
- inode->i_uid = default_uid;
- inode->i_gid = default_gid;
+ inode->i_uid = make_kuid(&init_user_ns, default_uid);
+ inode->i_gid = make_kgid(&init_user_ns, default_gid);
inode->i_atime = inode->i_mtime = inode->i_ctime
= CURRENT_TIME;
inode->i_private = data;
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
index a84b53c01436..459b9ac45cf5 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -30,7 +30,8 @@ static struct inode *xenfs_make_inode(struct super_block *sb, int mode)
if (ret) {
ret->i_mode = mode;
- ret->i_uid = ret->i_gid = 0;
+ ret->i_uid = GLOBAL_ROOT_UID;
+ ret->i_gid = GLOBAL_ROOT_GID;
ret->i_blocks = 0;
ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
}