ACK/CMNT: [PATCH 1/2] squashfs metadata 2: electric boogaloo
Tyler Hicks
tyhicks at canonical.com
Wed Feb 20 13:34:20 UTC 2019
On 2019-02-19 15:32:30, Paolo Pisati wrote:
> From: Linus Torvalds <torvalds at linux-foundation.org>
This line should be added when committing this change:
BugLink: https://bugs.launchpad.net/bugs/1816756
>
> Anatoly continues to find issues with fuzzed squashfs images.
>
> This time, corrupt, missing, or undersized data for the page filling
> wasn't checked for, because the squashfs_{copy,read}_cache() functions
> did the squashfs_copy_data() call without checking the resulting data
> size.
>
> Which could result in the page cache pages being incompletely filled in,
> and no error indication to the user space reading garbage data.
>
> So make a helper function for the "fill in pages" case, because the
> exact same incomplete sequence existed in two places.
>
> [ I should have made a squashfs branch for these things, but I didn't
> intend to start doing them in the first place.
>
> My historical connection through cramfs is why I got into looking at
> these issues at all, and every time I (continue to) think it's a
> one-off.
>
> Because _this_ time is always the last time. Right? - Linus ]
>
> Reported-by: Anatoly Trosinenko <anatoly.trosinenko at gmail.com>
> Tested-by: Willy Tarreau <w at 1wt.eu>
> Cc: Al Viro <viro at zeniv.linux.org.uk>
> Cc: Phillip Lougher <phillip at squashfs.org.uk>
> Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
> (cherry picked from commit cdbb65c4c7ead680ebe54f4f0d486e2847a500ea)
You had to change PAGE_SIZE to PAGE_CACHE_SIZE so the above line needs
s/cherry picked/backported/
With the above two changes,
Acked-by: Tyler Hicks <tyhicks at canonical.com>
Tyler
> Signed-off-by: Paolo Pisati <paolo.pisati at canonical.com>
> ---
> fs/squashfs/file.c | 25 ++++++++++++++++++-------
> fs/squashfs/file_direct.c | 8 +-------
> fs/squashfs/squashfs.h | 1 +
> 3 files changed, 20 insertions(+), 14 deletions(-)
>
> diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
> index 1ec7bae2..fa3eb0a 100644
> --- a/fs/squashfs/file.c
> +++ b/fs/squashfs/file.c
> @@ -374,13 +374,29 @@ static int read_blocklist(struct inode *inode, int index, u64 *block)
> return squashfs_block_size(size);
> }
>
> +void squashfs_fill_page(struct page *page, struct squashfs_cache_entry *buffer, int offset, int avail)
> +{
> + int copied;
> + void *pageaddr;
> +
> + pageaddr = kmap_atomic(page);
> + copied = squashfs_copy_data(pageaddr, buffer, offset, avail);
> + memset(pageaddr + copied, 0, PAGE_CACHE_SIZE - copied);
> + kunmap_atomic(pageaddr);
> +
> + flush_dcache_page(page);
> + if (copied == avail)
> + SetPageUptodate(page);
> + else
> + SetPageError(page);
> +}
> +
> /* Copy data into page cache */
> void squashfs_copy_cache(struct page *page, struct squashfs_cache_entry *buffer,
> int bytes, int offset)
> {
> struct inode *inode = page->mapping->host;
> struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
> - void *pageaddr;
> int i, mask = (1 << (msblk->block_log - PAGE_CACHE_SHIFT)) - 1;
> int start_index = page->index & ~mask, end_index = start_index | mask;
>
> @@ -406,12 +422,7 @@ void squashfs_copy_cache(struct page *page, struct squashfs_cache_entry *buffer,
> if (PageUptodate(push_page))
> goto skip_page;
>
> - pageaddr = kmap_atomic(push_page);
> - squashfs_copy_data(pageaddr, buffer, offset, avail);
> - memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
> - kunmap_atomic(pageaddr);
> - flush_dcache_page(push_page);
> - SetPageUptodate(push_page);
> + squashfs_fill_page(push_page, buffer, offset, avail);
> skip_page:
> unlock_page(push_page);
> if (i != page->index)
> diff --git a/fs/squashfs/file_direct.c b/fs/squashfs/file_direct.c
> index 43e7a7e..f4fcb8c 100644
> --- a/fs/squashfs/file_direct.c
> +++ b/fs/squashfs/file_direct.c
> @@ -144,7 +144,6 @@ static int squashfs_read_cache(struct page *target_page, u64 block, int bsize,
> struct squashfs_cache_entry *buffer = squashfs_get_datablock(i->i_sb,
> block, bsize);
> int bytes = buffer->length, res = buffer->error, n, offset = 0;
> - void *pageaddr;
>
> if (res) {
> ERROR("Unable to read page, block %llx, size %x\n", block,
> @@ -159,12 +158,7 @@ static int squashfs_read_cache(struct page *target_page, u64 block, int bsize,
> if (page[n] == NULL)
> continue;
>
> - pageaddr = kmap_atomic(page[n]);
> - squashfs_copy_data(pageaddr, buffer, offset, avail);
> - memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
> - kunmap_atomic(pageaddr);
> - flush_dcache_page(page[n]);
> - SetPageUptodate(page[n]);
> + squashfs_fill_page(page[n], buffer, offset, avail);
> unlock_page(page[n]);
> if (page[n] != target_page)
> page_cache_release(page[n]);
> diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
> index 887d6d2..d8d4372 100644
> --- a/fs/squashfs/squashfs.h
> +++ b/fs/squashfs/squashfs.h
> @@ -67,6 +67,7 @@ extern __le64 *squashfs_read_fragment_index_table(struct super_block *,
> u64, u64, unsigned int);
>
> /* file.c */
> +void squashfs_fill_page(struct page *, struct squashfs_cache_entry *, int, int);
> void squashfs_copy_cache(struct page *, struct squashfs_cache_entry *, int,
> int);
>
> --
> 2.7.4
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list