linux/fs/fuse
Jann Horn b18915248a fuse: use unsigned type for getxattr/listxattr size truncation
The existing code uses min_t(ssize_t, outarg.size, XATTR_LIST_MAX) when
parsing the FUSE daemon's response to a zero-length getxattr/listxattr
request.
On 32-bit kernels, where ssize_t and outarg.size are the same size, this is
wrong: The min_t() will pass through any size values that are negative when
interpreted as signed.
fuse_listxattr() will then return this userspace-supplied negative value,
which callers will treat as an error value.

This kind of bug pattern can lead to fairly bad security bugs because of
how error codes are used in the Linux kernel. If a caller were to convert
the numeric error into an error pointer, like so:

    struct foo *func(...) {
      int len = fuse_getxattr(..., NULL, 0);
      if (len < 0)
        return ERR_PTR(len);
      ...
    }

then it would end up returning this userspace-supplied negative value cast
to a pointer - but the caller of this function wouldn't recognize it as an
error pointer (IS_ERR_VALUE() only detects values in the narrow range in
which legitimate errno values are), and so it would just be treated as a
kernel pointer.

I think there is at least one theoretical codepath where this could happen,
but that path would involve virtio-fs with submounts plus some weird
SELinux configuration, so I think it's probably not a concern in practice.

Cc: stable@vger.kernel.org # v4.9
Fixes: 63401ccdb2 ("fuse: limit xattr returned size")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2024-08-28 18:10:29 +02:00
..
acl.c fuse: Use in_group_or_capable() helper 2024-06-25 11:15:48 +02:00
control.c fuse: remove unneeded lock which protecting update of congestion_threshold 2024-03-06 11:07:51 +01:00
cuse.c cuse: add kernel-doc comments to cuse_process_init_reply() 2024-04-15 11:02:10 +02:00
dax.c fuse: dax: set fc->dax to NULL in fuse_dax_conn_free() 2023-12-04 10:16:53 +01:00
dev.c fuse: clear FR_SENT when re-adding requests into pending list 2024-05-10 11:10:39 +02:00
dir.c fuse: fix leaked ENOSYS error on first statx call 2024-04-15 10:12:44 +02:00
file.c fuse: Convert fuse_readpages_end() to use folio_end_read() 2024-05-08 09:31:21 +02:00
fuse_i.h fuse: fix wrong ff->iomode state changes from parallel dio write 2024-04-15 10:12:03 +02:00
inode.c fuse: Convert to new uid/gid option parsing helpers 2024-07-03 16:55:11 +02:00
ioctl.c fuse: Add initial support for fs-verity 2024-05-08 09:31:21 +02:00
iomode.c fuse: fix parallel dio write on file open in passthrough mode 2024-04-15 10:12:44 +02:00
Kconfig fuse: introduce FUSE_PASSTHROUGH capability 2024-02-23 17:36:32 +01:00
Makefile fuse: introduce FUSE_PASSTHROUGH capability 2024-02-23 17:36:32 +01:00
passthrough.c fuse: verify zero padding in fuse_backing_map 2024-04-22 17:13:43 +02:00
readdir.c fuse: get rid of ff->readdir.lock 2024-03-06 16:20:58 +01:00
virtio_fs.c virtio: rename virtio_find_vqs_info() to virtio_find_vqs() 2024-07-17 05:20:58 -04:00
xattr.c fuse: use unsigned type for getxattr/listxattr size truncation 2024-08-28 18:10:29 +02:00