linux/fs/fuse
Miklos Szeredi 3cb53dd557 fuse: don't truncate cached, mutated symlink
[ Upstream commit b4c173dfbb ]

Fuse allows the value of a symlink to change and this property is exploited
by some filesystems (e.g. CVMFS).

It has been observed, that sometimes after changing the symlink contents,
the value is truncated to the old size.

This is caused by fuse_getattr() racing with fuse_reverse_inval_inode().
fuse_reverse_inval_inode() updates the fuse_inode's attr_version, which
results in fuse_change_attributes() exiting before updating the cached
attributes

This is okay, as the cached attributes remain invalid and the next call to
fuse_change_attributes() will likely update the inode with the correct
values.

The reason this causes problems is that cached symlinks will be
returned through page_get_link(), which truncates the symlink to
inode->i_size.  This is correct for filesystems that don't mutate
symlinks, but in this case it causes bad behavior.

The solution is to just remove this truncation.  This can cause a
regression in a filesystem that relies on supplying a symlink larger than
the file size, but this is unlikely.  If that happens we'd need to make
this behavior conditional.

Reported-by: Laura Promberger <laura.promberger@cern.ch>
Tested-by: Sam Lewis <samclewis@google.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Link: https://lore.kernel.org/r/20250220100258.793363-1-mszeredi@redhat.com
Reviewed-by: Bernd Schubert <bschubert@ddn.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2025-03-28 21:58:53 +01:00
..
acl.c vfs: add rcu argument to ->get_acl() callback 2021-08-18 22:08:24 +02:00
control.c fuse: Remove the control interface for virtio-fs 2022-07-21 16:06:19 +02:00
cuse.c fuse: fix UAF in rcu pathwalks 2024-08-29 17:30:34 +02:00
dax.c fuse: dax: set fc->dax to NULL in fuse_dax_conn_free() 2023-12-20 17:00:20 +01:00
dev.c fuse: add request extension 2024-09-12 11:10:27 +02:00
dir.c fuse: don't truncate cached, mutated symlink 2025-03-28 21:58:53 +01:00
file.c fuse: allow non-extending parallel direct writes on the same file 2024-09-12 11:10:27 +02:00
fuse_i.h fuse: add request extension 2024-09-12 11:10:27 +02:00
inode.c fuse: add feature flag for expire-only 2024-09-12 11:10:30 +02:00
ioctl.c fuse: ioctl: translate ENOSYS in outarg 2023-07-27 08:50:25 +02:00
Kconfig dax: remove CONFIG_DAX_DRIVER 2021-12-04 08:58:51 -08:00
Makefile fuse: move ioctl to separate source file 2021-04-12 15:04:30 +02:00
readdir.c fuse: nlookup missing decrement in fuse_direntplus_link 2023-09-19 12:28:05 +02:00
virtio_fs.c virtiofs: forbid newlines in tags 2024-08-29 17:30:36 +02:00
xattr.c fuse: use unsigned type for getxattr/listxattr size truncation 2024-09-12 11:10:17 +02:00