Skip to content

Commit 5d6d3a3

Browse files
author
Miklos Szeredi
committed
fuse: allow server to run in different pid_ns
Commit 0b6e9ea ("fuse: Add support for pid namespaces") broke Sandstorm.io development tools, which have been sending FUSE file descriptors across PID namespace boundaries since early 2014. The above patch added a check that prevented I/O on the fuse device file descriptor if the pid namespace of the reader/writer was different from the pid namespace of the mounter. With this change passing the device file descriptor to a different pid namespace simply doesn't work. The check was added because pids are transferred to/from the fuse userspace server in the namespace registered at mount time. To fix this regression, remove the checks and do the following: 1) the pid in the request header (the pid of the task that initiated the filesystem operation) is translated to the reader's pid namespace. If a mapping doesn't exist for this pid, then a zero pid is used. Note: even if a mapping would exist between the initiator task's pid namespace and the reader's pid namespace the pid will be zero if either mapping from initator's to mounter's namespace or mapping from mounter's to reader's namespace doesn't exist. 2) The lk.pid value in setlk/setlkw requests and getlk reply is left alone. Userspace should not interpret this value anyway. Also allow the setlk/setlkw operations if the pid of the task cannot be represented in the mounter's namespace (pid being zero in that case). Reported-by: Kenton Varda <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]> Fixes: 0b6e9ea ("fuse: Add support for pid namespaces") Cc: <[email protected]> # v4.12+ Cc: Eric W. Biederman <[email protected]> Cc: Seth Forshee <[email protected]>
1 parent 569dbb8 commit 5d6d3a3

File tree

2 files changed

+7
-9
lines changed

2 files changed

+7
-9
lines changed

fs/fuse/dev.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,9 +1222,6 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
12221222
struct fuse_in *in;
12231223
unsigned reqsize;
12241224

1225-
if (task_active_pid_ns(current) != fc->pid_ns)
1226-
return -EIO;
1227-
12281225
restart:
12291226
spin_lock(&fiq->waitq.lock);
12301227
err = -EAGAIN;
@@ -1262,6 +1259,13 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
12621259

12631260
in = &req->in;
12641261
reqsize = in->h.len;
1262+
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+
12651269
/* If request is too large, reply with an error and restart the read */
12661270
if (nbytes < reqsize) {
12671271
req->out.h.error = -EIO;
@@ -1823,9 +1827,6 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
18231827
struct fuse_req *req;
18241828
struct fuse_out_header oh;
18251829

1826-
if (task_active_pid_ns(current) != fc->pid_ns)
1827-
return -EIO;
1828-
18291830
if (nbytes < sizeof(struct fuse_out_header))
18301831
return -EINVAL;
18311832

fs/fuse/file.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,9 +2181,6 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
21812181
if ((fl->fl_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX)
21822182
return 0;
21832183

2184-
if (pid && pid_nr == 0)
2185-
return -EOVERFLOW;
2186-
21872184
fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg);
21882185
err = fuse_simple_request(fc, &args);
21892186

0 commit comments

Comments
 (0)