Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp5083764imm; Tue, 26 Jun 2018 05:43:53 -0700 (PDT) X-Google-Smtp-Source: AAOMgpeJsJBqF0J8TAJNwhzuvHjcfYndzIq7WGnsCzpvJ/U1h0DpzEPxB8xmNPKo5G39+vnYU+PL X-Received: by 2002:aa7:808f:: with SMTP id v15-v6mr1455596pff.38.1530017033376; Tue, 26 Jun 2018 05:43:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530017033; cv=none; d=google.com; s=arc-20160816; b=ZOF2ZQnqh0qceQoe+olC5PBO9LlT5/IBlj7FVss5brofcgixqWFBVNc/bCOnG68vU7 RTfQrYCmVZZu+7zb4ZOo7VxN8D6GvJSF8QOcENr3pBL/yCKvbPNKs4eM+Ymx17tooJuU 03k8Kf3VnnR01gu6IuWJnFHX/0Wzqrkqx0fqinKm64hkL3r1EK/CFQPV0b/SPLzyeUVV ZhzTINXYwDfqKIRD6LfyzzXyc4PEUryhZWD58wXCtI5kLzY6m1tEJ06KVWnTOD+FGMYL m2snZnIB3EjPcBBJPQzRY1TuR6Xyg8mR1/6MlIXkyU1FT1vXhLgNxsCue/prfTk2CsWI Rp7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature :arc-authentication-results; bh=7eLYNtASiDOAlMoqr1YfWqB7aTxNWIQ6KuRvStP7jJY=; b=0WytDEvH2FwPyWzJAcwGSHKFHEp3RLi88jv8IJXF2Y9rr/J4n+KmbOxsCWwrWaWKIQ pzg/Qy2Itt5XzrUndzZYOSWsTe37SGakFVDxbeY+bcOInOgmry0vJbFAaKkFnKZCYgak 1zrBlZPMgrb2FdR9nn8QHO8nhWejxnWwFuN/wjhGGOnPtrsKe4W/3mLy/btqlR7mCwVS oS3vyuxPEngt3lRUOG7Nq4r+vJZAoQR1ksSQOEaplzTCJksGEi2576zxSk63S/M77uPY R5qONjd+Mxyee0HKM0lCVtWYds/k5Jm3MXcc73X6KC/zOjb+LrdFfXnemxzzJfOhxwWP nDdg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=S7xqszTv; 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 h12-v6si1224101pgq.48.2018.06.26.05.43.38; Tue, 26 Jun 2018 05:43:53 -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=S7xqszTv; 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 S934865AbeFZMm5 (ORCPT + 99 others); Tue, 26 Jun 2018 08:42:57 -0400 Received: from mail-oi0-f67.google.com ([209.85.218.67]:35825 "EHLO mail-oi0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932438AbeFZMm4 (ORCPT ); Tue, 26 Jun 2018 08:42:56 -0400 Received: by mail-oi0-f67.google.com with SMTP id e8-v6so15853192oii.2 for ; Tue, 26 Jun 2018 05:42:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=7eLYNtASiDOAlMoqr1YfWqB7aTxNWIQ6KuRvStP7jJY=; b=S7xqszTvOHl1zUssczwNZMJ46hU210tWfzZ/ddDQ/PuCleRclRLmCxS0KH7U5N5J6h fDgiWzuDOGofQabaG3VJEH2WNe+WfqksuaIWLNopr9AY39+tB/YMHZKW25rFegYLVMO+ jdCGB4cYXAP31xCHU43Gchg1eMFIXOibO/Nt6ezyDmdzkYzpsWlzNNfujnGytVmbUlFl 29MpgYSsfM4WE9Myt/T7rN7DfyUrMEZ45adHDyf9mdHDy90N3DG5o36ageor8MIKvakL DmyH9jN3lDQlXQVr5To7dH7PSYf/YsLuxMvlSMDZH2Z112zK+A61njRR69bvlsGp+n6D erpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=7eLYNtASiDOAlMoqr1YfWqB7aTxNWIQ6KuRvStP7jJY=; b=bO4Ndq4rEUWg7l5D/DwXmkgb+oCPtgdeZFjLEidwEl0AyD3fyt0kdtUL/S7L4/lE+j 09u3GqJQmlXrjsVunAcUbkcx5AhGtyQisnpF0itl0REOR9u3FVLiMPtj9VnflUGnWH2V CPWgL/5dy9h1AKpXSWLV7IJegDkeXl1L9Lj+G0Ko8YRDIGRFBQB3jEpIzTYDgqgqq4ZO HmyceZjBVTuyc33qejWZ5Tqb1LBRTgcEDG50H4AMgl3LGYYDzJJSVYF4yL/VfTYHbIv9 K6Kbl3hgPgFsG66oldxrSpye4I3O1Dm6GAPGVPwZL40xZexjhwqOUeqNETEc9q/7m18J rUwA== X-Gm-Message-State: APt69E0SDty73S6Pgf/56ehULcIkWYDmKmALKvB8CVtLM74bjZH2K5uY ggCSW+XzHYcc1+Jz27scUAvhn1rUkp8U4zEQ8osmig== X-Received: by 2002:aca:5bd5:: with SMTP id p204-v6mr781807oib.91.1530016975567; Tue, 26 Jun 2018 05:42:55 -0700 (PDT) MIME-Version: 1.0 References: <20180625163425.216965-1-jannh@google.com> <9d5d0cb7-5875-0814-835b-097db650b6a1@tycho.nsa.gov> In-Reply-To: <9d5d0cb7-5875-0814-835b-097db650b6a1@tycho.nsa.gov> From: Jann Horn Date: Tue, 26 Jun 2018 14:42:43 +0200 Message-ID: Subject: Re: [PATCH] selinux: move user accesses in selinuxfs out of locked regions To: Stephen Smalley Cc: Paul Moore , Eric Paris , selinux@tycho.nsa.gov, security@kernel.org, kernel list 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 On Tue, Jun 26, 2018 at 2:15 PM Stephen Smalley wrote: > > On 06/25/2018 12:34 PM, Jann Horn wrote: > > 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 > > Only question I have is wrt the Fixes line, i.e. was this an issue until userfaultfd was introduced, and if not, > do we need it to be back-ported any further than the commit which introduced it. You can also use FUSE, if the system is configured appropriately: Mount a FUSE filesystem, mmap() a file from it, then pass a pointer to the mmapped region to a syscall. AFAICS FUSE was added to the kernel in commit d8a5ba45457e4a22aa39c939121efd7bb6c76672, first in v2.6.16.28. > Otherwise, you can add my > Acked-by: Stephen Smalley This patch should go through Paul Moore's tree, right? > > --- > > security/selinux/selinuxfs.c | 77 ++++++++++++++++-------------------- > > 1 file changed, 33 insertions(+), 44 deletions(-) > > > > diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c > > index f3d374d2ca04..065f8cea84e3 100644 > > --- a/security/selinux/selinuxfs.c > > +++ b/security/selinux/selinuxfs.c > > @@ -445,18 +445,13 @@ static ssize_t sel_read_policy(struct file *filp, char __user *buf, > > 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 vm_fault_t sel_mmap_policy_fault(struct vm_fault *vmf) > > @@ -1188,25 +1183,29 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, > > 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, > > @@ -1219,6 +1218,17 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, > > 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, > > @@ -1233,22 +1243,6 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, > > 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; > > @@ -1280,6 +1274,17 @@ static ssize_t sel_commit_bools_write(struct file *filep, > > 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, > > @@ -1289,22 +1294,6 @@ static ssize_t sel_commit_bools_write(struct file *filep, > > 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; > > >