summaryrefslogtreecommitdiffstats
path: root/fs/libfs.c
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2025-04-07 11:54:15 +0200
committerChristian Brauner <brauner@kernel.org>2025-04-07 16:18:46 +0200
commitcfd86ef7e8e7b9e015707e46479a6b1de141eed0 (patch)
tree85e16b07ef273652843b4dde624d2062f7efb655 /fs/libfs.c
parentdocs: initramfs: update compression and mtime descriptions (diff)
downloadlinux-cfd86ef7e8e7b9e015707e46479a6b1de141eed0.tar.gz
linux-cfd86ef7e8e7b9e015707e46479a6b1de141eed0.zip
anon_inode: use a proper mode internally
This allows the VFS to not trip over anonymous inodes and we can add asserts based on the mode into the vfs. When we report it to userspace we can simply hide the mode to avoid regressions. I've audited all direct callers of alloc_anon_inode() and only secretmen overrides i_mode and i_op inode operations but it already uses a regular file. Link: https://lore.kernel.org/20250407-work-anon_inode-v1-1-53a44c20d44e@kernel.org Fixes: af153bb63a336 ("vfs: catch invalid modes in may_open()") Reviewed-by: Jeff Layton <jlayton@kernel.org> Cc: stable@vger.kernel.org # all LTS kernels Reported-by: syzbot+5d8e79d323a13aa0b248@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/67ed3fb3.050a0220.14623d.0009.GAE@google.com Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/libfs.c')
-rw-r--r--fs/libfs.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/libfs.c b/fs/libfs.c
index 6393d7c49ee6..e1146620346e 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1647,7 +1647,13 @@ struct inode *alloc_anon_inode(struct super_block *s)
* that it already _is_ on the dirty list.
*/
inode->i_state = I_DIRTY;
- inode->i_mode = S_IRUSR | S_IWUSR;
+ /*
+ * Historically anonymous inodes didn't have a type at all and
+ * userspace has come to rely on this. Internally they're just
+ * regular files but S_IFREG is masked off when reporting
+ * information to userspace.
+ */
+ inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
inode->i_flags |= S_PRIVATE;