Out of bounds write vulnerability in the sqfs_readdir() function

Jincheng Wang jc.w4ng at gmail.com
Thu May 26 10:28:07 CEST 2022


Hello u-boot list,

I found the sqfs_readdir() function is vulnerable to Out-of-Bound write,
which will cause arbitrary code execution.

```
int sqfs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
{
......
/* Set entry name */

strncpy(dent->name, dirs->entry->name, dirs->entry->name_size + 1);
dent->name[dirs->entry->name_size + 1] = '\0';

offset = dirs->entry->name_size + 1 + SQFS_ENTRY_BASE_LENGTH;
dirs->entry_count--;
.......
}


struct squashfs_dir_stream {
struct fs_dir_stream fs_dirs;
struct fs_dirent dentp;
size_t size;
int entry_count;
struct squashfs_directory_header *dir_header;
struct squashfs_directory_entry *entry;
......
};


static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char
**token_list,
  int token_count, u32 *m_list, int m_count)
{
......
while (!sqfs_readdir(dirsp, &dent)) {
ret = strcmp(dent->name, token_list[j]);
if (!ret)
break;
free(dirs->entry);
dirs->entry = NULL;
}
......
}

```

The sqfs_readdir() function  use strncpy to  set entry name, while the type
of dirs->entry->name_size is defined as "u16" in the struct
squashfs_directory_entry
and dent->name
is defined as "char[256]" in the struct fs_dirent.

We can overwrite *dirs_header and *entry in the struct squashfs_dir_stream,
so that  we can use the sqfs_search_dir() function to free a fake
chunk which causes arbitrary code execution.
You can see the Poc in the attachment.

     host bind 0 test4.sqfs
     ls host 0 /dirs
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test4.sqfs
Type: application/octet-stream
Size: 4096 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20220526/8d602dc7/attachment.obj>


More information about the U-Boot mailing list