Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp2989525imm; Sun, 1 Jul 2018 09:49:24 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJ7If46z3Jc3VP1oaKVS9hj3M4MHg6Mys4C6WnyY2TmkkP2nwqfTg+p8oB+YAJt2kawQR+T X-Received: by 2002:a17:902:2f43:: with SMTP id s61-v6mr22525448plb.274.1530463764737; Sun, 01 Jul 2018 09:49:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530463764; cv=none; d=google.com; s=arc-20160816; b=XZZZZYikDFA883KeSHf5yyXqEWs9Lc9SxF8arYfKskLaJcNkl/qkjADbHF/6B+0dDm vNVfwWK4lDjmy9TLDV5RZ6NQY0o5oAYSdyUTA0TV0xZcoBpwFGjJFz2gFd0oqQxnU1kO OIhznUOiTbuB+YpJ9wrlJGv6dwHjvN5Lfb4JIFalaDjM2pfe88BFYelgoLAJqsb6cZ57 eEV4+LPs0WexZQfhPcC42RHEtzfhvmiGpvv7zMumhZkI4TwogocqQM61MFdCl3lthO/2 9JRXS9TJGHe0cCNsnAOTRnmQHihqQmAnbGKnCK41deQPBuTKwX1e5Mi0qdR4wNHPFKK+ 9wew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=FgcwIdLz7H6xeCQxZFRJNGsZMYwd4r9r3++pCnpsDUI=; b=RNQ2Smrygyjvdm94B/dxr0Z+T3DKuPbzmy4WGcNbpZBmCfZZ8Ctwm2Xi5XGeHZRPVK aQ1le4Sl5YKez6thX3uy+wzfKJ6v7oL5+gpaAjXcHG9BvWPbVfYtEUpWM4Wcyiev8NCI B9UTn2NoHgZMzglVv/qMJdf6AJ2hJTUaNoHHEn81FxXBm6bOfHWUDFj9yECsXbop21G+ MKuQfXgjhpkU3vwE66xY8Up3POJh/vCexRxTVfrAl1CuIyig+avFceuOiJbnD+qpiDzb ijEYEePmEltHiqcCWPfLM+7LvBO+JRx7lCmyowyDj7uwTn02v6xhzumARESLKyWlkaZc 6yFw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o1-v6si14041044pld.424.2018.07.01.09.49.10; Sun, 01 Jul 2018 09:49:24 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1032331AbeGAQqi (ORCPT + 99 others); Sun, 1 Jul 2018 12:46:38 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:38470 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753759AbeGAQqf (ORCPT ); Sun, 1 Jul 2018 12:46:35 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 97177ACC; Sun, 1 Jul 2018 16:46:34 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jann Horn , Stephen Smalley , Paul Moore Subject: [PATCH 4.17 215/220] selinux: move user accesses in selinuxfs out of locked regions Date: Sun, 1 Jul 2018 18:23:59 +0200 Message-Id: <20180701160917.128390570@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180701160908.272447118@linuxfoundation.org> References: <20180701160908.272447118@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 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 4.17-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jann Horn commit 0da74120c5341389b97c4ee27487a97224999ee1 upstream. If a user is accessing a file in selinuxfs with a pointer to a userspace buffer that is backed by e.g. a userfaultfd, the userspace access can stall indefinitely, which can block fsi->mutex if it is held. For sel_read_policy(), remove the locking, since this method doesn't seem to access anything that requires locking. For sel_read_bool(), move the user access below the locked region. For sel_write_bool() and sel_commit_bools_write(), move the user access up above the locked region. Cc: stable@vger.kernel.org Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Jann Horn Acked-by: Stephen Smalley [PM: removed an unused variable in sel_read_policy()] Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- security/selinux/selinuxfs.c | 78 ++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 45 deletions(-) --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -435,22 +435,16 @@ static int sel_release_policy(struct ino static ssize_t sel_read_policy(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { - struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info; struct policy_load_memory *plm = filp->private_data; int ret; - mutex_lock(&fsi->mutex); - ret = avc_has_perm(&selinux_state, current_sid(), SECINITSID_SECURITY, SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL); if (ret) - goto out; + return ret; - ret = simple_read_from_buffer(buf, count, ppos, plm->data, plm->len); -out: - mutex_unlock(&fsi->mutex); - return ret; + return simple_read_from_buffer(buf, count, ppos, plm->data, plm->len); } static int sel_mmap_policy_fault(struct vm_fault *vmf) @@ -1182,25 +1176,29 @@ static ssize_t sel_read_bool(struct file ret = -EINVAL; if (index >= fsi->bool_num || strcmp(name, fsi->bool_pending_names[index])) - goto out; + goto out_unlock; ret = -ENOMEM; page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) - goto out; + goto out_unlock; cur_enforcing = security_get_bool_value(fsi->state, index); if (cur_enforcing < 0) { ret = cur_enforcing; - goto out; + goto out_unlock; } length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, fsi->bool_pending_values[index]); - ret = simple_read_from_buffer(buf, count, ppos, page, length); -out: mutex_unlock(&fsi->mutex); + ret = simple_read_from_buffer(buf, count, ppos, page, length); +out_free: free_page((unsigned long)page); return ret; + +out_unlock: + mutex_unlock(&fsi->mutex); + goto out_free; } static ssize_t sel_write_bool(struct file *filep, const char __user *buf, @@ -1213,6 +1211,17 @@ static ssize_t sel_write_bool(struct fil unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK; const char *name = filep->f_path.dentry->d_name.name; + if (count >= PAGE_SIZE) + return -ENOMEM; + + /* No partial writes. */ + if (*ppos != 0) + return -EINVAL; + + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) + return PTR_ERR(page); + mutex_lock(&fsi->mutex); length = avc_has_perm(&selinux_state, @@ -1227,22 +1236,6 @@ static ssize_t sel_write_bool(struct fil fsi->bool_pending_names[index])) goto out; - length = -ENOMEM; - if (count >= PAGE_SIZE) - goto out; - - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) - goto out; - - page = memdup_user_nul(buf, count); - if (IS_ERR(page)) { - length = PTR_ERR(page); - page = NULL; - goto out; - } - length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) goto out; @@ -1274,6 +1267,17 @@ static ssize_t sel_commit_bools_write(st ssize_t length; int new_value; + if (count >= PAGE_SIZE) + return -ENOMEM; + + /* No partial writes. */ + if (*ppos != 0) + return -EINVAL; + + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) + return PTR_ERR(page); + mutex_lock(&fsi->mutex); length = avc_has_perm(&selinux_state, @@ -1283,22 +1287,6 @@ static ssize_t sel_commit_bools_write(st if (length) goto out; - length = -ENOMEM; - if (count >= PAGE_SIZE) - goto out; - - /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) - goto out; - - page = memdup_user_nul(buf, count); - if (IS_ERR(page)) { - length = PTR_ERR(page); - page = NULL; - goto out; - } - length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) goto out;