From patchwork Thu Nov 12 01:53:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Gidra X-Patchwork-Id: 11898869 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CCB80139F for ; Thu, 12 Nov 2020 01:54:11 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 5B7A520791 for ; Thu, 12 Nov 2020 01:54:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="SQyRpCsk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5B7A520791 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 6BB8C6B0068; Wed, 11 Nov 2020 20:54:10 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 643066B006C; Wed, 11 Nov 2020 20:54:10 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4BF386B006E; Wed, 11 Nov 2020 20:54:10 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0242.hostedemail.com [216.40.44.242]) by kanga.kvack.org (Postfix) with ESMTP id 1C9CA6B0068 for ; Wed, 11 Nov 2020 20:54:10 -0500 (EST) Received: from smtpin10.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id C14411EE6 for ; Thu, 12 Nov 2020 01:54:09 +0000 (UTC) X-FDA: 77474095818.10.gold45_4b1688627302 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin10.hostedemail.com (Postfix) with ESMTP id 9DEEC16A07E for ; Thu, 12 Nov 2020 01:54:09 +0000 (UTC) X-Spam-Summary: 1,0,0,66d8a422ecda5f83,d41d8cd98f00b204,3wjwsxwskckemplftihjesbhpphmf.dpnmjovy-nnlwbdl.psh@flex--lokeshgidra.bounces.google.com,,RULES_HIT:41:152:355:379:541:800:960:966:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1535:1544:1593:1594:1605:1711:1730:1747:1777:1792:2196:2199:2393:2559:2562:2693:2892:2894:2899:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3871:3874:4119:4250:4321:4385:4398:4605:5007:6117:6119:6120:6261:6653:6742:6743:7901:7903:8568:9969:10004:11026:11473:11658:11914:12043:12048:12114:12296:12297:12438:12555:12895:12986:13138:13161:13229:13231:14096:14097:14181:14394:14659:14721:21080:21433:21444:21451:21627:21990:30029:30054:30070:30075,0,RBL:209.85.219.202:@flex--lokeshgidra.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100;04yf64pfn1o3qtepg45ncq5qdd6e8ycgkmkk3w5nf7e7637sgwns9wytk97h3kb.wdtwcufzmcwamgjwwg9euwswzj65a3a6a9ofh1iwmfpen1n4at7rib7e9zcsxej.r-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0 .5,0.5,N X-HE-Tag: gold45_4b1688627302 X-Filterd-Recvd-Size: 8665 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) by imf30.hostedemail.com (Postfix) with ESMTP for ; Thu, 12 Nov 2020 01:54:09 +0000 (UTC) Received: by mail-yb1-f202.google.com with SMTP id v12so4272396ybi.6 for ; Wed, 11 Nov 2020 17:54:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=c9Og5DC1k1cUQRw8CGbu3hvhZccACMgaVukw9TXsnBk=; b=SQyRpCskDDQyjOj6Y7KQvyf3aH7p5CeESVkOzrwBVOw1wcZF5i6plpZZMnli4dRCk7 KoIwO3P2UyZnp6UypXtHWy5M2Dap/44fsRQwyPpwXGdkVenFWanSIFIsv8SGfQcvEbdD o3eZGOw8xs9KPTNqy27mnkEv64rarQjcTaWJnxSDIWKqLGZwr5qem3oI89F0v3cxeyAU j/PhrDuI/dRIqJ5zGSIoLc1kEtTjSQdSW91Q0HjlOPZvrgj3pxvwZiNTwhAZwfq7bafH 2sxTzHwcbexnyW7lTYQKJQZnTscocjiFdeH1tr0iAXvu/jrYNsRGNcaV10CkQ6IUrf/I 8iBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=c9Og5DC1k1cUQRw8CGbu3hvhZccACMgaVukw9TXsnBk=; b=mSII/ycSdUfMwUUm0hxX4AG/+0kY1J4qec3jGKZDwECw/GCjpzORbjpejU+3CBp9mL sle5NKSfILh6EZ7p85byQM8wMXvIamNbSn01fugawi2dLgFlJvQDvChqnnPHxi6u69Rx LIEVLpc6iQRX1HmTmwavUMUj97RNwCP4fNXOpYP9qY4g2HAUvUvYuY5QjTLfJEbB9dn2 IMoovpQRz/N9zaPNoGtkt1p0lMn2ly35lZVpvJydObeC2iTm0c9xKowKPGRQXtwPEiqq SlRCrO8NJWvRFg5giIwStA5XPkCRNE4EW9fpUyOmHLwUpbYWA1Gq0Igft3Mv5pthnqFY Nruw== X-Gm-Message-State: AOAM530y+uBFdweO1MC/e2qaLhPoM4sPACq0dGi7/O0v9S8WbRd1RUM7 Gevgp/l8C1Luv6J6AyK/yluEadTGfWiFAzWKzg== X-Google-Smtp-Source: ABdhPJwbEExJZLbWaATpLGAop1r2dI05u8VEsbPmkQZCo1UtYBTDWpESrtyVB/fsRM0ZspxgBdPVqcsf9LpufrRfvw== X-Received: from lg.mtv.corp.google.com ([2620:15c:211:202:f693:9fff:fef4:29dd]) (user=lokeshgidra job=sendgmr) by 2002:a25:5702:: with SMTP id l2mr38652087ybb.184.1605146048341; Wed, 11 Nov 2020 17:54:08 -0800 (PST) Date: Wed, 11 Nov 2020 17:53:56 -0800 In-Reply-To: <20201112015359.1103333-1-lokeshgidra@google.com> Message-Id: <20201112015359.1103333-2-lokeshgidra@google.com> Mime-Version: 1.0 References: <20201112015359.1103333-1-lokeshgidra@google.com> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog Subject: [PATCH v13 1/4] security: add inode_init_security_anon() LSM hook From: Lokesh Gidra To: Andrea Arcangeli , Alexander Viro , James Morris , Stephen Smalley , Casey Schaufler , Eric Biggers , Paul Moore Cc: "Serge E. Hallyn" , Eric Paris , Lokesh Gidra , Daniel Colascione , Kees Cook , "Eric W. Biederman" , KP Singh , David Howells , Anders Roxell , Sami Tolvanen , Matthew Garrett , Aaron Goidel , Randy Dunlap , "Joel Fernandes (Google)" , YueHaibing , Christian Brauner , Alexei Starovoitov , Alexey Budankov , Adrian Reber , Aleksa Sarai , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, kaleshsingh@google.com, calin@google.com, surenb@google.com, jeffv@google.com, kernel-team@android.com, linux-mm@kvack.org, Andrew Morton , hch@infradead.org, Eric Biggers X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This change adds a new LSM hook, inode_init_security_anon(), that will be used while creating secure anonymous inodes. The hook allows/denies its creation and assigns a security context to the inode. The new hook accepts an optional context_inode parameter that callers can use to provide additional contextual information to security modules for granting/denying permission to create an anon-inode of the same type. This context_inode's security_context can also be used to initialize the newly created anon-inode's security_context. Signed-off-by: Lokesh Gidra Reviewed-by: Eric Biggers --- include/linux/lsm_hook_defs.h | 2 ++ include/linux/lsm_hooks.h | 9 +++++++++ include/linux/security.h | 10 ++++++++++ security/security.c | 8 ++++++++ 4 files changed, 29 insertions(+) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 32a940117e7a..435a2e22ff95 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -113,6 +113,8 @@ LSM_HOOK(void, LSM_RET_VOID, inode_free_security, struct inode *inode) LSM_HOOK(int, 0, inode_init_security, struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len) +LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode, + const struct qstr *name, const struct inode *context_inode) LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry, umode_t mode) LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir, diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index c503f7ab8afb..3af055b7ee1f 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -233,6 +233,15 @@ * Returns 0 if @name and @value have been successfully set, * -EOPNOTSUPP if no security attribute is needed, or * -ENOMEM on memory allocation failure. + * @inode_init_security_anon: + * Set up the incore security field for the new anonymous inode + * and return whether the inode creation is permitted by the security + * module or not. + * @inode contains the inode structure + * @name name of the anonymous inode class + * @context_inode optional related inode + * Returns 0 on success, -EACCES if the security module denies the + * creation of this inode, or another -errno upon other errors. * @inode_create: * Check permission to create a regular file. * @dir contains inode structure of the parent of the new file. diff --git a/include/linux/security.h b/include/linux/security.h index bc2725491560..7494a93b9ed9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -323,6 +323,9 @@ void security_inode_free(struct inode *inode); int security_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, initxattrs initxattrs, void *fs_data); +int security_inode_init_security_anon(struct inode *inode, + const struct qstr *name, + const struct inode *context_inode); int security_old_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len); @@ -737,6 +740,13 @@ static inline int security_inode_init_security(struct inode *inode, return 0; } +static inline int security_inode_init_security_anon(struct inode *inode, + const struct qstr *name, + const struct inode *context_inode) +{ + return 0; +} + static inline int security_old_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, diff --git a/security/security.c b/security/security.c index a28045dc9e7f..8989ba6af4f6 100644 --- a/security/security.c +++ b/security/security.c @@ -1058,6 +1058,14 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, } EXPORT_SYMBOL(security_inode_init_security); +int security_inode_init_security_anon(struct inode *inode, + const struct qstr *name, + const struct inode *context_inode) +{ + return call_int_hook(inode_init_security_anon, 0, inode, name, + context_inode); +} + int security_old_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len) From patchwork Thu Nov 12 01:53:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Gidra X-Patchwork-Id: 11898871 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4C140139F for ; Thu, 12 Nov 2020 01:54:16 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id DFF94216C4 for ; Thu, 12 Nov 2020 01:54:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="pdFjGdzJ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DFF94216C4 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A8C106B006E; Wed, 11 Nov 2020 20:54:14 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A3A626B0070; Wed, 11 Nov 2020 20:54:14 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8DD3C6B0071; Wed, 11 Nov 2020 20:54:14 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0034.hostedemail.com [216.40.44.34]) by kanga.kvack.org (Postfix) with ESMTP id 5865B6B006E for ; Wed, 11 Nov 2020 20:54:14 -0500 (EST) Received: from smtpin12.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id F1074181AEF07 for ; Thu, 12 Nov 2020 01:54:13 +0000 (UTC) X-FDA: 77474095986.12.flame67_2007e5027302 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin12.hostedemail.com (Postfix) with ESMTP id CF5C81800F5BD for ; Thu, 12 Nov 2020 01:54:13 +0000 (UTC) X-Spam-Summary: 1,0,0,5341ac2def87bc26,d41d8cd98f00b204,3w5wsxwskckqpsoiwlkmhveksskpi.gsqpmryb-qqozego.svk@flex--lokeshgidra.bounces.google.com,,RULES_HIT:1:41:69:152:355:379:421:541:800:960:968:973:982:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:1801:2194:2198:2199:2200:2393:2553:2559:2562:2636:2693:2731:2892:2894:2898:2910:2911:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3874:4321:4425:4605:5007:6117:6119:6261:6653:6742:6743:7576:7875:7903:8568:9163:9969:10004:11026:11473:11658:11914:12043:12048:12291:12296:12297:12438:12555:12679:12683:12895:12986:13141:13161:13229:13230:14096:14097:14394:14659:21080:21222:21433:21444:21450:21451:21627:21990:30012:30029:30054:30070:30075:30090,0,RBL:209.85.210.201:@flex--lokeshgidra.bounces.google.com:.lbl8.mailshell.net-66.100.201.100 62.18.0.100;04yf6y7tofimb6goad43w6mws1t17ype5uzi3nmnjjzyyqo7bdtx68t6tw5hdqc.gqgn4f7ycimraayjeyyxgyqf7nof9rp1ojbrftruxdbewgrm7p3a3ei5jimht7j.k- lbl8.mai X-HE-Tag: flame67_2007e5027302 X-Filterd-Recvd-Size: 14471 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) by imf40.hostedemail.com (Postfix) with ESMTP for ; Thu, 12 Nov 2020 01:54:13 +0000 (UTC) Received: by mail-pf1-f201.google.com with SMTP id z125so2652714pfc.12 for ; Wed, 11 Nov 2020 17:54:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=3lqfRZtVZbvZzlKideU4HlR83ofeb2JRCxMe3NEILqc=; b=pdFjGdzJwu13zU0M/ASUiwCpli3mLLVPgtO6oabvuOWJu2ZP6zxWHqrFrIWAsQKvrJ OxOmpQOn6YZcjHoqviZ5TtjcLbUOkK6xCJypbCsuOnWgHTYNmmeGd3wzErIMA8sjwUEY FbFD3LT9IyF3iuyfAV19D6SWCiWgTvfJsDNSujCv9RXu1vMOe2D3wyQtqy5Gr0KsmU92 kzkXanNb6Z/EAGeE48pC8qjUp3i5E9A+MWGdzQdm/7k2d3xGohHv5VQ2yE3r+vXfNACk 84Nyc4K0WhhC91y/3PywLdJmN0Lfz9S1UDyuW8ctPDSSaumxKEoQvsetsPJc7yMK23aS VIMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=3lqfRZtVZbvZzlKideU4HlR83ofeb2JRCxMe3NEILqc=; b=OAz3GoTPM0pZ0zGFZiXEigTcCG4yfXC8BRNvNTa+WXRn3O0UXtkapnRAvJX4qA5inz 3sNPoKxF/ThKrMXO0CUvx9Q7JOFalxfBn3HxXfOqYcK3CgNK7L4ASXt0D+hHtBqTORs6 2NOBXsAai7cXZt1dJLSYoQ87RMp74GIBzCHAM5Bd8J929Sao6cna75kw3ROxIEBJ83ws c3Z9YeTHArzl8Y0O+z3V+apf7xD36zt/ZOKTHjao32jOkX60iGyCaTJDce1gJNvlKR/k pBJ1EYCzg1750hh+ztDVKp9JMOGEX0idVBtBdc8kLgatT8Ar6KGYGwaGrAN/uLXf9x+q kK7Q== X-Gm-Message-State: AOAM532Xf8RA8zn7ivAJ5RwgzpUuzr+fZOp3MzbVLRTK0BH8OrAeDvbL IfYLagb8IBFbeRvFmi+5pHRcKjvvK7D0YeJ3JQ== X-Google-Smtp-Source: ABdhPJzL7Ru2KFAyZ0V1LC4T/GMc65JRwkk3s3T+BmwMR4rs6T/ny4ewYAQd8DGrABQP7XiF39VbaUBCstlR4CGLZQ== X-Received: from lg.mtv.corp.google.com ([2620:15c:211:202:f693:9fff:fef4:29dd]) (user=lokeshgidra job=sendgmr) by 2002:a17:90b:293:: with SMTP id az19mr685557pjb.1.1605146051307; Wed, 11 Nov 2020 17:54:11 -0800 (PST) Date: Wed, 11 Nov 2020 17:53:57 -0800 In-Reply-To: <20201112015359.1103333-1-lokeshgidra@google.com> Message-Id: <20201112015359.1103333-3-lokeshgidra@google.com> Mime-Version: 1.0 References: <20201112015359.1103333-1-lokeshgidra@google.com> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog Subject: [PATCH v13 2/4] fs: add LSM-supporting anon-inode interface From: Lokesh Gidra To: Andrea Arcangeli , Alexander Viro , James Morris , Stephen Smalley , Casey Schaufler , Eric Biggers , Paul Moore Cc: "Serge E. Hallyn" , Eric Paris , Lokesh Gidra , Daniel Colascione , Kees Cook , "Eric W. Biederman" , KP Singh , David Howells , Anders Roxell , Sami Tolvanen , Matthew Garrett , Aaron Goidel , Randy Dunlap , "Joel Fernandes (Google)" , YueHaibing , Christian Brauner , Alexei Starovoitov , Alexey Budankov , Adrian Reber , Aleksa Sarai , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, kaleshsingh@google.com, calin@google.com, surenb@google.com, jeffv@google.com, kernel-team@android.com, linux-mm@kvack.org, Andrew Morton , hch@infradead.org, Daniel Colascione , Eric Biggers X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Daniel Colascione This change adds a new function, anon_inode_getfd_secure, that creates anonymous-node file with individual non-S_PRIVATE inode to which security modules can apply policy. Existing callers continue using the original singleton-inode kind of anonymous-inode file. We can transition anonymous inode users to the new kind of anonymous inode in individual patches for the sake of bisection and review. The new function accepts an optional context_inode parameter that callers can use to provide additional contextual information to security modules. For example, in case of userfaultfd, the created inode is a 'logical child' of the context_inode (userfaultfd inode of the parent process) in the sense that it provides the security context required during creation of the child process' userfaultfd inode. Signed-off-by: Daniel Colascione [Delete obsolete comments to alloc_anon_inode()] [Add context_inode description in comments to anon_inode_getfd_secure()] [Remove definition of anon_inode_getfile_secure() as there are no callers] [Make __anon_inode_getfile() static] [Use correct error cast in __anon_inode_getfile()] [Fix error handling in __anon_inode_getfile()] Signed-off-by: Lokesh Gidra Reviewed-by: Eric Biggers --- fs/anon_inodes.c | 150 ++++++++++++++++++++++++++---------- fs/libfs.c | 5 -- include/linux/anon_inodes.h | 5 ++ 3 files changed, 115 insertions(+), 45 deletions(-) diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 89714308c25b..023337d65a03 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -55,61 +55,79 @@ static struct file_system_type anon_inode_fs_type = { .kill_sb = kill_anon_super, }; -/** - * anon_inode_getfile - creates a new file instance by hooking it up to an - * anonymous inode, and a dentry that describe the "class" - * of the file - * - * @name: [in] name of the "class" of the new file - * @fops: [in] file operations for the new file - * @priv: [in] private data for the new file (will be file's private_data) - * @flags: [in] flags - * - * Creates a new file by hooking it on a single inode. This is useful for files - * that do not need to have a full-fledged inode in order to operate correctly. - * All the files created with anon_inode_getfile() will share a single inode, - * hence saving memory and avoiding code duplication for the file/inode/dentry - * setup. Returns the newly created file* or an error pointer. - */ -struct file *anon_inode_getfile(const char *name, - const struct file_operations *fops, - void *priv, int flags) +static struct inode *anon_inode_make_secure_inode( + const char *name, + const struct inode *context_inode) { - struct file *file; + struct inode *inode; + const struct qstr qname = QSTR_INIT(name, strlen(name)); + int error; + + inode = alloc_anon_inode(anon_inode_mnt->mnt_sb); + if (IS_ERR(inode)) + return inode; + inode->i_flags &= ~S_PRIVATE; + error = security_inode_init_security_anon(inode, &qname, context_inode); + if (error) { + iput(inode); + return ERR_PTR(error); + } + return inode; +} - if (IS_ERR(anon_inode_inode)) - return ERR_PTR(-ENODEV); +static struct file *__anon_inode_getfile(const char *name, + const struct file_operations *fops, + void *priv, int flags, + const struct inode *context_inode, + bool secure) +{ + struct inode *inode; + struct file *file; if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); - /* - * We know the anon_inode inode count is always greater than zero, - * so ihold() is safe. - */ - ihold(anon_inode_inode); - file = alloc_file_pseudo(anon_inode_inode, anon_inode_mnt, name, + if (secure) { + inode = anon_inode_make_secure_inode(name, context_inode); + if (IS_ERR(inode)) { + file = ERR_CAST(inode); + goto err; + } + } else { + inode = anon_inode_inode; + if (IS_ERR(inode)) { + file = ERR_PTR(-ENODEV); + goto err; + } + /* + * We know the anon_inode inode count is always + * greater than zero, so ihold() is safe. + */ + ihold(inode); + } + + file = alloc_file_pseudo(inode, anon_inode_mnt, name, flags & (O_ACCMODE | O_NONBLOCK), fops); if (IS_ERR(file)) - goto err; + goto err_iput; - file->f_mapping = anon_inode_inode->i_mapping; + file->f_mapping = inode->i_mapping; file->private_data = priv; return file; +err_iput: + iput(inode); err: - iput(anon_inode_inode); module_put(fops->owner); return file; } -EXPORT_SYMBOL_GPL(anon_inode_getfile); /** - * anon_inode_getfd - creates a new file instance by hooking it up to an - * anonymous inode, and a dentry that describe the "class" - * of the file + * anon_inode_getfile - creates a new file instance by hooking it up to an + * anonymous inode, and a dentry that describe the "class" + * of the file * * @name: [in] name of the "class" of the new file * @fops: [in] file operations for the new file @@ -118,12 +136,23 @@ EXPORT_SYMBOL_GPL(anon_inode_getfile); * * Creates a new file by hooking it on a single inode. This is useful for files * that do not need to have a full-fledged inode in order to operate correctly. - * All the files created with anon_inode_getfd() will share a single inode, + * All the files created with anon_inode_getfile() will share a single inode, * hence saving memory and avoiding code duplication for the file/inode/dentry - * setup. Returns new descriptor or an error code. + * setup. Returns the newly created file* or an error pointer. */ -int anon_inode_getfd(const char *name, const struct file_operations *fops, - void *priv, int flags) +struct file *anon_inode_getfile(const char *name, + const struct file_operations *fops, + void *priv, int flags) +{ + return __anon_inode_getfile(name, fops, priv, flags, NULL, false); +} +EXPORT_SYMBOL_GPL(anon_inode_getfile); + +static int __anon_inode_getfd(const char *name, + const struct file_operations *fops, + void *priv, int flags, + const struct inode *context_inode, + bool secure) { int error, fd; struct file *file; @@ -133,7 +162,8 @@ int anon_inode_getfd(const char *name, const struct file_operations *fops, return error; fd = error; - file = anon_inode_getfile(name, fops, priv, flags); + file = __anon_inode_getfile(name, fops, priv, flags, context_inode, + secure); if (IS_ERR(file)) { error = PTR_ERR(file); goto err_put_unused_fd; @@ -146,8 +176,48 @@ int anon_inode_getfd(const char *name, const struct file_operations *fops, put_unused_fd(fd); return error; } + +/** + * anon_inode_getfd - creates a new file instance by hooking it up to + * an anonymous inode and a dentry that describe + * the "class" of the file + * + * @name: [in] name of the "class" of the new file + * @fops: [in] file operations for the new file + * @priv: [in] private data for the new file (will be file's private_data) + * @flags: [in] flags + * + * Creates a new file by hooking it on a single inode. This is + * useful for files that do not need to have a full-fledged inode in + * order to operate correctly. All the files created with + * anon_inode_getfd() will use the same singleton inode, reducing + * memory use and avoiding code duplication for the file/inode/dentry + * setup. Returns a newly created file descriptor or an error code. + */ +int anon_inode_getfd(const char *name, const struct file_operations *fops, + void *priv, int flags) +{ + return __anon_inode_getfd(name, fops, priv, flags, NULL, false); +} EXPORT_SYMBOL_GPL(anon_inode_getfd); +/** + * Like anon_inode_getfd(), but creates a new !S_PRIVATE anon inode rather than + * reuse the singleton anon inode, and calls the inode_init_security_anon() LSM + * hook. This allows the inode to have its own security context and for a LSM + * to reject creation of the inode. An optional @context_inode argument is + * also added to provide the logical relationship with the new inode. The LSM + * may use @context_inode in inode_init_security_anon(), but a reference to it + * is not held. + */ +int anon_inode_getfd_secure(const char *name, const struct file_operations *fops, + void *priv, int flags, + const struct inode *context_inode) +{ + return __anon_inode_getfd(name, fops, priv, flags, context_inode, true); +} +EXPORT_SYMBOL_GPL(anon_inode_getfd_secure); + static int __init anon_inode_init(void) { anon_inode_mnt = kern_mount(&anon_inode_fs_type); diff --git a/fs/libfs.c b/fs/libfs.c index fc34361c1489..51c19c72e563 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1212,11 +1212,6 @@ static int anon_set_page_dirty(struct page *page) return 0; }; -/* - * A single inode exists for all anon_inode files. Contrary to pipes, - * anon_inode inodes have no associated per-instance data, so we need - * only allocate one of them. - */ struct inode *alloc_anon_inode(struct super_block *s) { static const struct address_space_operations anon_aops = { diff --git a/include/linux/anon_inodes.h b/include/linux/anon_inodes.h index d0d7d96261ad..71881a2b6f78 100644 --- a/include/linux/anon_inodes.h +++ b/include/linux/anon_inodes.h @@ -10,12 +10,17 @@ #define _LINUX_ANON_INODES_H struct file_operations; +struct inode; struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags); int anon_inode_getfd(const char *name, const struct file_operations *fops, void *priv, int flags); +int anon_inode_getfd_secure(const char *name, + const struct file_operations *fops, + void *priv, int flags, + const struct inode *context_inode); #endif /* _LINUX_ANON_INODES_H */ From patchwork Thu Nov 12 01:53:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Gidra X-Patchwork-Id: 11898873 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0C661391 for ; Thu, 12 Nov 2020 01:54:18 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 4F1E8206CA for ; Thu, 12 Nov 2020 01:54:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="Mz0/RepG" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4F1E8206CA Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 8E0CA6B0071; Wed, 11 Nov 2020 20:54:16 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 840206B0072; Wed, 11 Nov 2020 20:54:16 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6B90F6B0073; Wed, 11 Nov 2020 20:54:16 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0037.hostedemail.com [216.40.44.37]) by kanga.kvack.org (Postfix) with ESMTP id 339E26B0071 for ; Wed, 11 Nov 2020 20:54:16 -0500 (EST) Received: from smtpin06.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id D610E8249980 for ; Thu, 12 Nov 2020 01:54:15 +0000 (UTC) X-FDA: 77474096070.06.bat16_0f0731327302 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin06.hostedemail.com (Postfix) with ESMTP id B54A11003CA90 for ; Thu, 12 Nov 2020 01:54:15 +0000 (UTC) X-Spam-Summary: 1,0,0,dd512e5d80d3d9c0,d41d8cd98f00b204,3xpwsxwskckcsvrlzonpkyhnvvnsl.jvtspube-ttrchjr.vyn@flex--lokeshgidra.bounces.google.com,,RULES_HIT:41:152:355:379:541:800:960:966:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1535:1544:1593:1594:1711:1730:1747:1777:1792:2196:2199:2393:2559:2562:2894:2910:3138:3139:3140:3141:3142:3152:3355:3865:3866:3867:3868:3870:3871:3874:4119:4250:4321:4385:4605:5007:6117:6119:6261:6653:6742:6743:7576:7903:9969:10004:11026:11473:11658:11914:12043:12048:12291:12296:12297:12438:12555:12679:12895:12986:13143:13161:13229:13230:14181:14394:14659:14721:14799:21080:21433:21444:21451:21627:21740:21990:30029:30054:30070,0,RBL:209.85.219.201:@flex--lokeshgidra.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100;04ygafatnhjwzig3z3ighejfjde38yc3snci5bseasmkxpuqxd6w8qkyyt1kky4.6m79qa7coefwo9u5hpsfqt9zdkwczux8qc8zj3j53di9f3aitehnh4sw99k3hd4.s-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none ,DomainC X-HE-Tag: bat16_0f0731327302 X-Filterd-Recvd-Size: 8246 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) by imf11.hostedemail.com (Postfix) with ESMTP for ; Thu, 12 Nov 2020 01:54:15 +0000 (UTC) Received: by mail-yb1-f201.google.com with SMTP id b189so4295083ybh.5 for ; Wed, 11 Nov 2020 17:54:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=EKdfgxKmgqyWOrEoFelO0xo4xUprR4kVgmmY5QtMneA=; b=Mz0/RepGCaX9VPHW6LKYUdkGuWwDxdRh602UW+erQ9khnSph5lnBFq+8u9tT4GDxaS ckxAoj4jIZb/X+96/D7EN4p3mRLqrhrRnE3AxR4nd3qOi6FK1e/Z6XUKmdBv0V52oHoi fnRSEC7tE+8O3CSNKd8dbNMYYBVswtN2GpJKmuRoeXfgAY2LAq6yldLOmIxmMhutphYm j4fhBnd140Pi1Ckyo33E5c9jKyWfJ37HDd6ORnuKewANEJvZfovjkYwOABiS+IlQOpEn QIjD4OMXTdg/iDGYGT+UyppMyuf4rtDyeeBOjhzp9egpqH7d6TWO6igQsuhW95l5hcfa uSuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=EKdfgxKmgqyWOrEoFelO0xo4xUprR4kVgmmY5QtMneA=; b=A9ALF4LXgkFatYIEzinDFST7EBQvIjYARQrqyZzUyMh/pn9Ob0i80cynJrE1V6UWdE B+vAoof056OBQ2x9UiXTi5horc5mx7J/KCjdGhrztuScNje2McCA2efySStEtuq7ib9b Z+ehTWmBeCS+kUQYEGg5fGrJ1uFe1ot1zQo/oUpgnP8cbL7mPg3NazaAhtTMFxls2c+P Yrk5CvQqxkO/rD2o2v+hD3UtEyn4p0cHtJBGHslMPtFQ7GO8NhW6OxcCp2lHYRGJsDCK 3lz/15Kb1+cTgRGflhx8ZEBaI2uqcGeKVns8cCpf0rY+hrqxSVx2XctBaNndOiOLopTG CD0Q== X-Gm-Message-State: AOAM532X+7qP296j3flmQ6k3L9h2zCU8k0ahem8mBv6I1ME1UteM6SID wqIyipEtMo4X4y9c89EZ/bfA6DKqzgL77Ppccg== X-Google-Smtp-Source: ABdhPJzFSv/Xdn7GGdy2MUG7BhSbdefjZ9hVJ+MOvRURjTp6rSFxYr2XLTCAi7JOZcqE2J6h4zH58KP3k6BneY9sdA== X-Received: from lg.mtv.corp.google.com ([2620:15c:211:202:f693:9fff:fef4:29dd]) (user=lokeshgidra job=sendgmr) by 2002:a25:bc42:: with SMTP id d2mr6737406ybk.461.1605146054397; Wed, 11 Nov 2020 17:54:14 -0800 (PST) Date: Wed, 11 Nov 2020 17:53:58 -0800 In-Reply-To: <20201112015359.1103333-1-lokeshgidra@google.com> Message-Id: <20201112015359.1103333-4-lokeshgidra@google.com> Mime-Version: 1.0 References: <20201112015359.1103333-1-lokeshgidra@google.com> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog Subject: [PATCH v13 3/4] selinux: teach SELinux about anonymous inodes From: Lokesh Gidra To: Andrea Arcangeli , Alexander Viro , James Morris , Stephen Smalley , Casey Schaufler , Eric Biggers , Paul Moore Cc: "Serge E. Hallyn" , Eric Paris , Lokesh Gidra , Daniel Colascione , Kees Cook , "Eric W. Biederman" , KP Singh , David Howells , Anders Roxell , Sami Tolvanen , Matthew Garrett , Aaron Goidel , Randy Dunlap , "Joel Fernandes (Google)" , YueHaibing , Christian Brauner , Alexei Starovoitov , Alexey Budankov , Adrian Reber , Aleksa Sarai , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, kaleshsingh@google.com, calin@google.com, surenb@google.com, jeffv@google.com, kernel-team@android.com, linux-mm@kvack.org, Andrew Morton , hch@infradead.org, Daniel Colascione X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Daniel Colascione This change uses the anon_inodes and LSM infrastructure introduced in the previous patches to give SELinux the ability to control anonymous-inode files that are created using the new anon_inode_getfd_secure() function. A SELinux policy author detects and controls these anonymous inodes by adding a name-based type_transition rule that assigns a new security type to anonymous-inode files created in some domain. The name used for the name-based transition is the name associated with the anonymous inode for file listings --- e.g., "[userfaultfd]" or "[perf_event]". Example: type uffd_t; type_transition sysadm_t sysadm_t : anon_inode uffd_t "[userfaultfd]"; allow sysadm_t uffd_t:anon_inode { create }; (The next patch in this series is necessary for making userfaultfd support this new interface. The example above is just for exposition.) Signed-off-by: Daniel Colascione Signed-off-by: Lokesh Gidra --- security/selinux/hooks.c | 56 +++++++++++++++++++++++++++++ security/selinux/include/classmap.h | 2 ++ 2 files changed, 58 insertions(+) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6b1826fc3658..d092aa512868 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2927,6 +2927,61 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, return 0; } +static int selinux_inode_init_security_anon(struct inode *inode, + const struct qstr *name, + const struct inode *context_inode) +{ + const struct task_security_struct *tsec = selinux_cred(current_cred()); + struct common_audit_data ad; + struct inode_security_struct *isec; + int rc; + + if (unlikely(!selinux_initialized(&selinux_state))) + return 0; + + isec = selinux_inode(inode); + + /* + * We only get here once per ephemeral inode. The inode has + * been initialized via inode_alloc_security but is otherwise + * untouched. + */ + + if (context_inode) { + struct inode_security_struct *context_isec = + selinux_inode(context_inode); + if (context_isec->initialized != LABEL_INITIALIZED) + return -EACCES; + + isec->sclass = context_isec->sclass; + isec->sid = context_isec->sid; + } else { + isec->sclass = SECCLASS_ANON_INODE; + rc = security_transition_sid( + &selinux_state, tsec->sid, tsec->sid, + isec->sclass, name, &isec->sid); + if (rc) + return rc; + } + + isec->initialized = LABEL_INITIALIZED; + + /* + * Now that we've initialized security, check whether we're + * allowed to actually create this type of anonymous inode. + */ + + ad.type = LSM_AUDIT_DATA_INODE; + ad.u.inode = inode; + + return avc_has_perm(&selinux_state, + tsec->sid, + isec->sid, + isec->sclass, + ANON_INODE__CREATE, + &ad); +} + static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode) { return may_create(dir, dentry, SECCLASS_FILE); @@ -6992,6 +7047,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security), LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security), + LSM_HOOK_INIT(inode_init_security_anon, selinux_inode_init_security_anon), LSM_HOOK_INIT(inode_create, selinux_inode_create), LSM_HOOK_INIT(inode_link, selinux_inode_link), LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink), diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 40cebde62856..ba2e01a6955c 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -249,6 +249,8 @@ struct security_class_mapping secclass_map[] = { {"open", "cpu", "kernel", "tracepoint", "read", "write"} }, { "lockdown", { "integrity", "confidentiality", NULL } }, + { "anon_inode", + { COMMON_FILE_PERMS, NULL } }, { NULL } }; From patchwork Thu Nov 12 01:53:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Gidra X-Patchwork-Id: 11898875 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4F2CD139F for ; Thu, 12 Nov 2020 01:54:21 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id F1A412076E for ; Thu, 12 Nov 2020 01:54:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="KHw/IjNn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F1A412076E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 5F8496B0073; Wed, 11 Nov 2020 20:54:19 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 5829F6B0074; Wed, 11 Nov 2020 20:54:19 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 386DB6B0075; Wed, 11 Nov 2020 20:54:19 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0122.hostedemail.com [216.40.44.122]) by kanga.kvack.org (Postfix) with ESMTP id 098B06B0073 for ; Wed, 11 Nov 2020 20:54:18 -0500 (EST) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 9E5AF181AEF07 for ; Thu, 12 Nov 2020 01:54:18 +0000 (UTC) X-FDA: 77474096196.13.yard45_00047ba27302 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin13.hostedemail.com (Postfix) with ESMTP id 6FBFC18140B67 for ; Thu, 12 Nov 2020 01:54:18 +0000 (UTC) X-Spam-Summary: 1,0,0,637cc426eedb2b93,d41d8cd98f00b204,3yzwsxwskckovyuocrqsnbkqyyqvo.mywvsxeh-wwufkmu.ybq@flex--lokeshgidra.bounces.google.com,,RULES_HIT:41:152:355:379:541:800:960:966:968:973:982:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:2196:2199:2393:2559:2562:2894:2910:3138:3139:3140:3141:3142:3152:3353:3865:3866:3867:3870:4118:4321:4385:4605:5007:6261:6653:6742:6743:7576:7903:8531:9969:10004:10400:11026:11473:11658:11914:12043:12048:12296:12297:12438:12555:12679:12895:14181:14394:14659:14721:21080:21324:21433:21444:21451:21627:21990:30045:30051:30054:30070,0,RBL:209.85.219.202:@flex--lokeshgidra.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100;04yf5f83sn7bx1qzzdaq1djqd33y9op4tbohj1ztwrw756qg51gxp17tcraaas1.a1ehgqz59uycddcdjt717prj3eygb7p57ou5cr7jhq11wmwbh3ea51kaa53eucd.g-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL :neutral X-HE-Tag: yard45_00047ba27302 X-Filterd-Recvd-Size: 7566 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) by imf14.hostedemail.com (Postfix) with ESMTP for ; Thu, 12 Nov 2020 01:54:17 +0000 (UTC) Received: by mail-yb1-f202.google.com with SMTP id a6so4004795ybi.0 for ; Wed, 11 Nov 2020 17:54:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=P1DeZBXMBKdtEUpa7z1m8DxvFC3ulFf31LohQa26mKY=; b=KHw/IjNnKXINcRHDWgmqRHd0Zj1R0TpCpGkfvcK6YinJS9r0qY95sipaMLev7KDQLY SHvrOKRhjJK/mVp8a2oe/RxC2epBcB4njCqmWfs/WJHD+XSU5QvqOVEHfZc9DzUV2DcX zvqrzF0nu1YXHO7NObYOQnEFk4pdkrB3+mkT3SwMmpSZzlzC9Jvb4efewCRlLMHHReAr y+PEqn1JjuD/WISS3WPqtUOBmtQfpr/LIvNvH62uiqNkMDSkz882tB2/qHaRI5oWZ15r gJ1ll23udno6hVYcfe5GHleYlRSKx9Y3ylFdqS06NbLX0XzLLHFeN8khM45k+brEDzWy bIbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=P1DeZBXMBKdtEUpa7z1m8DxvFC3ulFf31LohQa26mKY=; b=dxfWo0dZQmMC7rv9lCz4h3y4qGhw0XP9TYzI/YK/p5Wqnc0QcR4fr2laPV9sG7IWKf ZpPsrSmMjTxObtabfPiyeijqfxYYvtltDaD8Dj6GkwEcbvOHY1fpOwHyL4jp/PY1y+4E vl4YaC+oTrjp4jbEpVvALDFnvwFsnUMdYeyUYSwU3SSJkyZ0K3cEIlFY9fuUCyIZ7krq ZWzpkoNyA5XqZjAV7nLorTtH2TwYuIlFHy8OfFTUg0OphlBVjc6Ps8Tpv71c3p/0zFiu jmiwUnAbGw8yFZDRkcEG6KyUMJ78pTneWD9R7b+zE3Y4KXBt9wK+8C/GyK45acJKhe+H 7xLA== X-Gm-Message-State: AOAM530mpzYwElWNmv/7WUKAWf/c2H1eFA8L1xnNIdi3KU9mYrb6wINq +EPDXvaLTR4jlLUw89ddw9phHVXJ+SOysx2Sgw== X-Google-Smtp-Source: ABdhPJzeZK4CgcTcXxnvjBUkLa6KfV72dT9Gdn9uAHIiX/UDZe+AdtYjzlUXrrU731++FmFjMGYes+NLu+clHGl60Q== X-Received: from lg.mtv.corp.google.com ([2620:15c:211:202:f693:9fff:fef4:29dd]) (user=lokeshgidra job=sendgmr) by 2002:a25:80cd:: with SMTP id c13mr42308074ybm.371.1605146057270; Wed, 11 Nov 2020 17:54:17 -0800 (PST) Date: Wed, 11 Nov 2020 17:53:59 -0800 In-Reply-To: <20201112015359.1103333-1-lokeshgidra@google.com> Message-Id: <20201112015359.1103333-5-lokeshgidra@google.com> Mime-Version: 1.0 References: <20201112015359.1103333-1-lokeshgidra@google.com> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog Subject: [PATCH v13 4/4] userfaultfd: use secure anon inodes for userfaultfd From: Lokesh Gidra To: Andrea Arcangeli , Alexander Viro , James Morris , Stephen Smalley , Casey Schaufler , Eric Biggers , Paul Moore Cc: "Serge E. Hallyn" , Eric Paris , Lokesh Gidra , Daniel Colascione , Kees Cook , "Eric W. Biederman" , KP Singh , David Howells , Anders Roxell , Sami Tolvanen , Matthew Garrett , Aaron Goidel , Randy Dunlap , "Joel Fernandes (Google)" , YueHaibing , Christian Brauner , Alexei Starovoitov , Alexey Budankov , Adrian Reber , Aleksa Sarai , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, kaleshsingh@google.com, calin@google.com, surenb@google.com, jeffv@google.com, kernel-team@android.com, linux-mm@kvack.org, Andrew Morton , hch@infradead.org, Daniel Colascione , Eric Biggers X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Daniel Colascione This change gives userfaultfd file descriptors a real security context, allowing policy to act on them. Signed-off-by: Daniel Colascione [Remove owner inode from userfaultfd_ctx] [Use anon_inode_getfd_secure() instead of anon_inode_getfile_secure() in userfaultfd syscall] [Use inode of file in userfaultfd_read() in resolve_userfault_fork()] Signed-off-by: Lokesh Gidra Reviewed-by: Eric Biggers --- fs/userfaultfd.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 000b457ad087..dd78daf06de6 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -972,14 +972,14 @@ static __poll_t userfaultfd_poll(struct file *file, poll_table *wait) static const struct file_operations userfaultfd_fops; -static int resolve_userfault_fork(struct userfaultfd_ctx *ctx, - struct userfaultfd_ctx *new, +static int resolve_userfault_fork(struct userfaultfd_ctx *new, + struct inode *inode, struct uffd_msg *msg) { int fd; - fd = anon_inode_getfd("[userfaultfd]", &userfaultfd_fops, new, - O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS)); + fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, new, + O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode); if (fd < 0) return fd; @@ -989,7 +989,7 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *ctx, } static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait, - struct uffd_msg *msg) + struct uffd_msg *msg, struct inode *inode) { ssize_t ret; DECLARE_WAITQUEUE(wait, current); @@ -1100,7 +1100,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait, spin_unlock_irq(&ctx->fd_wqh.lock); if (!ret && msg->event == UFFD_EVENT_FORK) { - ret = resolve_userfault_fork(ctx, fork_nctx, msg); + ret = resolve_userfault_fork(fork_nctx, inode, msg); spin_lock_irq(&ctx->event_wqh.lock); if (!list_empty(&fork_event)) { /* @@ -1160,6 +1160,7 @@ static ssize_t userfaultfd_read(struct file *file, char __user *buf, ssize_t _ret, ret = 0; struct uffd_msg msg; int no_wait = file->f_flags & O_NONBLOCK; + struct inode *inode = file_inode(file); if (ctx->state == UFFD_STATE_WAIT_API) return -EINVAL; @@ -1167,7 +1168,7 @@ static ssize_t userfaultfd_read(struct file *file, char __user *buf, for (;;) { if (count < sizeof(msg)) return ret ? ret : -EINVAL; - _ret = userfaultfd_ctx_read(ctx, no_wait, &msg); + _ret = userfaultfd_ctx_read(ctx, no_wait, &msg, inode); if (_ret < 0) return ret ? ret : _ret; if (copy_to_user((__u64 __user *) buf, &msg, sizeof(msg))) @@ -1985,8 +1986,8 @@ SYSCALL_DEFINE1(userfaultfd, int, flags) /* prevent the mm struct to be freed */ mmgrab(ctx->mm); - fd = anon_inode_getfd("[userfaultfd]", &userfaultfd_fops, ctx, - O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS)); + fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, ctx, + O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL); if (fd < 0) { mmdrop(ctx->mm); kmem_cache_free(userfaultfd_ctx_cachep, ctx);