aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/acl.c4
-rw-r--r--fs/fuse/cuse.c7
-rw-r--r--fs/fuse/dev.c8
-rw-r--r--fs/fuse/dir.c14
-rw-r--r--fs/fuse/fuse_i.h6
-rw-r--r--fs/fuse/inode.c31
6 files changed, 43 insertions, 27 deletions
diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c
index ec85765502f1..5a48cee6d7d3 100644
--- a/fs/fuse/acl.c
+++ b/fs/fuse/acl.c
@@ -34,7 +34,7 @@ struct posix_acl *fuse_get_acl(struct inode *inode, int type)
34 return ERR_PTR(-ENOMEM); 34 return ERR_PTR(-ENOMEM);
35 size = fuse_getxattr(inode, name, value, PAGE_SIZE); 35 size = fuse_getxattr(inode, name, value, PAGE_SIZE);
36 if (size > 0) 36 if (size > 0)
37 acl = posix_acl_from_xattr(&init_user_ns, value, size); 37 acl = posix_acl_from_xattr(fc->user_ns, value, size);
38 else if ((size == 0) || (size == -ENODATA) || 38 else if ((size == 0) || (size == -ENODATA) ||
39 (size == -EOPNOTSUPP && fc->no_getxattr)) 39 (size == -EOPNOTSUPP && fc->no_getxattr))
40 acl = NULL; 40 acl = NULL;
@@ -81,7 +81,7 @@ int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type)
81 if (!value) 81 if (!value)
82 return -ENOMEM; 82 return -ENOMEM;
83 83
84 ret = posix_acl_to_xattr(&init_user_ns, acl, value, size); 84 ret = posix_acl_to_xattr(fc->user_ns, acl, value, size);
85 if (ret < 0) { 85 if (ret < 0) {
86 kfree(value); 86 kfree(value);
87 return ret; 87 return ret;
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 31d33b69957f..8f68181256c0 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -48,6 +48,7 @@
48#include <linux/stat.h> 48#include <linux/stat.h>
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/uio.h> 50#include <linux/uio.h>
51#include <linux/user_namespace.h>
51 52
52#include "fuse_i.h" 53#include "fuse_i.h"
53 54
@@ -498,7 +499,11 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
498 if (!cc) 499 if (!cc)
499 return -ENOMEM; 500 return -ENOMEM;
500 501
501 fuse_conn_init(&cc->fc); 502 /*
503 * Limit the cuse channel to requests that can
504 * be represented in file->f_cred->user_ns.
505 */
506 fuse_conn_init(&cc->fc, file->f_cred->user_ns);
502 507
503 fud = fuse_dev_alloc(&cc->fc); 508 fud = fuse_dev_alloc(&cc->fc);
504 if (!fud) { 509 if (!fud) {
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 4852f8803156..686631f12001 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -156,8 +156,8 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
156 goto out; 156 goto out;
157 } 157 }
158 158
159 req->in.h.uid = from_kuid(&init_user_ns, current_fsuid()); 159 req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
160 req->in.h.gid = from_kgid(&init_user_ns, current_fsgid()); 160 req->in.h.gid = from_kgid(fc->user_ns, current_fsgid());
161 req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); 161 req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
162 162
163 __set_bit(FR_WAITING, &req->flags); 163 __set_bit(FR_WAITING, &req->flags);
@@ -257,8 +257,8 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
257 if (!req) 257 if (!req)
258 req = get_reserved_req(fc, file); 258 req = get_reserved_req(fc, file);
259 259
260 req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid()); 260 req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
261 req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid()); 261 req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
262 req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); 262 req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
263 263
264 __set_bit(FR_WAITING, &req->flags); 264 __set_bit(FR_WAITING, &req->flags);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 7a980b4462d9..cf8a1cd7a62e 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -858,8 +858,8 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
858 stat->ino = attr->ino; 858 stat->ino = attr->ino;
859 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); 859 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
860 stat->nlink = attr->nlink; 860 stat->nlink = attr->nlink;
861 stat->uid = make_kuid(&init_user_ns, attr->uid); 861 stat->uid = make_kuid(fc->user_ns, attr->uid);
862 stat->gid = make_kgid(&init_user_ns, attr->gid); 862 stat->gid = make_kgid(fc->user_ns, attr->gid);
863 stat->rdev = inode->i_rdev; 863 stat->rdev = inode->i_rdev;
864 stat->atime.tv_sec = attr->atime; 864 stat->atime.tv_sec = attr->atime;
865 stat->atime.tv_nsec = attr->atimensec; 865 stat->atime.tv_nsec = attr->atimensec;
@@ -1475,17 +1475,17 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
1475 return true; 1475 return true;
1476} 1476}
1477 1477
1478static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, 1478static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1479 bool trust_local_cmtime) 1479 struct fuse_setattr_in *arg, bool trust_local_cmtime)
1480{ 1480{
1481 unsigned ivalid = iattr->ia_valid; 1481 unsigned ivalid = iattr->ia_valid;
1482 1482
1483 if (ivalid & ATTR_MODE) 1483 if (ivalid & ATTR_MODE)
1484 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode; 1484 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
1485 if (ivalid & ATTR_UID) 1485 if (ivalid & ATTR_UID)
1486 arg->valid |= FATTR_UID, arg->uid = from_kuid(&init_user_ns, iattr->ia_uid); 1486 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
1487 if (ivalid & ATTR_GID) 1487 if (ivalid & ATTR_GID)
1488 arg->valid |= FATTR_GID, arg->gid = from_kgid(&init_user_ns, iattr->ia_gid); 1488 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
1489 if (ivalid & ATTR_SIZE) 1489 if (ivalid & ATTR_SIZE)
1490 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; 1490 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
1491 if (ivalid & ATTR_ATIME) { 1491 if (ivalid & ATTR_ATIME) {
@@ -1657,7 +1657,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1657 1657
1658 memset(&inarg, 0, sizeof(inarg)); 1658 memset(&inarg, 0, sizeof(inarg));
1659 memset(&outarg, 0, sizeof(outarg)); 1659 memset(&outarg, 0, sizeof(outarg));
1660 iattr_to_fattr(attr, &inarg, trust_local_cmtime); 1660 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
1661 if (file) { 1661 if (file) {
1662 struct fuse_file *ff = file->private_data; 1662 struct fuse_file *ff = file->private_data;
1663 inarg.valid |= FATTR_FH; 1663 inarg.valid |= FATTR_FH;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 7d2e7deea64b..f630951df8dc 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -26,6 +26,7 @@
26#include <linux/xattr.h> 26#include <linux/xattr.h>
27#include <linux/pid_namespace.h> 27#include <linux/pid_namespace.h>
28#include <linux/refcount.h> 28#include <linux/refcount.h>
29#include <linux/user_namespace.h>
29 30
30/** Max number of pages that can be used in a single read request */ 31/** Max number of pages that can be used in a single read request */
31#define FUSE_MAX_PAGES_PER_REQ 32 32#define FUSE_MAX_PAGES_PER_REQ 32
@@ -466,6 +467,9 @@ struct fuse_conn {
466 /** The pid namespace for this mount */ 467 /** The pid namespace for this mount */
467 struct pid_namespace *pid_ns; 468 struct pid_namespace *pid_ns;
468 469
470 /** The user namespace for this mount */
471 struct user_namespace *user_ns;
472
469 /** Maximum read size */ 473 /** Maximum read size */
470 unsigned max_read; 474 unsigned max_read;
471 475
@@ -876,7 +880,7 @@ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
876/** 880/**
877 * Initialize fuse_conn 881 * Initialize fuse_conn
878 */ 882 */
879void fuse_conn_init(struct fuse_conn *fc); 883void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns);
880 884
881/** 885/**
882 * Release reference to fuse_conn 886 * Release reference to fuse_conn
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 3c9b675d99da..1643043d4fe5 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -171,8 +171,8 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
171 inode->i_ino = fuse_squash_ino(attr->ino); 171 inode->i_ino = fuse_squash_ino(attr->ino);
172 inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); 172 inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
173 set_nlink(inode, attr->nlink); 173 set_nlink(inode, attr->nlink);
174 inode->i_uid = make_kuid(&init_user_ns, attr->uid); 174 inode->i_uid = make_kuid(fc->user_ns, attr->uid);
175 inode->i_gid = make_kgid(&init_user_ns, attr->gid); 175 inode->i_gid = make_kgid(fc->user_ns, attr->gid);
176 inode->i_blocks = attr->blocks; 176 inode->i_blocks = attr->blocks;
177 inode->i_atime.tv_sec = attr->atime; 177 inode->i_atime.tv_sec = attr->atime;
178 inode->i_atime.tv_nsec = attr->atimensec; 178 inode->i_atime.tv_nsec = attr->atimensec;
@@ -477,7 +477,8 @@ static int fuse_match_uint(substring_t *s, unsigned int *res)
477 return err; 477 return err;
478} 478}
479 479
480static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) 480static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,
481 struct user_namespace *user_ns)
481{ 482{
482 char *p; 483 char *p;
483 memset(d, 0, sizeof(struct fuse_mount_data)); 484 memset(d, 0, sizeof(struct fuse_mount_data));
@@ -513,7 +514,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
513 case OPT_USER_ID: 514 case OPT_USER_ID:
514 if (fuse_match_uint(&args[0], &uv)) 515 if (fuse_match_uint(&args[0], &uv))
515 return 0; 516 return 0;
516 d->user_id = make_kuid(current_user_ns(), uv); 517 d->user_id = make_kuid(user_ns, uv);
517 if (!uid_valid(d->user_id)) 518 if (!uid_valid(d->user_id))
518 return 0; 519 return 0;
519 d->user_id_present = 1; 520 d->user_id_present = 1;
@@ -522,7 +523,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)