From patchwork Tue May 19 08:13:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 1293106 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Nf2JVT9S; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49R7ts1Pnsz9sT8 for ; Tue, 19 May 2020 18:13:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726329AbgESINk (ORCPT ); Tue, 19 May 2020 04:13:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726318AbgESINk (ORCPT ); Tue, 19 May 2020 04:13:40 -0400 Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C992AC061A0C for ; Tue, 19 May 2020 01:13:39 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id 190so13840314qki.1 for ; Tue, 19 May 2020 01:13:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=z1aKyGVstSxgvZKBf5pLwF1xs8pWkWrTSVxdLEZi1Ys=; b=Nf2JVT9SRwdYsi5cCsOn7TMmWYY2Y+WCV5BQxO50WGsFmspIkPQje+rX4m70FHrImX 4Lq2X0UxWNLPwcyVHxhYm4T8oXfGBEitplRY/4NwQ3AOR4QF9/jGnvTxIWQYQ1RFeWm/ D+MVFJp3Wddqp1YtvJcSkEC0DUsmEljQAc9kFxFrMGgQpUrxPcYhCjs/UluMaiGPbT+E juWTXm2nGyXpCw6g+tYNGwzKCR8emRfX/K0htvE29qNmBgLSSAoF1H3g6Oss9CXrWv6p rkjTmTerkTvJHEtAoe1A+Oqw8x7Plo6tPnHxOrOo+QW7uzixUPV+YmTv8+nYuZsXvaq4 7Qpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=z1aKyGVstSxgvZKBf5pLwF1xs8pWkWrTSVxdLEZi1Ys=; b=anZKl73f5QKHE6iWU52pXylrvoRuSaP3KLYxlP3dxO+65IFVncvlhC7mbtroqKfm4u 0Pw7rZ0qkzOSBAeY0/y7v9niACgL9dCT3xWGqB1E7sho4XkxrWB+bbHE2mDaREvVh8Zw S/K+HBcPj/MypYLkwmoHjYSF+/kNy08Lj4Cb7IfMafP3fG/Olqh/xcYZzgR2tKUQaAjY 3/1HjeUi5Kjy0Uhmi9senENd5sI2w0132bGQdkWxdQuO7DgKfLbGK2pQN0f3BNmgCYpZ KFpEIxqko3PNjUi7sN1jTSdT+t2sbv5fYzq9OOIa88KNXtGKPZ5kAuAC0196Wp3j/LP0 D10g== X-Gm-Message-State: AOAM531ICqTwEPtcVwx/tD7ng1yca2uK+mk+OmRw5LsRmhaAR/Gqtnyp Zq/uwIr/gT5tH9CDeM6ouvzdCY4bjU3ATkI46LNxt/Ql X-Google-Smtp-Source: ABdhPJytLx/CPHm7lK3+8J6jvt5eTuhU6Vkq0KJoAgxVo/iCsTG7kRM1H76JXcNLBmZ/ZIjP3JuoPjVFA8MUCc0hNPs= X-Received: by 2002:a25:d6c3:: with SMTP id n186mr27235649ybg.375.1589876018746; Tue, 19 May 2020 01:13:38 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Tue, 19 May 2020 03:13:28 -0500 Message-ID: Subject: [PATCH][CIFS] Add 'nodelete' mount parm To: CIFS Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org In order to handle workloads where it is important to make sure that a buggy app did not delete content on the drive, the new mount option "nodelete" allows standard permission checks on the server to work, but prevents on the client any attempts to unlink a file or delete a directory on that mount point. This can be helpful when running a little understood app on a network mount that contains important content that should not be deleted. Reviewed-by: Pavel Shilovsky From 2755388f5e8b5c6dc949fa0108d3210e818ca883 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 19 May 2020 03:06:57 -0500 Subject: [PATCH] smb3: Add new parm "nodelete" In order to handle workloads where it is important to make sure that a buggy app did not delete content on the drive, the new mount option "nodelete" allows standard permission checks on the server to work, but prevents on the client any attempts to unlink a file or delete a directory on that mount point. This can be helpful when running a little understood app on a network mount that contains important content that should not be deleted. Signed-off-by: Steve French CC: Stable --- fs/cifs/cifsfs.c | 2 ++ fs/cifs/cifsglob.h | 2 ++ fs/cifs/connect.c | 9 ++++++++- fs/cifs/inode.c | 11 +++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index c31f362fa098..889f9c71049b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -534,6 +534,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_puts(s, ",signloosely"); if (tcon->nocase) seq_puts(s, ",nocase"); + if (tcon->nodelete) + seq_puts(s, ",nodelete"); if (tcon->local_lease) seq_puts(s, ",locallease"); if (tcon->retry) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 39b708d9d86d..4d261fd78fcb 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -562,6 +562,7 @@ struct smb_vol { bool override_gid:1; bool dynperm:1; bool noperm:1; + bool nodelete:1; bool mode_ace:1; bool no_psx_acl:1; /* set if posix acl support should be disabled */ bool cifs_acl:1; @@ -1136,6 +1137,7 @@ struct cifs_tcon { bool retry:1; bool nocase:1; bool nohandlecache:1; /* if strange server resource prob can turn off */ + bool nodelete:1; bool seal:1; /* transport encryption for this mounted share */ bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol for this mount even if server would support */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 62503fbed2ab..cde7ff55f0a3 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -75,7 +75,7 @@ enum { Opt_forceuid, Opt_noforceuid, Opt_forcegid, Opt_noforcegid, Opt_noblocksend, Opt_noautotune, Opt_nolease, - Opt_hard, Opt_soft, Opt_perm, Opt_noperm, + Opt_hard, Opt_soft, Opt_perm, Opt_noperm, Opt_nodelete, Opt_mapposix, Opt_nomapposix, Opt_mapchars, Opt_nomapchars, Opt_sfu, Opt_nosfu, Opt_nodfs, Opt_posixpaths, @@ -141,6 +141,7 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_soft, "soft" }, { Opt_perm, "perm" }, { Opt_noperm, "noperm" }, + { Opt_nodelete, "nodelete" }, { Opt_mapchars, "mapchars" }, /* SFU style */ { Opt_nomapchars, "nomapchars" }, { Opt_mapposix, "mapposix" }, /* SFM style */ @@ -1761,6 +1762,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, case Opt_noperm: vol->noperm = 1; break; + case Opt_nodelete: + vol->nodelete = 1; + break; case Opt_mapchars: vol->sfu_remap = true; vol->remap = false; /* disable SFM mapping */ @@ -3363,6 +3367,8 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info) return 0; if (tcon->no_lease != volume_info->no_lease) return 0; + if (tcon->nodelete != volume_info->nodelete) + return 0; return 1; } @@ -3598,6 +3604,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) tcon->retry = volume_info->retry; tcon->nocase = volume_info->nocase; tcon->nohandlecache = volume_info->nohandlecache; + tcon->nodelete = volume_info->nodelete; tcon->local_lease = volume_info->local_lease; INIT_LIST_HEAD(&tcon->pending_opens); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 5d2965a23730..873b1effd412 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1418,6 +1418,11 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) xid = get_xid(); + if (tcon->nodelete) { + rc = -EACCES; + goto unlink_out; + } + /* Unlink can be called from rename so we can not take the * sb->s_vfs_rename_mutex here */ full_path = build_path_from_dentry(dentry); @@ -1746,6 +1751,12 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) goto rmdir_exit; } + if (tcon->nodelete) { + rc = -EACCES; + cifs_put_tlink(tlink); + goto rmdir_exit; + } + rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb); cifs_put_tlink(tlink); -- 2.25.1