On Thu, May 26, 2022 at 04:28:07PM +0800, Jincheng Wang wrote: > 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
Adding the listed maintainers... -- Tom
signature.asc
Description: PGP signature