fuse: allow server to run in different pid_ns

Commit 0b6e9ea041e6 ("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 <kenton@sandstorm.io>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Fixes: 0b6e9ea041e6 ("fuse: Add support for pid namespaces")
Cc: <stable@vger.kernel.org> # v4.12+
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Seth Forshee <seth.forshee@canonical.com>

+7 -9
+7 -6
fs/fuse/dev.c
··· 1222 1222 struct fuse_in *in; 1223 1223 unsigned reqsize; 1224 1224 1225 - if (task_active_pid_ns(current) != fc->pid_ns) 1226 - return -EIO; 1227 - 1228 1225 restart: 1229 1226 spin_lock(&fiq->waitq.lock); 1230 1227 err = -EAGAIN; ··· 1259 1262 1260 1263 in = &req->in; 1261 1264 reqsize = in->h.len; 1265 + 1266 + if (task_active_pid_ns(current) != fc->pid_ns) { 1267 + rcu_read_lock(); 1268 + in->h.pid = pid_vnr(find_pid_ns(in->h.pid, fc->pid_ns)); 1269 + rcu_read_unlock(); 1270 + } 1271 + 1262 1272 /* If request is too large, reply with an error and restart the read */ 1263 1273 if (nbytes < reqsize) { 1264 1274 req->out.h.error = -EIO; ··· 1826 1822 struct fuse_pqueue *fpq = &fud->pq; 1827 1823 struct fuse_req *req; 1828 1824 struct fuse_out_header oh; 1829 - 1830 - if (task_active_pid_ns(current) != fc->pid_ns) 1831 - return -EIO; 1832 1825 1833 1826 if (nbytes < sizeof(struct fuse_out_header)) 1834 1827 return -EINVAL;
-3
fs/fuse/file.c
··· 2181 2181 if ((fl->fl_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX) 2182 2182 return 0; 2183 2183 2184 - if (pid && pid_nr == 0) 2185 - return -EOVERFLOW; 2186 - 2187 2184 fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg); 2188 2185 err = fuse_simple_request(fc, &args); 2189 2186