]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
orangefs: keep the readdir entry size 64-bit in fill_from_part()
authorBryam Vargas <hexlabsecurity@proton.me>
Fri, 19 Jun 2026 09:38:20 +0000 (04:38 -0500)
committerChristian Brauner <brauner@kernel.org>
Wed, 1 Jul 2026 13:26:27 +0000 (15:26 +0200)
fill_from_part() computes the size of a directory entry in size_t but
stores it in a __u32. An entry length near U32_MAX wraps it to a small
value, bypasses the bounds check, and is then used to index the entry,
reading far past the directory part -- an out-of-bounds read that oopses
the kernel.

Compute the size as a u64 so it cannot truncate; the bounds check then
rejects the entry. The trailer is supplied by the userspace client.

Fixes: 480e3e532e31 ("orangefs: support very large directories")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260619-b4-disp-50d2bd59-v1-1-ce332969b4a2@proton.me
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/orangefs/dir.c

index 6e2ebc8b9867b5c0cf5102505b09def42c9e1987..115b2c2f526944328657d8cc9623a480f03e2ba4 100644 (file)
@@ -191,7 +191,8 @@ static int fill_from_part(struct orangefs_dir_part *part,
 {
        const int offset = sizeof(struct orangefs_readdir_response_s);
        struct orangefs_khandle *khandle;
-       __u32 *len, padlen;
+       __u32 *len;
+       u64 padlen;
        loff_t i;
        char *s;
        i = ctx->pos & ~PART_MASK;
@@ -215,8 +216,8 @@ static int fill_from_part(struct orangefs_dir_part *part,
                 * len is the size of the string itself.  padlen is the
                 * total size of the encoded string.
                 */
-               padlen = (sizeof *len + *len + 1) +
-                   (8 - (sizeof *len + *len + 1)%8)%8;
+               padlen = (u64)sizeof *len + *len + 1;
+               padlen += (8 - padlen % 8) % 8;
                if (part->len < i + padlen + sizeof *khandle)
                        goto next;
                s = (void *)part + offset + i + sizeof *len;