Received: by 10.192.165.156 with SMTP id m28csp271127imm; Tue, 17 Apr 2018 09:53:23 -0700 (PDT) X-Google-Smtp-Source: AIpwx48NWvck9GCvJJOL16FpRyg1lRtMzUPOBeG1oY0Wa7ImIUrHHrSQSP42ePfAJa/wqAIu7tnU X-Received: by 2002:a17:902:bc3:: with SMTP id 61-v6mr2733415plr.117.1523984003392; Tue, 17 Apr 2018 09:53:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523984003; cv=none; d=google.com; s=arc-20160816; b=naj14jV6ksbtrck83se3ialntgefud6NTLPC4q8meQGnhY6djt8718Mz6zES9GNsqU 7b9/i/y0yL/GvAgaWDJ4DWyxYKcsYpdHtsDllzQjyou6Mz9iIpo/0Zs1r5ZzWTVc/Cds FV1ZjMLQMtq5Ce1KvdFQovCBfv0nw8cIvhU7vrVYD1i7eFcd1lTAafmvyC0IhBs61kKO ysra+woHp9TFxtD1zjxB+9L1Pn5D9nkxXBN9bjHF5Lo+4FMxB3bRONkPJ2crv1oJWZQY X2Pw76sNhPtTAUwzJBjulGdbsmqT0JYgtPD196bIidxYT/aemkC2JXXakfzcFKjFcsx6 QuQQ== 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=Tx/Pqtg9RfugCyMh9O0h/MKXQfZReCdCN8ICY6qDyxw=; b=SdeZieY3ZZP1zwVcefrYdhhSf3RRGPUDZ93Xn5iNjek+jzLy8RztDzus0aDYuBq6qN LKqTeqQOfpfWDlGmVHVwZSnNvNFlo7uyb5VazpMd5PD13yd2rODeu0k51siVeEDRB0AD Ke/zOknso+8cTx1SV7JKzaWyQaitJHy8qPhMRhzqF8VUIwaVoEqDRPQNb/zhYSdY7PXv JOlOhcsXyQMMVpv1vKLkIL3TK6Z5bfbxiuAp/PePz9bfQxRTaepYlUcB2+M5YW8yTlKZ VVBwXd5krT+AXGeK+nnPYGC2gi5NI+HkDBRmsQ6HYPx0/Fx9M+ASVb7Lkw0Jxpmnjmoj 7pmg== 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 y10si7655352pgr.672.2018.04.17.09.53.09; Tue, 17 Apr 2018 09:53:23 -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 S1754547AbeDQQwD (ORCPT + 99 others); Tue, 17 Apr 2018 12:52:03 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:34240 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754499AbeDQQEi (ORCPT ); Tue, 17 Apr 2018 12:04:38 -0400 Received: from localhost (unknown [46.44.180.42]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id A2231CF2; Tue, 17 Apr 2018 16:04:30 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lucash Stach , "J. Bruce Fields" Subject: [PATCH 4.15 36/53] nfsd: fix incorrect umasks Date: Tue, 17 Apr 2018 17:59:01 +0200 Message-Id: <20180417155724.893176389@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180417155723.091120060@linuxfoundation.org> References: <20180417155723.091120060@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.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: J. Bruce Fields commit 880a3a5325489a143269a8e172e7563ebf9897bc upstream. We're neglecting to clear the umask after it's set, which can cause a later unrelated rpc to (incorrectly) use the same umask if it happens to be processed by the same thread. There's a more subtle problem here too: An NFSv4 compound request is decoded all in one pass before any operations are executed. Currently we're setting current->fs->umask at the time we decode the compound. In theory a single compound could contain multiple creates each setting a umask. In that case we'd end up using whichever umask was passed in the *last* operation as the umask for all the creates, whether that was correct or not. So, we should just be saving the umask at decode time and waiting to set it until we actually process the corresponding operation. In practice it's unlikely any client would do multiple creates in a single compound. And even if it did they'd likely be from the same process (hence carry the same umask). So this is a little academic, but we should get it right anyway. Fixes: 47057abde515 (nfsd: add support for the umask attribute) Cc: stable@vger.kernel.org Reported-by: Lucash Stach Signed-off-by: J. Bruce Fields Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4proc.c | 12 ++++++++++-- fs/nfsd/nfs4xdr.c | 8 +++----- fs/nfsd/xdr4.h | 2 ++ 3 files changed, 15 insertions(+), 7 deletions(-) --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -32,6 +32,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -252,11 +253,13 @@ do_open_lookup(struct svc_rqst *rqstp, s * Note: create modes (UNCHECKED,GUARDED...) are the same * in NFSv4 as in v3 except EXCLUSIVE4_1. */ + current->fs->umask = open->op_umask; status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &open->op_iattr, *resfh, open->op_createmode, (u32 *)open->op_verf.data, &open->op_truncate, &open->op_created); + current->fs->umask = 0; if (!status && open->op_label.len) nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval); @@ -603,6 +606,7 @@ nfsd4_create(struct svc_rqst *rqstp, str if (status) return status; + current->fs->umask = create->cr_umask; switch (create->cr_type) { case NF4LNK: status = nfsd_symlink(rqstp, &cstate->current_fh, @@ -611,20 +615,22 @@ nfsd4_create(struct svc_rqst *rqstp, str break; case NF4BLK: + status = nfserr_inval; rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); if (MAJOR(rdev) != create->cr_specdata1 || MINOR(rdev) != create->cr_specdata2) - return nfserr_inval; + goto out_umask; status = nfsd_create(rqstp, &cstate->current_fh, create->cr_name, create->cr_namelen, &create->cr_iattr, S_IFBLK, rdev, &resfh); break; case NF4CHR: + status = nfserr_inval; rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); if (MAJOR(rdev) != create->cr_specdata1 || MINOR(rdev) != create->cr_specdata2) - return nfserr_inval; + goto out_umask; status = nfsd_create(rqstp, &cstate->current_fh, create->cr_name, create->cr_namelen, &create->cr_iattr,S_IFCHR, rdev, &resfh); @@ -668,6 +674,8 @@ nfsd4_create(struct svc_rqst *rqstp, str fh_dup2(&cstate->current_fh, &resfh); out: fh_put(&resfh); +out_umask: + current->fs->umask = 0; return status; } --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -33,7 +33,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include @@ -683,7 +682,7 @@ nfsd4_decode_create(struct nfsd4_compoun status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, &create->cr_acl, &create->cr_label, - ¤t->fs->umask); + &create->cr_umask); if (status) goto out; @@ -928,7 +927,6 @@ nfsd4_decode_open(struct nfsd4_compounda case NFS4_OPEN_NOCREATE: break; case NFS4_OPEN_CREATE: - current->fs->umask = 0; READ_BUF(4); open->op_createmode = be32_to_cpup(p++); switch (open->op_createmode) { @@ -936,7 +934,7 @@ nfsd4_decode_open(struct nfsd4_compounda case NFS4_CREATE_GUARDED: status = nfsd4_decode_fattr(argp, open->op_bmval, &open->op_iattr, &open->op_acl, &open->op_label, - ¤t->fs->umask); + &open->op_umask); if (status) goto out; break; @@ -951,7 +949,7 @@ nfsd4_decode_open(struct nfsd4_compounda COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE); status = nfsd4_decode_fattr(argp, open->op_bmval, &open->op_iattr, &open->op_acl, &open->op_label, - ¤t->fs->umask); + &open->op_umask); if (status) goto out; break; --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -118,6 +118,7 @@ struct nfsd4_create { } u; u32 cr_bmval[3]; /* request */ struct iattr cr_iattr; /* request */ + int cr_umask; /* request */ struct nfsd4_change_info cr_cinfo; /* response */ struct nfs4_acl *cr_acl; struct xdr_netobj cr_label; @@ -228,6 +229,7 @@ struct nfsd4_open { u32 op_why_no_deleg; /* response - DELEG_NONE_EXT only */ u32 op_create; /* request */ u32 op_createmode; /* request */ + int op_umask; /* request */ u32 op_bmval[3]; /* request */ struct iattr op_iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ nfs4_verifier op_verf __attribute__((aligned(32)));