aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 11:50:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 11:50:57 -0400
commitda315f6e03988a7127680bbc26e1028991b899b8 (patch)
treefc4a41dbb22ac0a7a2f683dc5c5c6789957ce5e8 /fs/fuse
parent1c8c5a9d38f607c0b6fd12c91cbe1a4418762a21 (diff)
parent543b8f8662fe6d21f19958b666ab0051af9db21a (diff)
Merge tag 'fuse-update-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi: "The most interesting part of this update is user namespace support, mostly done by Eric Biederman. This enables safe unprivileged fuse mounts within a user namespace. There are also a couple of fixes for bugs found by syzbot and miscellaneous fixes and cleanups" * tag 'fuse-update-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: don't keep dead fuse_conn at fuse_fill_super(). fuse: fix control dir setup and teardown fuse: fix congested state leak on aborted connections fuse: Allow fully unprivileged mounts fuse: Ensure posix acls are translated outside of init_user_ns fuse: add writeback documentation fuse: honor AT_STATX_FORCE_SYNC fuse: honor AT_STATX_DONT_SYNC fuse: Restrict allow_other to the superblock's namespace or a descendant fuse: Support fuse filesystems outside of init_user_ns fuse: Fail all requests with invalid uids or gids fuse: Remove the buggy retranslation of pids in fuse_dev_do_read fuse: return -ECONNABORTED on /dev/fuse read after abort fuse: atomic_o_trunc should truncate pagecache
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/acl.c4
-rw-r--r--fs/fuse/control.c15
-rw-r--r--fs/fuse/cuse.c11
-rw-r--r--fs/fuse/dev.c43
-rw-r--r--fs/fuse/dir.c45
-rw-r--r--fs/fuse/fuse_i.h15
-rw-r--r--fs/fuse/inode.c50
-rw-r--r--fs/fuse/xattr.c43
8 files changed, 164 insertions, 62 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/control.c b/fs/fuse/control.c
index b9ea99c5b5b3..0b694655d988 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -35,7 +35,7 @@ static ssize_t fuse_conn_abort_write(struct file *file, const char __user *buf,
35{ 35{
36 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 36 struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
37 if (fc) { 37 if (fc) {
38 fuse_abort_conn(fc); 38 fuse_abort_conn(fc, true);
39 fuse_conn_put(fc); 39 fuse_conn_put(fc);
40 } 40 }
41 return count; 41 return count;
@@ -211,10 +211,11 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
211 if (!dentry) 211 if (!dentry)
212 return NULL; 212 return NULL;
213 213
214 fc->ctl_dentry[fc->ctl_ndents++] = dentry;
215 inode = new_inode(fuse_control_sb); 214 inode = new_inode(fuse_control_sb);
216 if (!inode) 215 if (!inode) {
216 dput(dentry);
217 return NULL; 217 return NULL;
218 }
218 219
219 inode->i_ino = get_next_ino(); 220 inode->i_ino = get_next_ino();
220 inode->i_mode = mode; 221 inode->i_mode = mode;
@@ -228,6 +229,9 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
228 set_nlink(inode, nlink); 229 set_nlink(inode, nlink);
229 inode->i_private = fc; 230 inode->i_private = fc;
230 d_add(dentry, inode); 231 d_add(dentry, inode);
232
233 fc->ctl_dentry[fc->ctl_ndents++] = dentry;
234
231 return dentry; 235 return dentry;
232} 236}
233 237
@@ -284,7 +288,10 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc)
284 for (i = fc->ctl_ndents - 1; i >= 0; i--) { 288 for (i = fc->ctl_ndents - 1; i >= 0; i--) {
285 struct dentry *dentry = fc->ctl_dentry[i]; 289 struct dentry *dentry = fc->ctl_dentry[i];
286 d_inode(dentry)->i_private = NULL; 290 d_inode(dentry)->i_private = NULL;
287 d_drop(dentry); 291 if (!i) {
292 /* Get rid of submounts: */
293 d_invalidate(dentry);
294 }
288 dput(dentry); 295 dput(dentry);
289 } 296 }
290 drop_nlink(d_inode(fuse_control_sb->s_root)); 297 drop_nlink(d_inode(fuse_control_sb->s_root));
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index e9e97803442a..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
@@ -406,7 +407,7 @@ err_unlock:
406err_region: 407err_region:
407 unregister_chrdev_region(devt, 1); 408 unregister_chrdev_region(devt, 1);
408err: 409err:
409 fuse_abort_conn(fc); 410 fuse_abort_conn(fc, false);
410 goto out; 411 goto out;
411} 412}
412 413
@@ -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) {
@@ -581,7 +586,7 @@ static ssize_t cuse_class_abort_store(struct device *dev,
581{ 586{
582 struct cuse_conn *cc = dev_get_drvdata(dev); 587 struct cuse_conn *cc = dev_get_drvdata(dev);
583 588
584 fuse_abort_conn(&cc->fc); 589 fuse_abort_conn(&cc->fc, false);
585 return count; 590 return count;
586} 591}
587static DEVICE_ATTR(abort, 0200, NULL, cuse_class_abort_store); 592static DEVICE_ATTR(abort, 0200, NULL, cuse_class_abort_store);
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 5d06384c2cae..e03ca14f40e9 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -112,13 +112,6 @@ static void __fuse_put_request(struct fuse_req *req)
112 refcount_dec(&req->count); 112 refcount_dec(&req->count);
113} 113}
114 114
115static void fuse_req_init_context(struct fuse_conn *fc, struct fuse_req *req)
116{
117 req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid());
118 req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid());
119 req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
120}
121
122void fuse_set_initialized(struct fuse_conn *fc) 115void fuse_set_initialized(struct fuse_conn *fc)
123{ 116{
124 /* Make sure stores before this are seen on another CPU */ 117 /* Make sure stores before this are seen on another CPU */
@@ -163,11 +156,19 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
163 goto out; 156 goto out;
164 } 157 }
165 158
166 fuse_req_init_context(fc, req); 159 req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
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);
162
167 __set_bit(FR_WAITING, &req->flags); 163 __set_bit(FR_WAITING, &req->flags);
168 if (for_background) 164 if (for_background)
169 __set_bit(FR_BACKGROUND, &req->flags); 165 __set_bit(FR_BACKGROUND, &req->flags);
170 166
167 if (unlikely(req->in.h.uid == ((uid_t)-1) ||
168 req->in.h.gid == ((gid_t)-1))) {
169 fuse_put_request(fc, req);
170 return ERR_PTR(-EOVERFLOW);
171 }
171 return req; 172 return req;
172 173
173 out: 174 out:
@@ -256,7 +257,10 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
256 if (!req) 257 if (!req)
257 req = get_reserved_req(fc, file); 258 req = get_reserved_req(fc, file);
258 259
259 fuse_req_init_context(fc, req); 260 req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
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);
263
260 __set_bit(FR_WAITING, &req->flags); 264 __set_bit(FR_WAITING, &req->flags);
261 __clear_bit(FR_BACKGROUND, &req->flags); 265 __clear_bit(FR_BACKGROUND, &req->flags);
262 return req; 266 return req;
@@ -381,8 +385,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
381 if (!fc->blocked && waitqueue_active(&fc->blocked_waitq)) 385 if (!fc->blocked && waitqueue_active(&fc->blocked_waitq))
382 wake_up(&fc->blocked_waitq); 386 wake_up(&fc->blocked_waitq);
383 387
384 if (fc->num_background == fc->congestion_threshold && 388 if (fc->num_background == fc->congestion_threshold && fc->sb) {
385 fc->connected && fc->sb) {
386 clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 389 clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
387 clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 390 clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
388 } 391 }
@@ -1234,9 +1237,10 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1234 if (err) 1237 if (err)
1235 goto err_unlock; 1238 goto err_unlock;
1236 1239
1237 err = -ENODEV; 1240 if (!fiq->connected) {
1238 if (!fiq->connected) 1241 err = (fc->aborted && fc->abort_err) ? -ECONNABORTED : -ENODEV;
1239 goto err_unlock; 1242 goto err_unlock;
1243 }
1240 1244
1241 if (!list_empty(&fiq->interrupts)) { 1245 if (!list_empty(&fiq->interrupts)) {
1242 req = list_entry(fiq->interrupts.next, struct fuse_req, 1246 req = list_entry(fiq->interrupts.next, struct fuse_req,
@@ -1260,12 +1264,6 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1260 in = &req->in; 1264 in = &req->in;
1261 reqsize = in->h.len; 1265 reqsize = in->h.len;
1262 1266
1263 if (task_active_pid_ns(current) != fc->pid_ns) {
1264 rcu_read_lock();
1265 in->h.pid = pid_vnr(find_pid_ns(in->h.pid, fc->pid_ns));
1266 rcu_read_unlock();
1267 }
1268
1269 /* If request is too large, reply with an error and restart the read */ 1267 /* If request is too large, reply with an error and restart the read */
1270 if (nbytes < reqsize) { 1268 if (nbytes < reqsize) {
1271 req->out.h.error = -EIO; 1269 req->out.h.error = -EIO;
@@ -1287,7 +1285,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1287 spin_lock(&fpq->lock); 1285 spin_lock(&fpq->lock);
1288 clear_bit(FR_LOCKED, &req->flags); 1286 clear_bit(FR_LOCKED, &req->flags);
1289 if (!fpq->connected) { 1287 if (!fpq->connected) {
1290 err = -ENODEV; 1288 err = (fc->aborted && fc->abort_err) ? -ECONNABORTED : -ENODEV;
1291 goto out_end; 1289 goto out_end;
1292 } 1290 }
1293 if (err) { 1291 if (err) {
@@ -2076,7 +2074,7 @@ static void end_polls(struct fuse_conn *fc)
2076 * is OK, the request will in that case be removed from the list before we touch 2074 * is OK, the request will in that case be removed from the list before we touch
2077 * it. 2075 * it.
2078 */ 2076 */
2079void fuse_abort_conn(struct fuse_conn *fc) 2077void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
2080{ 2078{
2081 struct fuse_iqueue *fiq = &fc->iq; 2079 struct fuse_iqueue *fiq = &fc->iq;
2082 2080
@@ -2089,6 +2087,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
2089 2087
2090 fc->connected = 0; 2088 fc->connected = 0;
2091 fc->blocked = 0; 2089 fc->blocked = 0;
2090 fc->aborted = is_abort;
2092 fuse_set_initialized(fc); 2091 fuse_set_initialized(fc);
2093 list_for_each_entry(fud, &fc->devices, entry) { 2092 list_for_each_entry(fud, &fc->devices, entry) {
2094 struct fuse_pqueue *fpq = &fud->pq; 2093 struct fuse_pqueue *fpq = &fud->pq;
@@ -2151,7 +2150,7 @@ int fuse_dev_release(struct inode *inode, struct file *file)
2151 /* Are we the last open device? */ 2150 /* Are we the last open device? */
2152 if (atomic_dec_and_test(&fc->dev_count)) { 2151 if (atomic_dec_and_test(&fc->dev_count)) {
2153 WARN_ON(fc->iq.fasync != NULL); 2152 WARN_ON(fc->iq.fasync != NULL);
2154 fuse_abort_conn(fc); 2153 fuse_abort_conn(fc, false);
2155 } 2154 }
2156 fuse_dev_free(fud); 2155 fuse_dev_free(fud);
2157 } 2156 }
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 24967382a7b1..56231b31f806 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;
@@ -924,12 +924,20 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
924} 924}
925 925
926static int fuse_update_get_attr(struct inode *inode, struct file *file, 926static int fuse_update_get_attr(struct inode *inode, struct file *file,
927 struct kstat *stat) 927 struct kstat *stat, unsigned int flags)
928{ 928{
929 struct fuse_inode *fi = get_fuse_inode(inode); 929 struct fuse_inode *fi = get_fuse_inode(inode);
930 int err = 0; 930 int err = 0;
931 bool sync;
931 932
932 if (time_before64(fi->i_time, get_jiffies_64())) { 933 if (flags & AT_STATX_FORCE_SYNC)
934 sync = true;
935 else if (flags & AT_STATX_DONT_SYNC)
936 sync = false;
937 else
938 sync = time_before64(fi->i_time, get_jiffies_64());
939
940 if (sync) {
933 forget_all_cached_acls(inode); 941 forget_all_cached_acls(inode);
934 err = fuse_do_getattr(inode, stat, file); 942 err = fuse_do_getattr(inode, stat, file);
935 } else if (stat) { 943 } else if (stat) {
@@ -943,7 +951,7 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
943 951
944int fuse_update_attributes(struct inode *inode, struct file *file) 952int fuse_update_attributes(struct inode *inode, struct file *file)
945{ 953{
946 return fuse_update_get_attr(inode, file, NULL); 954 return fuse_update_get_attr(inode, file, NULL, 0);
947} 955}
948 956
949int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid, 957int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
@@ -1030,7 +1038,7 @@ int fuse_allow_current_process(struct fuse_conn *fc)
1030 const struct cred *cred; 1038 const struct cred *cred;
1031 1039
1032 if (fc->allow_other) 1040 if (fc->allow_other)
1033 return 1; 1041 return current_in_userns(fc->user_ns);
1034 1042
1035 cred = current_cred(); 1043 cred = current_cred();
1036 if (uid_eq(cred->euid, fc->user_id) && 1044 if (uid_eq(cred->euid, fc->user_id) &&
@@ -1475,17 +1483,17 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
1475 return true; 1483 return true;
1476} 1484}
1477 1485
1478static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, 1486static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1479 bool trust_local_cmtime) 1487 struct fuse_setattr_in *arg, bool trust_local_cmtime)
1480{ 1488{
1481 unsigned ivalid = iattr->ia_valid; 1489 unsigned ivalid = iattr->ia_valid;
1482 1490
1483 if (ivalid & ATTR_MODE) 1491 if (ivalid & ATTR_MODE)
1484 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode; 1492 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
1485 if (ivalid & ATTR_UID) 1493 if (ivalid & ATTR_UID)
1486 arg->valid |= FATTR_UID, arg->uid = from_kuid(&init_user_ns, iattr->ia_uid); 1494 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
1487 if (ivalid & ATTR_GID) 1495 if (ivalid & ATTR_GID)
1488 arg->valid |= FATTR_GID, arg->gid = from_kgid(&init_user_ns, iattr->ia_gid); 1496 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
1489 if (ivalid & ATTR_SIZE) 1497 if (ivalid & ATTR_SIZE)
1490 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; 1498 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
1491 if (ivalid & ATTR_ATIME) { 1499 if (ivalid & ATTR_ATIME) {
@@ -1629,8 +1637,19 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1629 return err; 1637 return err;
1630 1638
1631 if (attr->ia_valid & ATTR_OPEN) { 1639 if (attr->ia_valid & ATTR_OPEN) {
1632 if (fc->atomic_o_trunc) 1640 /* This is coming from open(..., ... | O_TRUNC); */
1641 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1642 WARN_ON(attr->ia_size != 0);
1643 if (fc->atomic_o_trunc) {
1644 /*
1645 * No need to send request to userspace, since actual
1646 * truncation has already been done by OPEN. But still
1647 * need to truncate page cache.
1648 */
1649 i_size_write(inode, 0);
1650 truncate_pagecache(inode, 0);
1633 return 0; 1651 return 0;
1652 }
1634 file = NULL; 1653 file = NULL;
1635 } 1654 }
1636 1655
@@ -1646,7 +1665,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1646 1665
1647 memset(&inarg, 0, sizeof(inarg)); 1666 memset(&inarg, 0, sizeof(inarg));
1648 memset(&outarg, 0, sizeof(outarg)); 1667 memset(&outarg, 0, sizeof(outarg));
1649 iattr_to_fattr(attr, &inarg, trust_local_cmtime); 1668 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
1650 if (file) { 1669 if (file) {
1651 struct fuse_file *ff = file->private_data; 1670 struct fuse_file *ff = file->private_data;
1652 inarg.valid |= FATTR_FH; 1671 inarg.valid |= FATTR_FH;
@@ -1783,7 +1802,7 @@ static int fuse_getattr(const struct path *path, struct kstat *stat,
1783 if (!fuse_allow_current_process(fc)) 1802 if (!fuse_allow_current_process(fc))
1784 return -EACCES; 1803 return -EACCES;
1785 1804
1786 return fuse_update_get_attr(inode, NULL, stat); 1805 return fuse_update_get_attr(inode, NULL, stat, flags);
1787} 1806}
1788 1807
1789static const struct inode_operations fuse_dir_inode_operations = { 1808static const struct inode_operations fuse_dir_inode_operations = {
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index c4c093bbf456..5256ad333b05 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
@@ -515,6 +519,9 @@ struct fuse_conn {
515 abort and device release */ 519 abort and device release */
516 unsigned connected; 520 unsigned connected;
517 521
522 /** Connection aborted via sysfs */
523 bool aborted;
524
518 /** Connection failed (version mismatch). Cannot race with 525 /** Connection failed (version mismatch). Cannot race with
519 setting other bitfields since it is only set once in INIT 526 setting other bitfields since it is only set once in INIT
520 reply, before any other request, and never cleared */ 527 reply, before any other request, and never cleared */
@@ -526,6 +533,9 @@ struct fuse_conn {
526 /** Do readpages asynchronously? Only set in INIT */ 533 /** Do readpages asynchronously? Only set in INIT */
527 unsigned async_read:1; 534 unsigned async_read:1;
528 535
536 /** Return an unique read error after abort. Only set in INIT */
537 unsigned abort_err:1;
538
529 /** Do not send separate SETATTR request before open(O_TRUNC) */ 539 /** Do not send separate SETATTR request before open(O_TRUNC) */
530 unsigned atomic_o_trunc:1; 540 unsigned atomic_o_trunc:1;
531 541
@@ -851,7 +861,7 @@ void fuse_request_send_background_locked(struct fuse_conn *fc,
851 struct fuse_req *req); 861 struct fuse_req *req);
852 862
853/* Abort all requests */ 863/* Abort all requests */
854void fuse_abort_conn(struct fuse_conn *fc); 864void fuse_abort_conn(struct fuse_conn *fc, bool is_abort);
855 865
856/** 866/**
857 * Invalidate inode attributes 867 * Invalidate inode attributes
@@ -870,7 +880,7 @@ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
870/** 880/**
871 * Initialize fuse_conn 881 * Initialize fuse_conn
872 */ 882 */
873void fuse_conn_init(struct fuse_conn *fc); 883void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns);
874 884
875/** 885/**
876 * Release reference to fuse_conn 886 * Release reference to fuse_conn
@@ -975,6 +985,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size);
975int fuse_removexattr(struct inode *inode, const char *name); 985int fuse_removexattr(struct inode *inode, const char *name);
976extern const struct xattr_handler *fuse_xattr_handlers[]; 986extern const struct xattr_handler *fuse_xattr_handlers[];
977extern const struct xattr_handler *fuse_acl_xattr_handlers[]; 987extern const struct xattr_handler *fuse_acl_xattr_handlers[];
988extern const struct xattr_handler *fuse_no_acl_xattr_handlers[];
978 989
979struct posix_acl; 990struct posix_acl;
980struct posix_acl *fuse_get_acl(struct inode *inode, int type); 991struct posix_acl *fuse_get_acl(struct inode *inode, int type);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index ef309958e060..ffcaf98044b9 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;
@@ -371,7 +371,7 @@ void fuse_unlock_inode(struct inode *inode)
371 371
372static void fuse_umount_begin(struct super_block *sb) 372static void fuse_umount_begin(struct super_block *sb)
373{ 373{
374 fuse_abort_conn(get_fuse_conn_super(sb)); 374 fuse_abort_conn(get_fuse_conn_super(sb), false);
375} 375}
376 376
377static void fuse_send_destroy(struct fuse_conn *fc) 377static void fuse_send_destroy(struct fuse_conn *fc)
@@ -393,7 +393,7 @@ static void fuse_put_super(struct super_block *sb)
393 393
394 fuse_send_destroy(fc); 394 fuse_send_destroy(fc);
395 395
396 fuse_abort_conn(fc); 396 fuse_abort_conn(fc, false);
397 mutex_lock(&fuse_mutex); 397 mutex_lock(&fuse_mutex);
398 list_del(&fc->entry); 398 list_del(&fc->entry);
399 fuse_ctl_remove_conn(fc); 399 fuse_ctl_remove_conn(fc);
@@ -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)
522 case OPT_GROUP_ID: 523 case OPT_GROUP_ID:
523 if (fuse_match_uint(&args[0], &uv)) 524 if (fuse_match_uint(&args[0], &uv))
524 return 0; 525 return 0;
525 d->group_id = make_kgid(current_user_ns(), uv); 526 d->group_id = make_kgid(user_ns, uv);
526 if (!gid_valid(d->group_id)) 527 if (!gid_valid(d->group_id))
527 return 0; 528 return 0;
528 d->group_id_present = 1; 529 d->group_id_present = 1;
@@ -565,8 +566,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
565 struct super_block *sb = root->d_sb; 566 struct super_block *sb = root->d_sb;
566 struct fuse_conn *fc = get_fuse_conn_super(sb); 567 struct fuse_conn *fc = get_fuse_conn_super(sb);
567 568
568 seq_printf(m, ",user_id=%u", from_kuid_munged(&init_user_ns, fc->user_id)); 569 seq_printf(m, ",user_id=%u", from_kuid_munged(fc->user_ns, fc->user_id));
569 seq_printf(m, ",group_id=%u", from_kgid_munged(&init_user_ns, fc->group_id)); 570 seq_printf(m, ",group_id=%u", from_kgid_munged(fc->user_ns, fc->group_id));
570 if (fc->default_permissions) 571 if (fc->default_permissions)
571 seq_puts(m, ",default_permissions"); 572 seq_puts(m, ",default_permissions");
572 if (fc->allow_other) 573 if (fc->allow_other)
@@ -597,7 +598,7 @@ static void fuse_pqueue_init(struct fuse_pqueue *fpq)
597 fpq->connected = 1; 598 fpq->connected = 1;
598} 599}
599 600
600void fuse_conn_init(struct fuse_conn *fc) 601void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns)
601{ 602{
602 memset(fc, 0, sizeof(*fc)); 603 memset(fc, 0, sizeof(*fc));
603 spin_lock_init(&fc->lock); 604 spin_lock_init(&fc->lock);
@@ -621,6 +622,7 @@ void fuse_conn_init(struct fuse_conn *fc)
621 fc->attr_version = 1; 622 fc->attr_version = 1;
622 get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); 623 get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
623 fc->pid_ns = get_pid_ns(task_active_pid_ns(current)); 624 fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
625 fc->user_ns = get_user_ns(user_ns);
624} 626}
625EXPORT_SYMBOL_GPL(fuse_conn_init); 627EXPORT_SYMBOL_GPL(fuse_conn_init);
626 628
@@ -630,6 +632,7 @@ void fuse_conn_put(struct fuse_conn *fc)
630 if (fc->destroy_req) 632 if (fc->destroy_req)
631 fuse_request_free(fc->destroy_req); 633 fuse_request_free(fc->destroy_req);
632 put_pid_ns(fc->pid_ns); 634 put_pid_ns(fc->pid_ns);
635 put_user_ns(fc->user_ns);
633 fc->release(fc); 636 fc->release(fc);
634 } 637 }
635} 638}
@@ -918,6 +921,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
918 fc->posix_acl = 1; 921 fc->posix_acl = 1;
919 fc->sb->s_xattr = fuse_acl_xattr_handlers; 922 fc->sb->s_xattr = fuse_acl_xattr_handlers;
920 } 923 }
924 if (arg->flags & FUSE_ABORT_ERROR)
925 fc->abort_err = 1;
921 } else { 926 } else {
922 ra_pages = fc->max_read / PAGE_SIZE; 927 ra_pages = fc->max_read / PAGE_SIZE;
923 fc->no_lock = 1; 928 fc->no_lock = 1;
@@ -948,7 +953,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
948 FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | 953 FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
949 FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | 954 FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
950 FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | 955 FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT |
951 FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL; 956 FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
957 FUSE_ABORT_ERROR;
952 req->in.h.opcode = FUSE_INIT; 958 req->in.h.opcode = FUSE_INIT;
953 req->in.numargs = 1; 959 req->in.numargs = 1;
954 req->in.args[0].size = sizeof(*arg); 960 req->in.args[0].size = sizeof(*arg);
@@ -1061,7 +1067,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
1061 1067
1062 sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION); 1068 sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION);
1063 1069
1064 if (!parse_fuse_opt(data, &d, is_bdev)) 1070 if (!parse_fuse_opt(data, &d, is_bdev, sb->s_user_ns))
1065 goto err; 1071 goto err;
1066 1072
1067 if (is_bdev) { 1073 if (is_bdev) {
@@ -1089,16 +1095,27 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
1089 if (!file) 1095 if (!file)
1090 goto err; 1096 goto err;
1091 1097
1092 if ((file->f_op != &fuse_dev_operations) || 1098 /*
1093 (file->f_cred->user_ns != &init_user_ns)) 1099 * Require mount to happen from the same user namespace which
1100 * opened /dev/fuse to prevent potential attacks.
1101 */
1102 if (file->f_op != &fuse_dev_operations ||
1103 file->f_cred->user_ns != sb->s_user_ns)
1094 goto err_fput; 1104 goto err_fput;
1095 1105
1106 /*
1107 * If we are not in the initial user namespace posix
1108 * acls must be translated.
1109 */
1110 if (sb->s_user_ns != &init_user_ns)
1111 sb->s_xattr = fuse_no_acl_xattr_handlers;
1112
1096 fc = kmalloc(sizeof(*fc), GFP_KERNEL); 1113 fc = kmalloc(sizeof(*fc), GFP_KERNEL);
1097 err = -ENOMEM; 1114 err = -ENOMEM;
1098 if (!fc) 1115 if (!fc)
1099 goto err_fput; 1116 goto err_fput;
1100 1117
1101 fuse_conn_init(fc); 1118 fuse_conn_init(fc, sb->s_user_ns);
1102 fc->release = fuse_free_conn; 1119 fc->release = fuse_free_conn;
1103 1120
1104 fud = fuse_dev_alloc(fc); 1121 fud = fuse_dev_alloc(fc);
@@ -1179,6 +1196,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
1179 fuse_dev_free(fud); 1196 fuse_dev_free(fud);
1180 err_put_conn: 1197 err_put_conn:
1181 fuse_conn_put(fc); 1198 fuse_conn_put(fc);
1199 sb->s_fs_info = NULL;
1182 err_fput: 1200 err_fput:
1183 fput(file); 1201 fput(file);
1184 err: 1202 err:
@@ -1208,7 +1226,7 @@ static void fuse_kill_sb_anon(struct super_block *sb)
1208static struct file_system_type fuse_fs_type = { 1226static struct file_system_type fuse_fs_type = {
1209 .owner = THIS_MODULE, 1227 .owner = THIS_MODULE,
1210 .name = "fuse", 1228 .name = "fuse",
1211 .fs_flags = FS_HAS_SUBTYPE, 1229 .fs_flags = FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
1212 .mount = fuse_mount, 1230 .mount = fuse_mount,
1213 .kill_sb = fuse_kill_sb_anon, 1231 .kill_sb = fuse_kill_sb_anon,
1214}; 1232};
diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c
index 3caac46b08b0..433717640f78 100644
--- a/fs/fuse/xattr.c
+++ b/fs/fuse/xattr.c
@@ -192,6 +192,26 @@ static int fuse_xattr_set(const struct xattr_handler *handler,
192 return fuse_setxattr(inode, name, value, size, flags); 192 return fuse_setxattr(inode, name, value, size, flags);
193} 193}
194 194
195static bool no_xattr_list(struct dentry *dentry)
196{
197 return false;
198}
199
200static int no_xattr_get(const struct xattr_handler *handler,
201 struct dentry *dentry, struct inode *inode,
202 const char *name, void *value, size_t size)
203{
204 return -EOPNOTSUPP;
205}
206
207static int no_xattr_set(const struct xattr_handler *handler,
208 struct dentry *dentry, struct inode *nodee,
209 const char *name, const void *value,
210 size_t size, int flags)
211{
212 return -EOPNOTSUPP;
213}
214
195static const struct xattr_handler fuse_xattr_handler = { 215static const struct xattr_handler fuse_xattr_handler = {
196 .prefix = "", 216 .prefix = "",
197 .get = fuse_xattr_get, 217 .get = fuse_xattr_get,
@@ -209,3 +229,26 @@ const struct xattr_handler *fuse_acl_xattr_handlers[] = {
209 &fuse_xattr_handler, 229 &fuse_xattr_handler,
210 NULL 230 NULL
211}; 231};
232
233static const struct xattr_handler fuse_no_acl_access_xattr_handler = {
234 .name = XATTR_NAME_POSIX_ACL_ACCESS,
235 .flags = ACL_TYPE_ACCESS,
236 .list = no_xattr_list,
237 .get = no_xattr_get,
238 .set = no_xattr_set,
239};
240
241static const struct xattr_handler fuse_no_acl_default_xattr_handler = {
242 .name = XATTR_NAME_POSIX_ACL_DEFAULT,
243 .flags = ACL_TYPE_ACCESS,
244 .list = no_xattr_list,
245 .get = no_xattr_get,
246 .set = no_xattr_set,
247};
248
249const struct xattr_handler *fuse_no_acl_xattr_handlers[] = {
250 &fuse_no_acl_access_xattr_handler,
251 &fuse_no_acl_default_xattr_handler,
252 &fuse_xattr_handler,
253 NULL
254};