Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp2546229ybp; Sat, 12 Oct 2019 12:17:36 -0700 (PDT) X-Google-Smtp-Source: APXvYqxsXy7yBy8SRm3rgF9UOn8y8QHk7tfE2JluPStM2WinvV0iHM329qLGsijURytZlCT+SKVY X-Received: by 2002:a17:906:6b88:: with SMTP id l8mr20345919ejr.26.1570907856550; Sat, 12 Oct 2019 12:17:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570907856; cv=none; d=google.com; s=arc-20160816; b=JKgtVS036PFyUXWHRluXtbFMUnQdRXkEIiKSRiWjhF3b81mgz1Vh+KbJ+xAK6Mlpmq sdq9rc+QTk4KcbDNhqGEPBlMpVIAuhHU9fYH+irdxdzyP6jyZFKxGNL6jRI31X2dMMlR 8nwdIm/K5oAHvzJJlP4x/irq5umvPVerrJ+XnJIp7L3O0FMZCBNkAkT8hkfkTbL/NYjV aVjMMYhSJN8fioeI4x1RKUhzSceYymYZ1NHlvQBaMuNzG63yHq3kTghH1R9AJAlTE9kX 2TihAB8+OW2pEb/u5wBWkgqBh/oRVUleW+IpbexqmkFmfxGJ8ebGilt2crA7+8G9EBDg ctxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=6PNxQptqFZv6r7KIq1szAGaXtND1cZM6S6IWMEOmUXc=; b=MdmJhcSf1U/YwRmoJJAEnTnlS8WbyvTWwE824ADGUTndA53jrlh5O+TGiyD/v3ymgh HJ8Vn21ZVxSTgUDS7Um1EQkPIcXlskdm7GxAEM7w9RTRlwhkS5saQXBGZ2nTn/gdb7GQ IDVCFztJdvHQ+MIPsseFz7k2W/rFzcPHkj/9FMQXUFXG5CT6C5dSPicgC+nYuZiO0j35 OAiNLzD1STDokiojS06EUxZnd5eaX4/ZA+uerO4P2IXnLgyGQ5U3G7+Eesx9zljfvh02 XuvXScngApmZ1zBrthX38mg+wROmQnvvbkwOC5pmnNyfQlYbWTyt5y6ef9kXUBqppype Z6dw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=GvtWWssI; 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 b4si7986553edq.221.2019.10.12.12.17.12; Sat, 12 Oct 2019 12:17:36 -0700 (PDT) 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=GvtWWssI; 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 S1729713AbfJLTQY (ORCPT + 99 others); Sat, 12 Oct 2019 15:16:24 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:33001 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729679AbfJLTQT (ORCPT ); Sat, 12 Oct 2019 15:16:19 -0400 Received: by mail-pf1-f201.google.com with SMTP id z4so10244952pfn.0 for ; Sat, 12 Oct 2019 12:16:19 -0700 (PDT) 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 :cc; bh=6PNxQptqFZv6r7KIq1szAGaXtND1cZM6S6IWMEOmUXc=; b=GvtWWssIS1EIVUdbLh2WfKcReIx5BeqxA4y/iDMumOgVaRZjvAvOsXv2DSrj7efJkA BMKEqFhC1gwAktf1nwfztGDt5cXsm4YwKEuEImuVTBSuVmcaK/cfh1RnH9n3jlBeNaEf oAy6C7zroHshvIt5v5qI3DPxyYYfoZ95UlKhxcymO4AcE+OZkxs+HSiG8h9ADevFq61/ kNwLX6vZ6RHGWtRlyKegsKtqLhslkrQCr0WWEyz9lccyMc0Lh4Wm0gh6yLDdrdsKS5L+ CA2+kbo3A9wlFHEueQCU+2drPOIHVmvsSHLZB7Uqy65VKVMA2dPDPY+hA2ZRUrNencyP R4rw== 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:cc; bh=6PNxQptqFZv6r7KIq1szAGaXtND1cZM6S6IWMEOmUXc=; b=SrcV+3lRBKEBUc6WNCOfzeLFDntnonRBVK+Pq97XCXgvOuQSy8NheXkrCXod9nuDy9 IihaNpmB0Bp4w/8mH//PdDRLzBs5A+wcj0vXIbxPjt3NN5sd1QZVgkSJbq0c4INGcggl GaYuLd+wqxq948paqvG5gsll+ZHA3T1Vr1R5UjMqBXDIamqk7Rfz8CTz7DH1FqFBd2Fw GkWWGUdxN5azwfpk+11b4xnkWX86LRGxVbnq1y05jUCJTRV2S8lzScvyCS5KVQ63mrH9 ILlMLEe0uCF4wmFVbMJjWEcca02VlW1BcxzZ1MNYbf2q7dWHOCPAAUMCMxzRGKHiMqHX 6MtQ== X-Gm-Message-State: APjAAAUF5SA8yD1Hhq5rIVmbMjdNVVj2XAWl+30HftCzWhrcT5XDdDwo iItus44Ib8HWXoOH7lVyT2fC98BkV+A= X-Received: by 2002:a65:62d2:: with SMTP id m18mr23615514pgv.117.1570907778962; Sat, 12 Oct 2019 12:16:18 -0700 (PDT) Date: Sat, 12 Oct 2019 12:15:59 -0700 In-Reply-To: <20191012191602.45649-1-dancol@google.com> Message-Id: <20191012191602.45649-5-dancol@google.com> Mime-Version: 1.0 References: <20191012191602.45649-1-dancol@google.com> X-Mailer: git-send-email 2.23.0.700.g56cf767bdb-goog Subject: [PATCH 4/7] Teach SELinux about a new userfaultfd class From: Daniel Colascione To: linux-api@vger.kernel.org, linux-kernel@vger.kernel.org, lokeshgidra@google.com, dancol@google.com, nnk@google.com Cc: nosh@google.com, timmurray@google.com 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 29f920fb236e..1123089c3d55 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) @@ -1934,7 +1932,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 9625b99e677f..0b3a36cbfbdc 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" @@ -2943,6 +2947,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); @@ -6840,6 +6907,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security), 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 32e9b03be3dd..41bc5da78048 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -244,6 +244,8 @@ struct security_class_mapping secclass_map[] = { {"map_create", "map_read", "map_write", "prog_load", "prog_run"} }, { "xdp_socket", { COMMON_SOCK_PERMS, NULL } }, + { "uffd", + { COMMON_FILE_PERMS, NULL } }, { NULL } }; -- 2.23.0.700.g56cf767bdb-goog