From patchwork Tue Apr 26 19:36:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seth Forshee X-Patchwork-Id: 8944651 Return-Path: X-Original-To: patchwork-selinux@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 636359F1D3 for ; Tue, 26 Apr 2016 20:13:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 72A652014A for ; Tue, 26 Apr 2016 20:13:57 +0000 (UTC) Received: from emsm-gh1-uea11.nsa.gov (smtp.nsa.gov [8.44.101.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AA86820138 for ; Tue, 26 Apr 2016 20:13:55 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.24,538,1454976000"; d="scan'208";a="15644204" IronPort-PHdr: =?us-ascii?q?9a23=3AHxSnVh8UzXAsx/9uRHKM819IXTAuvvDOBiVQ1KB8?= =?us-ascii?q?0eIcTK2v8tzYMVDF4r011RmSDdWdtKMP0rGI+4nbGkU+or+5+EgYd5JNUxJXwe?= =?us-ascii?q?43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6anHS+4HYoFwnlMkIt?= =?us-ascii?q?f6KuSt6U0JX8jrvss7ToICx2xxOFKYtoKxu3qQiD/uI3uqBFbpgL9x3Sv3FTcP?= =?us-ascii?q?5Xz247bXianhL7+9vitMU7q3cYk7sb+sVBSaT3ebgjBfwdVWx+cjN92Mq+/zTZ?= =?us-ascii?q?TADH2T1UeGQbnhdSBgHDplmuU53wvyf3rO9VyCybJtb3SrZyUjOnueMjbR7rjC?= =?us-ascii?q?AcfwUr/Xvahs042KdaoxamvDRk0YPObY2UcvpjKPDzZ9QfEFFMQsYZeStbGYOx?= =?us-ascii?q?YsNbFOcdPaBWqJPmp1YDhRC3Aw6qBejmznlDgXqgjv5y6PgoDQyThF9oJNkJqn?= =?us-ascii?q?mB6YytbKo=3D?= X-IPAS-Result: =?us-ascii?q?A2EJBQBiyx9X/wHyM5BeHAGCcCuBULt3H4F2hUVMAQEBAQE?= =?us-ascii?q?BAgJiJ4ItfVs9AQEBAwECDxUTBgEBDCALAQIDCQEBFykICAMBLQMBBQELEQYBB?= =?us-ascii?q?wsFGAQBiAgBpVGBMT4xik+FKAEEjEcBAQEHAQEBARYGCoQNggqIWhEBhXQBjky?= =?us-ascii?q?JSIFVjESBZYdFJQyFNI1yMIEOYoIFG4FpTgGHeIE1AQEB?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by emsm-gh1-uea11.nsa.gov with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Apr 2016 20:13:30 +0000 Received: from prometheus.infosec.tycho.ncsc.mil (prometheus [192.168.25.40]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u3QKDTTS022345; Tue, 26 Apr 2016 16:13:30 -0400 Received: from tarius.tycho.ncsc.mil (tarius.infosec.tycho.ncsc.mil [144.51.242.1]) by prometheus.infosec.tycho.ncsc.mil (8.15.2/8.15.2) with ESMTP id u3QJbGuQ172333 for ; Tue, 26 Apr 2016 15:37:16 -0400 Received: from goalie.tycho.ncsc.mil (goalie [144.51.242.250]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u3QJak07011587 for ; Tue, 26 Apr 2016 15:37:15 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BBBQD9wR9X/yQp0Apegw0rgVC3cIQJCBeFeAKBQEwBAQEBAQFmJ4RCAQEBAxIVGQEBNwEPUTQBBQEcBgESIogIAaVXgTE+MYpPhSgBBIxKAQEBAQEBAQMCARcGCoQNggqLUgtAgkOOTYlIgVWMRIFlh0UxhTSNcjCBDmKBeA0bgWlOAYktAQEB X-IPAS-Result: A0BBBQD9wR9X/yQp0Apegw0rgVC3cIQJCBeFeAKBQEwBAQEBAQFmJ4RCAQEBAxIVGQEBNwEPUTQBBQEcBgESIogIAaVXgTE+MYpPhSgBBIxKAQEBAQEBAQMCARcGCoQNggqLUgtAgkOOTYlIgVWMRIFlh0UxhTSNcjCBDmKBeA0bgWlOAYktAQEB X-IronPort-AV: E=Sophos;i="5.24,537,1454994000"; d="scan'208";a="5410393" Received: from emsm-gh1-uea10.corp.nsa.gov (HELO emsm-gh1-uea10.nsa.gov) ([10.208.41.36]) by goalie.tycho.ncsc.mil with ESMTP; 26 Apr 2016 15:37:15 -0400 IronPort-PHdr: =?us-ascii?q?9a23=3Ayu3FwhSgCZebv2eZhRL2r9cSWtpsv+yvbD5Q0YIu?= =?us-ascii?q?jvd0So/mwa65ZhyN2/xhgRfzUJnB7Loc0qyN4/CmBj1LuM3Z+Fk5M7VyFDY9wf?= =?us-ascii?q?0MmAIhBMPXQWbaF9XNKxIAIcJZSVV+9Gu6O0UGUOz3ZlnVv2HgpWVKQka3CwN5?= =?us-ascii?q?K6zPF5LIiIzvjqbpq82VPFQD3WHlKZpJbzyI7izp/vEMhoVjLqtjgjDomVBvP9?= =?us-ascii?q?ps+GVzOFiIlAz97MrjtLRq8iBXpu5zv5UYCfayV+0CQLdZFDUrNXwurI2u7EGb?= =?us-ascii?q?DFjH2nxJGEgMkxEAPE6NxhD3UprrtyL8/KIp1SObMMH7V7UcSTGj9LxqTxmugy?= =?us-ascii?q?ACYXpx1WDUjstrxJlJrQisqx03l4vVY4WSL9JlbK7HcN8bA2pcCJV/TStEV7ix?= =?us-ascii?q?c4tHIe0bJuZVosGpvFYSrV2wAhO3BO7i4jRBgHjw3KYz16IqFgSQj19oJM4HrH?= =?us-ascii?q?mB9Ia9D6wVS+3gifCQlTg=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0HzAAC5wh9XkK3fVdFegw2Be7dwhAkIF?= =?us-ascii?q?4F2hAICgUBMAQEBAQEBAgIPAQEBAQcNCQkhL4ItfVs9AQEBAxIVGQEBNwEPUTQ?= =?us-ascii?q?BBQEcBgESIogIAaVXgTE+MYpPhSgBBIxKAQEBAQEBAQMCARcGCoQNggqLUgtAg?= =?us-ascii?q?kOOTYlIgVWMRIFlh0UxhTSNcjCBDoJaDREKgWlOAYktAQEB?= X-IPAS-Result: =?us-ascii?q?A0HzAAC5wh9XkK3fVdFegw2Be7dwhAkIF4F2hAICgUBMAQE?= =?us-ascii?q?BAQEBAgIPAQEBAQcNCQkhL4ItfVs9AQEBAxIVGQEBNwEPUTQBBQEcBgESIogIA?= =?us-ascii?q?aVXgTE+MYpPhSgBBIxKAQEBAQEBAQMCARcGCoQNggqLUgtAgkOOTYlIgVWMRIF?= =?us-ascii?q?lh0UxhTSNcjCBDoJaDREKgWlOAYktAQEB?= X-IronPort-AV: E=Sophos;i="5.24,537,1454976000"; d="scan'208";a="13051025" Received: from mail-io0-f173.google.com ([209.85.223.173]) by emsm-gh1-uea10.nsa.gov with ESMTP/TLS/AES128-GCM-SHA256; 26 Apr 2016 19:37:14 +0000 Received: by mail-io0-f173.google.com with SMTP id u185so30186267iod.3 for ; Tue, 26 Apr 2016 12:37:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7Unu8VnN34149l8geh5lTk0kqD1AtI2eeBujWTEQx9g=; b=PETvV9Blrhvy+jCvW4oZcjCQR0MNU/v0CRIgXf79UILQmyeZO5hWM0dMQrpNcS4TQc DzQIw1XbqcfwpBYN21XwH0VP8xhom2OHapOG+fK97tpPzoQCI1aAfTCobByRhDN2u2PP 25g5Nj5qhL+1D5lMDCarEIHhVHBvrooOlEl53KG8lbhGYwdemeA+9dbndlNcQ2UZrtwF Bi/YMMc3PeppPmGZZAG0g3s2CX9b2g366NGQj9GuDg7yNganeoofaDBO+BnveVmvJgnA MXTTEYwywwQr5WmxAUUDJscaWjicdyGdAKmHdH8OyoXFsoYqqMxis08Gfa2ysL1sJ2AQ aAaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7Unu8VnN34149l8geh5lTk0kqD1AtI2eeBujWTEQx9g=; b=NMu/h9itZsXUPguw5Sj/Mnx/1Ilf3qduRQqzWLOv+wLH71JICiDwYkt9jphPE1mLkt 8xSEUJSFTviJ6qDBysqBY+01Eqa0IQVJjRS5RJnS4e3qP4+x7saaDtYYvoqLTpBsjcV/ YsqmJtsGTl3raynK0D2OO73/UWt8GgjB2OUU1B/ZSQ2RAgx3p9pBCN53iy4x7Lz0z1lU yWBuOBAxpoIKHBpaopANbeODHvvrv1Rau+I35qTp4rIiwbuq86le2t3CjKtFqjAruGGq Y2F3OHw50HMvH/l3LFFW3uWQ/3Vjma8YOKa7QJsYPcs6AbD52K70Fnr1vT+e36ZDcSWj dRKw== X-Gm-Message-State: AOPr4FWoJOOVK3SaKh/xribbO9nwd6+D9lMkweZh+NGu2m3bS27Kr3wyLQ87+PBe4s3vtKZj X-Received: by 10.107.164.163 with SMTP id d35mr5749852ioj.80.1461699433973; Tue, 26 Apr 2016 12:37:13 -0700 (PDT) Received: from localhost ([2605:a601:aab:f920:39a1:5bcf:aa:5b00]) by smtp.gmail.com with ESMTPSA id jd8sm7576639igb.2.2016.04.26.12.37.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Apr 2016 12:37:13 -0700 (PDT) From: Seth Forshee To: "Eric W. Biederman" , Miklos Szeredi Subject: [PATCH v4 18/21] fuse: Add support for pid namespaces Date: Tue, 26 Apr 2016 14:36:31 -0500 Message-Id: <1461699396-33000-19-git-send-email-seth.forshee@canonical.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1461699396-33000-1-git-send-email-seth.forshee@canonical.com> References: <1461699396-33000-1-git-send-email-seth.forshee@canonical.com> X-Mailman-Approved-At: Tue, 26 Apr 2016 16:11:02 -0400 X-BeenThere: selinux@tycho.nsa.gov X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: Cc: linux-bcache@vger.kernel.org, Serge Hallyn , Seth Forshee , dm-devel@redhat.com, Miklos Szeredi , Richard Weinberger , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, linux-raid@vger.kernel.org, fuse-devel@lists.sourceforge.net, Austin S Hemmelgarn , linux-mtd@lists.infradead.org, Alexander Viro , selinux@tycho.nsa.gov, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, Pavel Tikhomirov MIME-Version: 1.0 Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When the userspace process servicing fuse requests is running in a pid namespace then pids passed via the fuse fd are not being translated into that process' namespace. Translation is necessary for the pid to be useful to that process. Since no use case currently exists for changing namespaces all translations can be done relative to the pid namespace in use when fuse_conn_init() is called. For fuse this translates to mount time, and for cuse this is when /dev/cuse is opened. IO for this connection from another namespace will return errors. Requests from processes whose pid cannot be translated into the target namespace are not permitted, except for requests allocated via fuse_get_req_nofail_nopages. For no-fail requests in.h.pid will be 0 if the pid translation fails. File locking changes based on previous work done by Eric Biederman. Signed-off-by: Seth Forshee Acked-by: Miklos Szeredi --- fs/fuse/dev.c | 19 +++++++++++++++---- fs/fuse/file.c | 22 +++++++++++++++++----- fs/fuse/fuse_i.h | 4 ++++ fs/fuse/inode.c | 3 +++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index cbece1221417..4e91b2ac25a7 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -19,6 +19,7 @@ #include #include #include +#include MODULE_ALIAS_MISCDEV(FUSE_MINOR); MODULE_ALIAS("devname:fuse"); @@ -124,11 +125,11 @@ static void __fuse_put_request(struct fuse_req *req) atomic_dec(&req->count); } -static void fuse_req_init_context(struct fuse_req *req) +static void fuse_req_init_context(struct fuse_conn *fc, struct fuse_req *req) { req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid()); req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid()); - req->in.h.pid = current->pid; + req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); } void fuse_set_initialized(struct fuse_conn *fc) @@ -181,10 +182,14 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, goto out; } - fuse_req_init_context(req); + fuse_req_init_context(fc, req); __set_bit(FR_WAITING, &req->flags); if (for_background) __set_bit(FR_BACKGROUND, &req->flags); + if (req->in.h.pid == 0) { + fuse_put_request(fc, req); + return ERR_PTR(-EOVERFLOW); + } return req; @@ -274,7 +279,7 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, if (!req) req = get_reserved_req(fc, file); - fuse_req_init_context(req); + fuse_req_init_context(fc, req); __set_bit(FR_WAITING, &req->flags); __clear_bit(FR_BACKGROUND, &req->flags); return req; @@ -1243,6 +1248,9 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, struct fuse_in *in; unsigned reqsize; + if (task_active_pid_ns(current) != fc->pid_ns) + return -EIO; + restart: spin_lock(&fiq->waitq.lock); err = -EAGAIN; @@ -1872,6 +1880,9 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, struct fuse_req *req; struct fuse_out_header oh; + if (task_active_pid_ns(current) != fc->pid_ns) + return -EIO; + if (nbytes < sizeof(struct fuse_out_header)) return -EINVAL; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 719924d6c706..b5c616c5ec98 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2067,7 +2067,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) { @@ -2082,7 +2083,14 @@ 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; + + /* + * Convert pid into the caller's pid namespace. If the pid + * does not map into the namespace fl_pid will get set to 0. + */ + rcu_read_lock(); + fl->fl_pid = pid_vnr(find_pid_ns(ffl->pid, fc->pid_ns)); + rcu_read_unlock(); break; default: @@ -2131,7 +2139,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) args.out.args[0].value = &outarg; err = fuse_simple_request(fc, &args); if (!err) - err = convert_fuse_file_lock(&outarg.lk, fl); + err = convert_fuse_file_lock(fc, &outarg.lk, fl); return err; } @@ -2143,7 +2151,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) FUSE_ARGS(args); struct fuse_lk_in inarg; 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; + pid_t pid_nr = pid_nr_ns(pid, fc->pid_ns); int err; if (fl->fl_lmops && fl->fl_lmops->lm_grant) { @@ -2155,7 +2164,10 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) if (fl->fl_flags & FL_CLOSE) return 0; - fuse_lk_fill(&args, file, fl, opcode, pid, flock, &inarg); + if (pid && pid_nr == 0) + return -EOVERFLOW; + + fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg); err = fuse_simple_request(fc, &args); /* locking is restartable */ diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index eddbe02c4028..9145445a759a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -23,6 +23,7 @@ #include #include #include +#include /** Max number of pages that can be used in a single read request */ #define FUSE_MAX_PAGES_PER_REQ 32 @@ -465,6 +466,9 @@ struct fuse_conn { /** The group id for this mount */ kgid_t group_id; + /** The pid namespace for this mount */ + struct pid_namespace *pid_ns; + /** The fuse mount flags for this mount */ unsigned flags; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1ce67668a8e1..eade0bfa4488 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -20,6 +20,7 @@ #include #include #include +#include MODULE_AUTHOR("Miklos Szeredi "); MODULE_DESCRIPTION("Filesystem in Userspace"); @@ -609,6 +610,7 @@ void fuse_conn_init(struct fuse_conn *fc) fc->connected = 1; fc->attr_version = 1; get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); + fc->pid_ns = get_pid_ns(task_active_pid_ns(current)); } EXPORT_SYMBOL_GPL(fuse_conn_init); @@ -617,6 +619,7 @@ void fuse_conn_put(struct fuse_conn *fc) if (atomic_dec_and_test(&fc->count)) { if (fc->destroy_req) fuse_request_free(fc->destroy_req); + put_pid_ns(fc->pid_ns); fc->release(fc); } }