>From 9bdaa744858d296f361a92c8940c33f878aec169 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 4 Oct 2012 13:42:34 -0700 Subject: [PATCH 2/4] fuse: Teach fuse how to handle the pid namespace. Signed-off-by: "Eric W. Biederman" --- fs/fuse/dev.c | 2 +- fs/fuse/file.c | 17 ++++++++++------- fs/fuse/fuse_i.h | 3 +++ fs/fuse/inode.c | 4 ++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index e01f30c51b3c..448775701763 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -128,7 +128,7 @@ static void fuse_req_init_context(struct fuse_conn *fc, struct fuse_req *req) { req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid()); req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid()); - req->in.h.pid = current->pid; + req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); } static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 912061ac4baf..2d52801fa5dd 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2130,7 +2130,8 @@ static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma) return generic_file_mmap(file, vma); } -static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, +static int convert_fuse_file_lock(struct fuse_conn *fc, + const struct fuse_file_lock *ffl, struct file_lock *fl) { switch (ffl->type) { @@ -2145,7 +2146,9 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, fl->fl_start = ffl->start; fl->fl_end = ffl->end; - fl->fl_pid = ffl->pid; + rcu_read_lock(); + fl->fl_pid = pid_vnr(find_pid_ns(ffl->pid, fc->pid_ns)); + rcu_read_unlock(); break; default: @@ -2156,7 +2159,7 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, } static void fuse_lk_fill(struct fuse_req *req, struct file *file, - const struct file_lock *fl, int opcode, pid_t pid, + const struct file_lock *fl, int opcode, struct pid *pid, int flock) { struct inode *inode = file_inode(file); @@ -2169,7 +2172,7 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file, arg->lk.start = fl->fl_start; arg->lk.end = fl->fl_end; arg->lk.type = fl->fl_type; - arg->lk.pid = pid; + arg->lk.pid = pid_nr_ns(pid, fc->pid_ns); if (flock) arg->lk_flags |= FUSE_LK_FLOCK; req->in.h.opcode = opcode; @@ -2191,7 +2194,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) if (IS_ERR(req)) return PTR_ERR(req); - fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0); + fuse_lk_fill(req, file, fl, FUSE_GETLK, NULL, 0); req->out.numargs = 1; req->out.args[0].size = sizeof(outarg); req->out.args[0].value = &outarg; @@ -2199,7 +2202,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) err = req->out.h.error; fuse_put_request(fc, req); if (!err) - err = convert_fuse_file_lock(&outarg.lk, fl); + err = convert_fuse_file_lock(fc, &outarg.lk, fl); return err; } @@ -2210,7 +2213,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_req *req; int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; - pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0; + struct pid *pid = fl->fl_type != F_UNLCK ? task_tgid(current) : NULL; int err; if (fl->fl_lmops && fl->fl_lmops->lm_grant) { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e7dbbb5d62b4..5d93f87e9960 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -601,6 +601,9 @@ struct fuse_conn { /** User namespace to communicate uids and gids to the fuse daemon */ struct user_namespace *user_ns; + + /** Pid namespace to communicate pids to the fuse daemon */ + struct pid_namespace *pid_ns; }; static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 894288f7ad67..5284d7fda269 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -21,6 +21,7 @@ #include #include #include +#include MODULE_AUTHOR("Miklos Szeredi "); MODULE_DESCRIPTION("Filesystem in Userspace"); @@ -618,6 +619,7 @@ void fuse_conn_init(struct fuse_conn *fc) fc->attr_version = 1; get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); fc->user_ns = get_user_ns(current_user_ns()); + fc->pid_ns = get_pid_ns(task_active_pid_ns(current)); } EXPORT_SYMBOL_GPL(fuse_conn_init); @@ -628,6 +630,8 @@ void fuse_conn_put(struct fuse_conn *fc) fuse_request_free(fc->destroy_req); put_user_ns(fc->user_ns); fc->user_ns = NULL; + put_pid_ns(fc->pid_ns); + fc->pid_ns = NULL; fc->release(fc); } } -- 1.9.1