From patchwork Fri Nov 15 15:30:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13876444 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id B1FCDD68BC6 for ; Fri, 15 Nov 2024 15:31:42 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2A5736B0095; Fri, 15 Nov 2024 10:31:37 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 256896B0096; Fri, 15 Nov 2024 10:31:37 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 080E86B0098; Fri, 15 Nov 2024 10:31:37 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id DE7B46B0095 for ; Fri, 15 Nov 2024 10:31:36 -0500 (EST) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 648C31C63D4 for ; Fri, 15 Nov 2024 15:31:36 +0000 (UTC) X-FDA: 82788718152.11.ACD82CD Received: from mail-yb1-f169.google.com (mail-yb1-f169.google.com [209.85.219.169]) by imf18.hostedemail.com (Postfix) with ESMTP id 4829F1C0005 for ; Fri, 15 Nov 2024 15:31:14 +0000 (UTC) Authentication-Results: imf18.hostedemail.com; dkim=pass header.d=toxicpanda-com.20230601.gappssmtp.com header.s=20230601 header.b=TT7AbsI9; spf=none (imf18.hostedemail.com: domain of josef@toxicpanda.com has no SPF policy when checking 209.85.219.169) smtp.mailfrom=josef@toxicpanda.com; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731684456; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=MRzK4Q1A3yuX/T2NQizEcUBNaZlB/P7dkcHbBOaMevU=; b=I3cmM4YgmMO0cvsvF6mwzVS4IvQSIZdqCWRJxUuRN9Kau57/PVzhzkFmQLcVSUWW5yumru 511xgNCEI1hid4aFxB2C9F8ByJ3hQoXg6zZq6+IsqIoZwhnyMTIxHxEnI8j7mvZjAFyVeq oVcQYcT0VkVfoAEMkyZCuIJ7a+o74YA= ARC-Authentication-Results: i=1; imf18.hostedemail.com; dkim=pass header.d=toxicpanda-com.20230601.gappssmtp.com header.s=20230601 header.b=TT7AbsI9; spf=none (imf18.hostedemail.com: domain of josef@toxicpanda.com has no SPF policy when checking 209.85.219.169) smtp.mailfrom=josef@toxicpanda.com; dmarc=none ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731684456; a=rsa-sha256; cv=none; b=p0TL0mohIaCfC4sYn9FnuJqoTO8eVLL0WKRfReGxJ2NNGpuICWBnk4VIh3YKKpHKMp6nsg oUgrEEJ1A8YK/tDvDaPE33EVStyTBxK6gE2FgeEopZE+NE8X2g4zci5urNZqJZ3SIz9XpG ihaINqOq5tzxfqf81rDkYsAZLfzVb7s= Received: by mail-yb1-f169.google.com with SMTP id 3f1490d57ef6-e380d1389a1so746911276.2 for ; Fri, 15 Nov 2024 07:31:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1731684693; x=1732289493; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=MRzK4Q1A3yuX/T2NQizEcUBNaZlB/P7dkcHbBOaMevU=; b=TT7AbsI9sykEGnCh0T8ZrdjFtigBEN+rvNlD39a4qCVfPuYa/n0pI1pbmbY2abfg4e GEIxeUN/Y0/LKF92LURNB7kwnyO6JOmfsAIN39Fyv/JVFGedUZxAQMbVww/A8QGNe2Pf aDOaIimBlKF5XfHY0mEZlQnedqelYL7GsqOF+6WBUGfr/PnQ6y36UBPCU0Q9KF9G3peI 1Pb6OmU35Ebhzmyx3KA9uzboKpbnfZvfyg9MYHBiNuB2Em7JbPwdkWjGBaFhtcqN6689 IH8mm3IjvBD+faZ941xpklbV87yEImstvarA8FiMX8fGuBlR3QlCCLpfaFHgD3vyVNZM hr4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731684693; x=1732289493; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MRzK4Q1A3yuX/T2NQizEcUBNaZlB/P7dkcHbBOaMevU=; b=qf++0+Y1Oufq3MDu9XZvQ7eSdXvoDTlV2TSFvcvfA3jlzbJeQcAIPlZ++W+1wo3yJu H/NAt0XBQwyqo/4gfK1eUaRWQFl5s3p5iI70fi6T8sMNL7+4d2yy0GpjFUsi6Uo4j5tV +Ge4D8vciCFdqnGljAWYpfb3/Fvo5HhNgkhlL8sLuu5me1dU8CbSl2N+LU+z/6pr3yS8 mzkOdo1ew/hugdfPPrPvPf6TdJnW0BuovsLMEoSQi2PlgtkJwyxC1Ym7FmqXDR+bKWuS coWU+6RsvJRNyQLKZYKMrNFeuFdNfZ440t761JNsnW1HS9dIv1YF0KRKOiMMMahqQBy9 5wng== X-Forwarded-Encrypted: i=1; AJvYcCV97yqgdsNidJNkI1cIOa/lWoBazDIrp1jiF+SE0WnDYGxNVZ98/L3kwkGs2nlmDy873PGI68H4bw==@kvack.org X-Gm-Message-State: AOJu0YxQ979pPHakJJv8Zu/pZKTpTSznebn+9xmAqcC8URimRsES8EZ4 1u18bIR/A0tFDvNDrmqrUk7fcHpo50cqWia/19/lo/XonHDJhlE3FsAOvD5rY8c= X-Google-Smtp-Source: AGHT+IGyWRJgeIXfM96kmRgZ4BcfzpHMEUIT23gvUh5NA4jhWm1kPkotZW2CvGFTnhHweMUdUT4Lug== X-Received: by 2002:a05:6902:f84:b0:e2b:b45a:149 with SMTP id 3f1490d57ef6-e382639f2b5mr2742461276.39.1731684693281; Fri, 15 Nov 2024 07:31:33 -0800 (PST) Received: from localhost (syn-076-182-020-124.res.spectrum.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id 3f1490d57ef6-e38152d0248sm963707276.23.2024.11.15.07.31.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 07:31:32 -0800 (PST) From: Josef Bacik To: kernel-team@fb.com, linux-fsdevel@vger.kernel.org, jack@suse.cz, amir73il@gmail.com, brauner@kernel.org, torvalds@linux-foundation.org, viro@zeniv.linux.org.uk, linux-xfs@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-mm@kvack.org, linux-ext4@vger.kernel.org Subject: [PATCH v8 07/19] fsnotify: introduce pre-content permission events Date: Fri, 15 Nov 2024 10:30:20 -0500 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 4829F1C0005 X-Stat-Signature: 4ncsubcq938byop6b6otybm5ah45am9k X-Rspam-User: X-HE-Tag: 1731684674-375563 X-HE-Meta: U2FsdGVkX18DBmF2cjjkqCj+xD12wReoRPmzC+NdAtBqZWrj9E4J7z0RjIInh5nojaxRcFHtd64Y9MPxJoWF1jzULM9++uN+Cx9gx5mu4PdtFSaZbsI9YXQtxEz4CC0yX9odnGoMfrZoB6nDcjCJVGat8D2NC/lwzocekeKpR9IT/GzWdNvrEfIMVpk/iVlNfntTHk1yF+wLaEtfEkuiXdBXLVXxQpsXVnfAevNARiQpTlWztGHBtFo6ztqzMgBGd7h6tniYijWyeMc9gNJ8WhARQYxfjLAgH0Zw5EGNl13OKUQt3YUl5uxyZckrFgHpglv+jVkJxUYePm3BpCEpLSH5doSLvYdXwpfyhpy5b9lu1VV1tGesywyXRX60HqMTMKTiC9d2kaUmay1AieAFKgXNMKkyUe8eA0Xl7RaMfm7xduQO3bWoYuYdAvnU1ea5LOYWkG1Z7JmnNwJ/lyikUiBV2nCBItnrtl82zDTgniSK/IMGeGe4lno+lLgRCFLGZPkzqNKzqDVqFEDvKzcMfIUorkZtj+hsy/K1buYlRcQ8lhroSQSrcXGJSP6uyCuUCFIWG78hZDbjD6VG6FbgeYEk6reJVYqDxiup7YtscQJMcKb06dJ8rVvTlqMPAOzunec9GgbIsgXej7lc49G71O4fH+FPHk8B3UlgscZtHVCRyOxNpd3dGzJMSFC5i5eiRZK9q9yZiUlOYKtia08Enk0ehRrMfiOHDnQPWIpGYzjs2RH8Fz73QFll5JwvS7ZRk9aZ1Mvr0E39MwdB6daJI6smvKiRV7Ss71zZOq//PB9b10ZOOtyY/+BQRQbbxuNwXPL6JjgiKs02soJLKmlCYrc06pDggIKJuY8NIRfx39kXObaAwMruXxxnc5zeQMs3E1dwK6ct3RR1BiEZ/TwqGW7YEayZeff2flAwGxBH2Q96i+HpFLRKMU6Uj4ZrO16oivwMZd5rYYirZJs+NVY BfECqv04 gSjUt9tLvvnvegAPsWJzg1/KozdhN4Hsh/GyzCPkRLGPnmKu9/6dk1W7aQ5AkqQJDLMZhwbzItS5moKl4tTKXpVhVYBYd0qRRuIaYQp6w8mxvgXKghAb8MAEFw0UVir3WzMRkBVLDts5BzBrekYbAeceYv5gckmiRcPk2/OJrE/iRKhjWswHaIHzuE5Is71G5hAHvsVgwWNh3Wv/N3SW/J1mAz3oGVGXYsifisNcmjYaESWq5i03EykT65tJ7BNVaqqcUuCgY19UjrHBhpLal8v2bgEBMH+2ud8W9z3bGqIg/pvYReitcPSgOJH7mqiajXjMnFLAAX3GGhh5DAPPMIdJFFg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Amir Goldstein The new FS_PRE_ACCESS permission event is similar to FS_ACCESS_PERM, but it meant for a different use case of filling file content before access to a file range, so it has slightly different semantics. Generate FS_PRE_ACCESS/FS_ACCESS_PERM as two seperate events, so content scanners could inspect the content filled by pre-content event handler. Unlike FS_ACCESS_PERM, FS_PRE_ACCESS is also called before a file is modified by syscalls as write() and fallocate(). FS_ACCESS_PERM is reported also on blockdev and pipes, but the new pre-content events are only reported for regular files and dirs. The pre-content events are meant to be used by hierarchical storage managers that want to fill the content of files on first access. There are some specific requirements from filesystems that could be used with pre-content events, so add a flag for fs to opt-in for pre-content events explicitly before they can be used. Signed-off-by: Amir Goldstein --- fs/notify/fsnotify.c | 2 +- include/linux/fs.h | 1 + include/linux/fsnotify.h | 39 ++++++++++++++++++++++++++++---- include/linux/fsnotify_backend.h | 12 ++++++++-- security/selinux/hooks.c | 3 ++- 5 files changed, 49 insertions(+), 8 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 33576a848a9f..d128cb7dee62 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -649,7 +649,7 @@ static __init int fsnotify_init(void) { int ret; - BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 23); + BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 24); ret = init_srcu_struct(&fsnotify_mark_srcu); if (ret) diff --git a/include/linux/fs.h b/include/linux/fs.h index 8e5c783013d2..d231f4bc12aa 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1256,6 +1256,7 @@ extern int send_sigurg(struct file *file); #define SB_I_RETIRED 0x00000800 /* superblock shouldn't be reused */ #define SB_I_NOUMASK 0x00001000 /* VFS does not apply umask */ #define SB_I_NOIDMAP 0x00002000 /* No idmapped mounts on this superblock */ +#define SB_I_ALLOW_HSM 0x00004000 /* Allow HSM events on this superblock */ /* Possible states of 'frozen' field */ enum { diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 54ec97366d7c..994d7a322369 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -134,9 +134,10 @@ static inline int fsnotify_file(struct file *file, __u32 mask) * Later, fsnotify permission hooks do not check if there are permission event * watches, but that there were permission event watches at open time. */ -static void file_set_fsnotify_mode(struct file *file) +static inline void file_set_fsnotify_mode(struct file *file) { struct super_block *sb = file->f_path.dentry->d_sb; + struct inode *inode; /* Is it a file opened by fanotify? */ if (FMODE_FSNOTIFY_NONE(file->f_mode)) @@ -162,6 +163,19 @@ static void file_set_fsnotify_mode(struct file *file) file->f_mode |= FMODE_NONOTIFY_HSM; return; } + + /* + * There are pre-content watchers in the filesystem, but are there + * pre-content watchers on this specific file? + * Pre-content events are only reported for regular files and dirs. + */ + inode = file_inode(file); + if ((!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode)) || + likely(!fsnotify_file_object_watched(file, + FSNOTIFY_PRE_CONTENT_EVENTS))) { + file->f_mode |= FMODE_NONOTIFY_HSM; + return; + } } /* @@ -177,12 +191,29 @@ static inline int fsnotify_file_area_perm(struct file *file, int perm_mask, */ lockdep_assert_once(file_write_not_started(file)); + if (!(perm_mask & (MAY_READ | MAY_WRITE | MAY_ACCESS))) + return 0; + + if (likely(!FMODE_FSNOTIFY_PERM(file->f_mode))) + return 0; + + /* + * read()/write() and other types of access generate pre-content events. + */ + if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode))) { + int ret = fsnotify_path(&file->f_path, FS_PRE_ACCESS); + + if (ret) + return ret; + } + if (!(perm_mask & MAY_READ)) return 0; - if (likely(file->f_mode & FMODE_NONOTIFY_PERM)) - return 0; - + /* + * read() also generates the legacy FS_ACCESS_PERM event, so content + * scanners can inspect the content filled by pre-content event. + */ return fsnotify_path(&file->f_path, FS_ACCESS_PERM); } diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 2dc30cf637aa..33880de72ef3 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -57,6 +57,8 @@ #define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */ /* #define FS_DIR_MODIFY 0x00080000 */ /* Deprecated (reserved) */ +#define FS_PRE_ACCESS 0x00100000 /* Pre-content access hook */ + /* * Set on inode mark that cares about things that happen to its children. * Always set for dnotify and inotify. @@ -78,8 +80,14 @@ */ #define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE | FS_RENAME) -#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \ - FS_OPEN_EXEC_PERM) +/* Content events can be used to inspect file content */ +#define FSNOTIFY_CONTENT_PERM_EVENTS (FS_OPEN_PERM | FS_OPEN_EXEC_PERM | \ + FS_ACCESS_PERM) +/* Pre-content events can be used to fill file content */ +#define FSNOTIFY_PRE_CONTENT_EVENTS (FS_PRE_ACCESS) + +#define ALL_FSNOTIFY_PERM_EVENTS (FSNOTIFY_CONTENT_PERM_EVENTS | \ + FSNOTIFY_PRE_CONTENT_EVENTS) /* * This is a list of all events that may get sent to a parent that is watching diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index fc926d3cac6e..c6f38705c715 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3404,7 +3404,8 @@ static int selinux_path_notify(const struct path *path, u64 mask, perm |= FILE__WATCH_WITH_PERM; /* watches on read-like events need the file:watch_reads permission */ - if (mask & (FS_ACCESS | FS_ACCESS_PERM | FS_CLOSE_NOWRITE)) + if (mask & (FS_ACCESS | FS_ACCESS_PERM | FS_PRE_ACCESS | + FS_CLOSE_NOWRITE)) perm |= FILE__WATCH_READS; return path_has_perm(current_cred(), path, perm);