From patchwork Thu Dec 7 12:38:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13483247 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PhO7ziab" Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F67210D for ; Thu, 7 Dec 2023 04:38:36 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-3332f1512e8so803016f8f.2 for ; Thu, 07 Dec 2023 04:38:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701952714; x=1702557514; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=X9M7pWIKBdDtotGC+N9xKXKIlgNDiYwgLVF9+Q4cIDk=; b=PhO7ziab4/J8ndmeN+oLfUDZvzrHpkDPPH6kw4GR6wn5QQ61E3TVGBpbCvfAsvaNhq 9tfMtf49+E8wfxCeUMrc8CWJK83dXCWHzgcPgFiR8jOD8ELceHLVvBi0T7OXLgH7MMs6 RJVS7fW+O5BcJerOiet8KzjQ58CDYuYD33GhcK22MatUIvU6syJf07WAlJIDVN8Dztzg /7CxAr6OXW23pp0sqh+sRldpuCYFyMcCMXCyGFfqyzf+oZTzkD7mPjHJ2jQelhQkpSFk R604/xbXFWH9mmZ2wV9/B9yuioqDfnPeQOj4ONWEuHaQq1BO9ZOtAYy2/hcdYEnBnleO eIDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701952714; x=1702557514; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X9M7pWIKBdDtotGC+N9xKXKIlgNDiYwgLVF9+Q4cIDk=; b=mUX+w2yIDuknhjz/et7Dv+gaweTniEk/3TJuXbYrqyPtJgc2NmjI4sxCaTsrrogJgn 79obYKmxYP3Z43uv6J/nYAip7rQbjwhIcWE2eNOyrIuYOnZRNghutsin5xjVtjeLtoO/ AHZcSI1skgBN5LhAaFmI8FYJMi7v2kW6CTLFdUVrT60N65vLac5St+C7HNL1nJzJEAaG fYvKCSwKW/VBeCnEOEIRrXeK8mFXZMhIa3hfbNzaDEAvSk0uWILZ0ZWY1N1YhcY3R5KW rvRDkAC0r75ASMIoAHcVMKJgrzuAZyGIarW8KOg43uy+ZYE9NNIaY4/P0DR7/7ZG7x0g KrQw== X-Gm-Message-State: AOJu0YydcHB/WIjkm1WjT0diH0laOYa8MlKLC700M/hoCBcaXEIyGSyw KFbuOZvfoa1jZdSAPtulJYc= X-Google-Smtp-Source: AGHT+IFuNkGJnJ7z8NF7XAiBnkmGVYD+i+ZNuROCpZmkt74hS+PzoM8fa0aHL/7Eqm3authfIkUjNg== X-Received: by 2002:a05:6000:4f0:b0:333:42ac:2009 with SMTP id cr16-20020a05600004f000b0033342ac2009mr1460686wrb.96.1701952714300; Thu, 07 Dec 2023 04:38:34 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id z17-20020a5d4c91000000b003333abf3edfsm1332431wrs.47.2023.12.07.04.38.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Dec 2023 04:38:33 -0800 (PST) From: Amir Goldstein To: Christian Brauner , Jan Kara Cc: Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH 1/4] fs: use splice_copy_file_range() inline helper Date: Thu, 7 Dec 2023 14:38:22 +0200 Message-Id: <20231207123825.4011620-2-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207123825.4011620-1-amir73il@gmail.com> References: <20231207123825.4011620-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 generic_copy_file_range() is just a wrapper around splice_file_range(). Move the wrapper to splice.h and rename it to splice_copy_file_range(). Suggested-by: Christoph Hellwig Link: https://lore.kernel.org/linux-fsdevel/20231204083849.GC32438@lst.de/ Signed-off-by: Amir Goldstein Reviewed-by: Jan Kara --- fs/ceph/file.c | 4 ++-- fs/fuse/file.c | 5 +++-- fs/nfs/nfs4file.c | 5 +++-- fs/read_write.c | 34 ---------------------------------- fs/smb/client/cifsfs.c | 5 +++-- fs/splice.c | 2 +- include/linux/fs.h | 3 --- include/linux/splice.h | 8 ++++++++ 8 files changed, 20 insertions(+), 46 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index f11de6e1f1c1..d380d9dad0e0 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -3090,8 +3090,8 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, len, flags); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(src_file, src_off, dst_file, - dst_off, len, flags); + ret = splice_copy_file_range(src_file, src_off, dst_file, + dst_off, len); return ret; } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a660f1f21540..148a71b8b4d0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -19,6 +19,7 @@ #include #include #include +#include static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, unsigned int open_flags, int opcode, @@ -3195,8 +3196,8 @@ static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off, len, flags); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(src_file, src_off, dst_file, - dst_off, len, flags); + ret = splice_copy_file_range(src_file, src_off, dst_file, + dst_off, len); return ret; } diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 02788c3c85e5..e238abc78a13 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "delegation.h" #include "internal.h" #include "iostat.h" @@ -195,8 +196,8 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, ret = __nfs4_copy_file_range(file_in, pos_in, file_out, pos_out, count, flags); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(file_in, pos_in, file_out, - pos_out, count, flags); + ret = splice_copy_file_range(file_in, pos_in, file_out, + pos_out, count); return ret; } diff --git a/fs/read_write.c b/fs/read_write.c index 01a14570015b..97a9d5c7ad96 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1396,40 +1396,6 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, } #endif -/** - * generic_copy_file_range - copy data between two files - * @file_in: file structure to read from - * @pos_in: file offset to read from - * @file_out: file structure to write data to - * @pos_out: file offset to write data to - * @len: amount of data to copy - * @flags: copy flags - * - * This is a generic filesystem helper to copy data from one file to another. - * It has no constraints on the source or destination file owners - the files - * can belong to different superblocks and different filesystem types. Short - * copies are allowed. - * - * This should be called from the @file_out filesystem, as per the - * ->copy_file_range() method. - * - * Returns the number of bytes copied or a negative error indicating the - * failure. - */ - -ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t len, unsigned int flags) -{ - /* May only be called from within ->copy_file_range() methods */ - if (WARN_ON_ONCE(flags)) - return -EINVAL; - - return splice_file_range(file_in, &pos_in, file_out, &pos_out, - min_t(size_t, len, MAX_RW_COUNT)); -} -EXPORT_SYMBOL(generic_copy_file_range); - /* * Performs necessary checks before doing a file copy * diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index ea3a7a668b45..ee461bf0ef63 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1362,8 +1363,8 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, free_xid(xid); if (rc == -EOPNOTSUPP || rc == -EXDEV) - rc = generic_copy_file_range(src_file, off, dst_file, - destoff, len, flags); + rc = splice_copy_file_range(src_file, off, dst_file, + destoff, len); return rc; } diff --git a/fs/splice.c b/fs/splice.c index 7cda013e5a1e..24bd93f8e4c3 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1243,7 +1243,7 @@ EXPORT_SYMBOL(do_splice_direct); * @len: number of bytes to splice * * Description: - * For use by generic_copy_file_range() and ->copy_file_range() methods. + * For use by ->copy_file_range() methods. * Like do_splice_direct(), but vfs_copy_file_range() already holds * start_file_write() on @out file. * diff --git a/include/linux/fs.h b/include/linux/fs.h index 04422a0eccdd..900d0cd55b50 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2090,9 +2090,6 @@ extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, loff_t, size_t, unsigned int); -extern ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t len, unsigned int flags); int __generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *len, unsigned int remap_flags, diff --git a/include/linux/splice.h b/include/linux/splice.h index 49532d5dda52..b92c4676c59b 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -89,6 +89,14 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, long splice_file_range(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len); +static inline long splice_copy_file_range(struct file *in, loff_t pos_in, + struct file *out, loff_t pos_out, + size_t len) +{ + return splice_file_range(in, &pos_in, out, &pos_out, + min_t(size_t, len, MAX_RW_COUNT)); +} + extern long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags); extern ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, From patchwork Thu Dec 7 12:38:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13483248 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AeCxmXEo" Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA1EC11F for ; Thu, 7 Dec 2023 04:38:37 -0800 (PST) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-3316d3d11e1so526278f8f.0 for ; Thu, 07 Dec 2023 04:38:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701952716; x=1702557516; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UbZB0CaH91bRuP24YpEqRFbdPVMxUfK74+WxyAJmrLc=; b=AeCxmXEoWfymT+nlcLQdsAS8pyYJwdcga+zse2i8Z1tPVtEJJi0JMk5IBnWqp07mU+ Ym7B/u0sD22lC51h3KGbIJUvubI3MR+8bRqoWEJJbGa+4TdQUq8WlbA5DHylvx9eMtMB SDqIyqTgEBvELd+0DHNUcuC1KwIeIQcsUDKXzbpRiG51IzC6CDBDv/Wgq6LHXjwPgSUb kckvOY7WdzLxBZvVCwWC1kSp2tLOcTx/ZowfJmmleU0EMRNkdeW3KeWCB7UH/v33NBgb inlucDGicf1eanv6MgNgqzSmT6jo4azGEw6S0fpGWFs8/HdrfhDhvEaZIlH8poTM3yV1 yluA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701952716; x=1702557516; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UbZB0CaH91bRuP24YpEqRFbdPVMxUfK74+WxyAJmrLc=; b=HESU2AtA4AIEDP20gOfQZuyx20JtCQ486VmktT8S6+zUU8R4sXwn062+TnPaIAeirz 07wkmFikgWgkEuxQFS54QGr97pmwQwt9O6eYE3hFOhK+elAqfgqY0pX5xxRFmug1mJjs FoL+pfipn+I7rrM5zvxCtXhqNfAiCxa9oN24VEEhshYGFZBv1RbM6wzrPf3NFLmqmFdx 2oEGlCPjoqUXANytaHgrsweZs29woWx4CurvmSQwtEsnp1r/CrfTLp0Q3KezgHKGwiQM +lFzEARchaDn8IKl8Tae1lD9MD1m4S6AyxuEyHEK1Y/V/W02+IVLPL22E9RDTuIxbgH0 bZBA== X-Gm-Message-State: AOJu0Yx6CJI5+pNol9xE/WkjpIhhccSeDFPWr06Uz/4Ke4Dj5eL7/bzo FhYA56oudC68qxQP2e9uTKE= X-Google-Smtp-Source: AGHT+IHAIaA0fb1AzIYgK5DT484BcQ6jp4mmRHpMyIXBdkYjt806RenC9+C9Oqaf/pMcwlXJV0pR3Q== X-Received: by 2002:adf:e80e:0:b0:333:870:bbc2 with SMTP id o14-20020adfe80e000000b003330870bbc2mr1642327wrm.9.1701952715835; Thu, 07 Dec 2023 04:38:35 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id z17-20020a5d4c91000000b003333abf3edfsm1332431wrs.47.2023.12.07.04.38.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Dec 2023 04:38:35 -0800 (PST) From: Amir Goldstein To: Christian Brauner , Jan Kara Cc: Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH 2/4] fsnotify: split fsnotify_perm() into two hooks Date: Thu, 7 Dec 2023 14:38:23 +0200 Message-Id: <20231207123825.4011620-3-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207123825.4011620-1-amir73il@gmail.com> References: <20231207123825.4011620-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 We would like to make changes to the fsnotify access permission hook - add file range arguments and add the pre modify event. In preparation for these changes, split the fsnotify_perm() hook into fsnotify_open_perm() and fsnotify_file_perm(). This is needed for fanotify "pre content" events. Signed-off-by: Amir Goldstein Reviewed-by: Jan Kara --- include/linux/fsnotify.h | 34 +++++++++++++++++++--------------- security/security.c | 4 ++-- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index bcb6609b54b3..926bb4461b9e 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -100,29 +100,33 @@ static inline int fsnotify_file(struct file *file, __u32 mask) return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH); } -/* Simple call site for access decisions */ -static inline int fsnotify_perm(struct file *file, int mask) +/* + * fsnotify_file_perm - permission hook before file access + */ +static inline int fsnotify_file_perm(struct file *file, int perm_mask) { - int ret; - __u32 fsnotify_mask = 0; + __u32 fsnotify_mask = FS_ACCESS_PERM; - if (!(mask & (MAY_READ | MAY_OPEN))) + if (!(perm_mask & MAY_READ)) return 0; - if (mask & MAY_OPEN) { - fsnotify_mask = FS_OPEN_PERM; + return fsnotify_file(file, fsnotify_mask); +} - if (file->f_flags & __FMODE_EXEC) { - ret = fsnotify_file(file, FS_OPEN_EXEC_PERM); +/* + * fsnotify_open_perm - permission hook before file open + */ +static inline int fsnotify_open_perm(struct file *file) +{ + int ret; - if (ret) - return ret; - } - } else if (mask & MAY_READ) { - fsnotify_mask = FS_ACCESS_PERM; + if (file->f_flags & __FMODE_EXEC) { + ret = fsnotify_file(file, FS_OPEN_EXEC_PERM); + if (ret) + return ret; } - return fsnotify_file(file, fsnotify_mask); + return fsnotify_file(file, FS_OPEN_PERM); } /* diff --git a/security/security.c b/security/security.c index dcb3e7014f9b..d7f3703c5905 100644 --- a/security/security.c +++ b/security/security.c @@ -2586,7 +2586,7 @@ int security_file_permission(struct file *file, int mask) if (ret) return ret; - return fsnotify_perm(file, mask); + return fsnotify_file_perm(file, mask); } /** @@ -2837,7 +2837,7 @@ int security_file_open(struct file *file) if (ret) return ret; - return fsnotify_perm(file, MAY_OPEN); + return fsnotify_open_perm(file); } /** From patchwork Thu Dec 7 12:38:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13483249 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LFN3RQ9A" Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1CA010FC for ; Thu, 7 Dec 2023 04:38:38 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-3332efd75c9so790265f8f.2 for ; Thu, 07 Dec 2023 04:38:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701952717; x=1702557517; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RkTRJy4JeCFBLG3CMd+4ebO5lvkwqEblB9voYoMpPs8=; b=LFN3RQ9A+fzRN6fbKYZSkoZ5A46QVAnbLQd6daK5tfUWdzMa0zkGj+bSMsjdzb2RAE na8vdEnwPicD3xedxWYGBS5KyMcbeQtTPmhQF+ajoAtPCmNkvhwY2R28ysYTCsRWStJi F3xIU8bx8YU6bse444jS1r2lKvW8KnwtaAvqBOcvEpWpUGeCZcscSfoWTsa9HrPJZcjC vqF2kPmPTUTMdlX1Ac5ZGHvvFBpw/lR3RDBBJHQKpzGcfr2h2lnTzaAEYL+gTa5Mq/5/ 8xB0RG+V4dpn/yynFCizgFJuUKpnkGw4dTIdri7YnpS2QUhhtnpyepo/bU1rWmM9x1aY SPxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701952717; x=1702557517; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RkTRJy4JeCFBLG3CMd+4ebO5lvkwqEblB9voYoMpPs8=; b=AZAECnlZFuExOZ5E9GtI+TgXzQi/H4Mno7LRAwovwSAzpS/PqDKHunwfZw44gchSpZ Z1OjLPZGx+2s+PN+lc/3J1LvdPQPmGbUkidbSb4S0TjeFDqESDy0orz7i5ttEMd9Jc6E ojXg2Rv2N7vglpWk6zCNq3VWMafVbfpFurawRMsmg34jUKSIa2E0fJ1lz3XG6wo1U8jF gchA8F7RinoK5u1F8EDknBfs+A5Bx2VNziQmk1HZc1QSJG8CCHgkzz1k1VA1eFNj50fM lVOTUSz7swvJD7q0eIBDLVrnl8rAZ/cRFgRQw/8u+SjEmzCB6S6to/RSetggxaCLaVzI Uweg== X-Gm-Message-State: AOJu0YyAAvdqZJDRw0lpSVZaROByDOgKmEzH2oaI0bvHW7xaEHFob/L8 khI2KL3ywmUjFY0ejwT7vRwWhcbHvKA= X-Google-Smtp-Source: AGHT+IH2WMZPjXOWZc2zx4h+mLzuppi1FBU8vqbDZWky0l0vndRiRbsJgzrlBNUcGI73AxTEXCsI7w== X-Received: by 2002:a05:6000:174e:b0:333:3117:c46e with SMTP id m14-20020a056000174e00b003333117c46emr575559wrf.255.1701952717344; Thu, 07 Dec 2023 04:38:37 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id z17-20020a5d4c91000000b003333abf3edfsm1332431wrs.47.2023.12.07.04.38.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Dec 2023 04:38:36 -0800 (PST) From: Amir Goldstein To: Christian Brauner , Jan Kara Cc: Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH 3/4] fsnotify: assert that file_start_write() is not held in permission hooks Date: Thu, 7 Dec 2023 14:38:24 +0200 Message-Id: <20231207123825.4011620-4-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207123825.4011620-1-amir73il@gmail.com> References: <20231207123825.4011620-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 filesystem may be modified in the context of fanotify permission events (e.g. by HSM service), so assert that sb freeze protection is not held. If the assertion fails, then the following deadlock would be possible: CPU0 CPU1 CPU2 ------------------------------------------------------------------------- file_start_write()#0 ... fsnotify_perm() fanotify_get_response() => (read event and fill file) ... ... freeze_super() ... sb_wait_write() ... vfs_write() file_start_write()#1 This example demonstrates a use case of an hierarchical storage management (HSM) service that uses fanotify permission events to fill the content of a file before access, while a 3rd process starts fsfreeze. This creates a circular dependeny: file_start_write()#0 => fanotify_get_response => file_start_write()#1 => sb_wait_write() => file_end_write()#0 Where file_end_write()#0 can never be called and none of the threads can make progress. The assertion is checked for both MAY_READ and MAY_WRITE permission hooks in preparation for a pre-modify permission event. The assertion is not checked for an open permission event, because do_open() takes mnt_want_write() in O_TRUNC case, meaning that it is not safe to write to filesystem in the content of an open permission event. Signed-off-by: Amir Goldstein Reviewed-by: Jan Kara --- include/linux/fsnotify.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 926bb4461b9e..0a9d6a8a747a 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -107,6 +107,13 @@ static inline int fsnotify_file_perm(struct file *file, int perm_mask) { __u32 fsnotify_mask = FS_ACCESS_PERM; + /* + * filesystem may be modified in the context of permission events + * (e.g. by HSM filling a file on access), so sb freeze protection + * must not be held. + */ + lockdep_assert_once(file_write_not_started(file)); + if (!(perm_mask & MAY_READ)) return 0; From patchwork Thu Dec 7 12:38:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 13483250 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ja2C4jV/" Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6305D10E0 for ; Thu, 7 Dec 2023 04:38:40 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-3334a701cbbso895656f8f.0 for ; Thu, 07 Dec 2023 04:38:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701952719; x=1702557519; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=91UBnG6fR3LUiwVV9EUqaRpgux2aghoi6YSdfsjb0uk=; b=Ja2C4jV/Tmd3N+396gTQbGp2K+K0AUh6bszdsUDqz0qYXSzosHNJOOEhMFvFkEJBIR sMgi+GeTpbDIAhEGxn/N8YxhXv7rthOv7SEUAH5dbjLsWu/IXmj0fzqDnzoOK4c/LQC0 nUNF38YEEm9e0pqdUZOHimBy4lhuJJRYswPLt8359HNcMw1MqnXuxa3CgUDmxT4ybVeD VQtM16t6FWFdn2BLe7MVfHxLwDYKcUFckUNDfm2n2aoddF0Itq2fFkcdmLpHWC0+n0Ho HqUMXXQwQLDtDf/8Ju5m19/NbGLZrTOIuUUvqhv1dhmc9qHyvibpksSbGKqHTg7AjHeC xmww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701952719; x=1702557519; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=91UBnG6fR3LUiwVV9EUqaRpgux2aghoi6YSdfsjb0uk=; b=ornHxHbnIUrdRktZPdw13J1MyrOn9WhAVhQQ218wl4tqwoDJqnOnhA01pJE14zneiZ VkpHKT8h894G2ivS9/PtQI2AoCMt8hSehcLrK744CB/Py8C8TLZWiFe4ohObN3qLX5xY q4dWPqpDUyC8/9VCapWFVP4MR+FMpMb8xGMBYTu0IVq/GCe9WsR57hQT2iUvkbAMPcyo FEDrLrMVN3vKZ40feMVda7asAwXc7tqDGWAuEz6oyx/K+pQx7lxYgmkDtUFtu147ddZG T5oYY0d3vx02+qeeTSq88Xv2aCzLvtszEXcb7jABs8PApu1WRn33Y2azsD7FD+Mi4Wlv XtbQ== X-Gm-Message-State: AOJu0YyqXmVJqg1EqdluqvC8TyH0VKomP7MTQkwajUhUQ0iCWvE0spfv sqzO8g9jJSJ1g1dbjG6eHjFYGlb6DOs= X-Google-Smtp-Source: AGHT+IFOed7UyAWJaBzMuTvt6ql/wcfr7qYMEko5w2Cbqjjc1ODgc+HxZz/l/iVbR9oeVtNFTtYdrA== X-Received: by 2002:a5d:6711:0:b0:333:2fd2:3bd4 with SMTP id o17-20020a5d6711000000b003332fd23bd4mr1079980wru.141.1701952718761; Thu, 07 Dec 2023 04:38:38 -0800 (PST) Received: from amir-ThinkPad-T480.lan ([5.29.249.86]) by smtp.gmail.com with ESMTPSA id z17-20020a5d4c91000000b003333abf3edfsm1332431wrs.47.2023.12.07.04.38.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Dec 2023 04:38:38 -0800 (PST) From: Amir Goldstein To: Christian Brauner , Jan Kara Cc: Jeff Layton , Josef Bacik , Christoph Hellwig , David Howells , Jens Axboe , Miklos Szeredi , Al Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH 4/4] fsnotify: pass access range in file permission hooks Date: Thu, 7 Dec 2023 14:38:25 +0200 Message-Id: <20231207123825.4011620-5-amir73il@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207123825.4011620-1-amir73il@gmail.com> References: <20231207123825.4011620-1-amir73il@gmail.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In preparation for pre-content permission events with file access range, move fsnotify_file_perm() hook out of security_file_permission() and into the callers that have the access range information and pass the access range to fsnotify_file_perm(). Signed-off-by: Amir Goldstein --- fs/open.c | 4 ++++ fs/read_write.c | 10 ++++++++-- fs/readdir.c | 4 ++++ fs/remap_range.c | 8 +++++++- include/linux/fsnotify.h | 3 ++- security/security.c | 8 +------- 6 files changed, 26 insertions(+), 11 deletions(-) diff --git a/fs/open.c b/fs/open.c index 02dc608d40d8..530f70da69e1 100644 --- a/fs/open.c +++ b/fs/open.c @@ -304,6 +304,10 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (ret) return ret; + ret = fsnotify_file_perm(file, MAY_WRITE, &offset, len); + if (ret) + return ret; + if (S_ISFIFO(inode->i_mode)) return -ESPIPE; diff --git a/fs/read_write.c b/fs/read_write.c index 97a9d5c7ad96..1b5b0883edba 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -354,6 +354,9 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) { + int mask = read_write == READ ? MAY_READ : MAY_WRITE; + int ret; + if (unlikely((ssize_t) count < 0)) return -EINVAL; @@ -371,8 +374,11 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t } } - return security_file_permission(file, - read_write == READ ? MAY_READ : MAY_WRITE); + ret = security_file_permission(file, mask); + if (ret) + return ret; + + return fsnotify_file_perm(file, mask, ppos, count); } EXPORT_SYMBOL(rw_verify_area); diff --git a/fs/readdir.c b/fs/readdir.c index c8c46e294431..684ae75d94a4 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -96,6 +96,10 @@ int iterate_dir(struct file *file, struct dir_context *ctx) if (res) goto out; + res = fsnotify_file_perm(file, MAY_READ, NULL, 0); + if (res) + goto out; + res = down_read_killable(&inode->i_rwsem); if (res) goto out; diff --git a/fs/remap_range.c b/fs/remap_range.c index 12131f2a6c9e..ee4729aafbde 100644 --- a/fs/remap_range.c +++ b/fs/remap_range.c @@ -102,7 +102,9 @@ static int generic_remap_checks(struct file *file_in, loff_t pos_in, static int remap_verify_area(struct file *file, loff_t pos, loff_t len, bool write) { + int mask = write ? MAY_WRITE : MAY_READ; loff_t tmp; + int ret; if (unlikely(pos < 0 || len < 0)) return -EINVAL; @@ -110,7 +112,11 @@ static int remap_verify_area(struct file *file, loff_t pos, loff_t len, if (unlikely(check_add_overflow(pos, len, &tmp))) return -EINVAL; - return security_file_permission(file, write ? MAY_WRITE : MAY_READ); + ret = security_file_permission(file, mask); + if (ret) + return ret; + + return fsnotify_file_perm(file, mask, &pos, len); } /* diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 0a9d6a8a747a..45e6ecbca057 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -103,7 +103,8 @@ static inline int fsnotify_file(struct file *file, __u32 mask) /* * fsnotify_file_perm - permission hook before file access */ -static inline int fsnotify_file_perm(struct file *file, int perm_mask) +static inline int fsnotify_file_perm(struct file *file, int perm_mask, + const loff_t *ppos, size_t count) { __u32 fsnotify_mask = FS_ACCESS_PERM; diff --git a/security/security.c b/security/security.c index d7f3703c5905..2a7fc7881cbc 100644 --- a/security/security.c +++ b/security/security.c @@ -2580,13 +2580,7 @@ int security_kernfs_init_security(struct kernfs_node *kn_dir, */ int security_file_permission(struct file *file, int mask) { - int ret; - - ret = call_int_hook(file_permission, 0, file, mask); - if (ret) - return ret; - - return fsnotify_file_perm(file, mask); + return call_int_hook(file_permission, 0, file, mask); } /**