Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp5390568ybv; Tue, 11 Feb 2020 14:57:40 -0800 (PST) X-Google-Smtp-Source: APXvYqzFUqDG8bLkYxm66pVhwqRW0Ga6cnVJ8m5AamRLn2T11SKRpgd3cL9E5xjUjpwb9CXJYi9O X-Received: by 2002:aca:ea43:: with SMTP id i64mr4503782oih.30.1581461860085; Tue, 11 Feb 2020 14:57:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581461860; cv=none; d=google.com; s=arc-20160816; b=tyRkaJDRqqCOMXWBEsLVB9tsxYjAzNIGiy1s6X56T6zbwhAQ+XOD9NcmLY3Q3qsTxg xd6a+mlP4pqLeCoz6sm2sdOmjsshaf9uc4CGfFXSoclgG1ao1rp/DSm9L0XL8LjB1vnf hiGXUMICmsC9GAexMQRaM4Acfit7uD0gN3mAAptrKZbJHzX2C0jGcSua+d11KSNeWDmx D7zPQYICXx5/WdhU9OXWQiqJiWQWXh64KeBkOlO9csAdGJhyzEPI8wClh+cDjVa18PVH KvditIlmLlNnhTiQ0J+9WRh1mt7ocqFajuvwd0oN92GZva/KNhw1XjOudyRYCCgOEnjp 6SkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=vHcKO3QArnYrq5IS1lBB+LSw7l3zk+6PTDFMKlLqjVY=; b=x+XXXiyLxyX2HPN2dhJnvevmkJXJOLRxNORpG4xrLjJFEdC9s5vjgRUrzZYC66EQP4 1qE7mclb19cgIrnlrkvHf+WVmWKFWGuBurULmf+VMh0eY1dwDS/oMcKmIYTsifNZZQAh NZZejr1aBsnLmsOfMTcJcrSErFsyyP9kGiZPPjCFYPrrTpMEn8hWq+f1iVhCteKUqZ2F wQwwnDeMHXboUzBJqW99usNyFmQ6ByRWW7b9YY9CYpzxfdyXyCaDRCQoimoGsOBjfSzx wmdqqwAh5SqtqrOyoacwAjx3Ud9R7mbyZ0BkJaFLnF7gLUgBfq0QzT0E1bmgAXUG2WWC +Lag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=gxgroxdp; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a22si2507863otp.84.2020.02.11.14.57.28; Tue, 11 Feb 2020 14:57:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=gxgroxdp; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727850AbgBKW4T (ORCPT + 99 others); Tue, 11 Feb 2020 17:56:19 -0500 Received: from mail-pg1-f202.google.com ([209.85.215.202]:57199 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727838AbgBKW4S (ORCPT ); Tue, 11 Feb 2020 17:56:18 -0500 Received: by mail-pg1-f202.google.com with SMTP id a4so106188pgm.23 for ; Tue, 11 Feb 2020 14:56:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to; bh=vHcKO3QArnYrq5IS1lBB+LSw7l3zk+6PTDFMKlLqjVY=; b=gxgroxdpy5apY+CiXlDvZ3ykbKxa6+DwISy7zYL64iaChm9WJXkU2eLLN7um5g8isj BOhtMjfkisilUoD1Djqg2bvSgeeDHdBVCYxg2Ut2KaCKn2bl6700QGsUZD+HoyobtI+E WiwDPOQmNQpSTpbyT6EdUAc4+QZV3rZA5o/dXf4j8wiHg3U3a3pxbBgMQ/16RGiBTBTX ajTB2PSHjdqaBEHWdmpxBJKkTVtdeF+C8Tvar0wr/jL0Ka+18+lZ9tN2a3pflblIv5vq vVR55P8bXSH7XwmnU+/GxqhJ/TP+Ku/aEAUmTpRXwSmZwzNylmwgsWmfUyDmDQEZkrFf wfOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to; bh=vHcKO3QArnYrq5IS1lBB+LSw7l3zk+6PTDFMKlLqjVY=; b=PB33JClrLR/fThXqQZaDh5yvGbFqzbRy1ZkzMYlFDgZEcYW/hpWFmQBZ5LKxTa6WUo iwXhGy4UumAo7CmTPwkx+rdxQbLOl/jD6Kk3h+7X4zNDDRxw9j3lctF87StaLhPBFZXT IURjjqiN4bMRlHnwd1BnWJBpAJ0fmbS989ZBzgumF1lky+pSQ+4A0SF6BuKCl1y/5esD sJo0m98n2KWPB+2yf58TKVAvETIHAkDIqoZVdIdcJoX5C0PaFt75oaBeJQe1gHcRhzA+ HAukGHMYp4/87xTccXFWDP433knUDCLxVb5UzQ53Ed02+sL7+Wl0Befhz3zuYOglzGND 9pRg== X-Gm-Message-State: APjAAAUH2BmAQNPh/TwoJIJlkzshIEdVuwkRYaWjvvGO7oTMyobLZSdV r9V7kV9K6f/nh0GuMN5Vmgo+fs0BVBg= X-Received: by 2002:a63:594a:: with SMTP id j10mr9436698pgm.227.1581461776754; Tue, 11 Feb 2020 14:56:16 -0800 (PST) Date: Tue, 11 Feb 2020 14:55:44 -0800 In-Reply-To: <20200211225547.235083-1-dancol@google.com> Message-Id: <20200211225547.235083-4-dancol@google.com> Mime-Version: 1.0 References: <20200211225547.235083-1-dancol@google.com> X-Mailer: git-send-email 2.25.0.225.g125e21ebc7-goog Subject: [PATCH v2 3/6] Teach SELinux about a new userfaultfd class From: Daniel Colascione To: dancol@google.com, timmurray@google.com, nosh@google.com, nnk@google.com, lokeshgidra@google.com, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, selinux@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use the secure anonymous inode LSM hook we just added to let SELinux policy place restrictions on userfaultfd use. The create operation applies to processes creating new instances of these file objects; transfer between processes is covered by restrictions on read, write, and ioctl access already checked inside selinux_file_receive. Signed-off-by: Daniel Colascione --- fs/userfaultfd.c | 4 +- include/linux/userfaultfd_k.h | 2 + security/selinux/hooks.c | 68 +++++++++++++++++++++++++++++ security/selinux/include/classmap.h | 2 + 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 37df7c9eedb1..07b0f6e03849 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -1014,8 +1014,6 @@ 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, struct uffd_msg *msg) @@ -1920,7 +1918,7 @@ static void userfaultfd_show_fdinfo(struct seq_file *m, struct file *f) } #endif -static const struct file_operations userfaultfd_fops = { +const struct file_operations userfaultfd_fops = { #ifdef CONFIG_PROC_FS .show_fdinfo = userfaultfd_show_fdinfo, #endif diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h index ac9d71e24b81..549c8b0cca52 100644 --- a/include/linux/userfaultfd_k.h +++ b/include/linux/userfaultfd_k.h @@ -30,6 +30,8 @@ extern int sysctl_unprivileged_userfaultfd; +extern const struct file_operations userfaultfd_fops; + extern vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason); extern ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1659b59fb5d7..e178f6f40e93 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -92,6 +92,10 @@ #include #include +#ifdef CONFIG_USERFAULTFD +#include +#endif + #include "avc.h" #include "objsec.h" #include "netif.h" @@ -2915,6 +2919,69 @@ 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 char *name, + const struct file_operations *fops) +{ + const struct task_security_struct *tsec = selinux_cred(current_cred()); + struct common_audit_data ad; + struct inode_security_struct *isec; + + if (unlikely(IS_PRIVATE(inode))) + return 0; + + /* + * We shouldn't be creating secure anonymous inodes before LSM + * initialization completes. + */ + if (unlikely(!selinux_state.initialized)) + return -EBUSY; + + 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, so check that the state is as + * inode_alloc_security left it. + */ + BUG_ON(isec->initialized != LABEL_INVALID); + BUG_ON(isec->sclass != SECCLASS_FILE); + +#ifdef CONFIG_USERFAULTFD + if (fops == &userfaultfd_fops) + isec->sclass = SECCLASS_UFFD; +#endif + + if (isec->sclass == SECCLASS_FILE) { + printk(KERN_WARNING "refusing to create secure anonymous inode " + "of unknown type"); + return -EOPNOTSUPP; + } + /* + * Always give secure anonymous inodes the sid of the + * creating task. + */ + + isec->sid = tsec->sid; + 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, + FILE__CREATE, + &ad); +} + static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode) { return may_create(dir, dentry, SECCLASS_FILE); @@ -6923,6 +6990,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 986f3ac14282..6d4f9ebf2017 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -248,6 +248,8 @@ struct security_class_mapping secclass_map[] = { {"open", "cpu", "kernel", "tracepoint", "read", "write"} }, { "lockdown", { "integrity", "confidentiality", NULL } }, + { "uffd", + { COMMON_FILE_PERMS, NULL } }, { NULL } }; -- 2.25.0.225.g125e21ebc7-goog