lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 20 Oct 2022 20:02:02 +0700
From:   Bagas Sanjaya <bagasdotme@...il.com>
To:     Jintao Yin <nicememory@...il.com>, phillip@...ashfs.org.uk
Cc:     hsinyi@...omium.org, linux-kernel@...r.kernel.org,
        marcmiltenberger@...il.com, mirsad.todorovac@....unizg.hr,
        regressions@...mhuis.info, regressions@...ts.linux.dev,
        srw@...dewatkins.net
Subject: Re: BISECT result: 6.0.0-RC kernels trigger Firefox snap bug with
 6.0.0-rc3 through 6.0.0-rc7

On 10/20/22 14:43, Jintao Yin wrote:
> Ignore my before diff. I didn't notice the end_index caculation greater
> than file_end part. Use the following diff instead.
> 
> This diff is based on Phillip's latest two patches and improves the logic
> to update the status of pages only if page actor touches them.
> 
> Please help test and feedbacks are welcome.
> 
> Thanks,
> 
> Jintao
> 
> diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
> index e56510964b22..5efa2a9f9630 100644
> --- a/fs/squashfs/file.c
> +++ b/fs/squashfs/file.c
> @@ -506,8 +506,9 @@ static int squashfs_readahead_fragment(struct page **page,
>  		squashfs_i(inode)->fragment_size);
>  	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
>  	unsigned int n, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
> +	int res = buffer->error;
>  
> -	if (buffer->error)
> +	if (res)
>  		goto out;
>  
>  	expected += squashfs_i(inode)->fragment_offset;
> @@ -529,7 +530,7 @@ static int squashfs_readahead_fragment(struct page **page,
>  
>  out:
>  	squashfs_cache_put(buffer);
> -	return buffer->error;
> +	return res;
>  }
>  
>  static void squashfs_readahead(struct readahead_control *ractl)
> @@ -557,6 +558,7 @@ static void squashfs_readahead(struct readahead_control *ractl)
>  		int res, bsize;
>  		u64 block = 0;
>  		unsigned int expected;
> +		int nr_used_pages;
>  
>  		nr_pages = __readahead_batch(ractl, pages, max_pages);
>  		if (!nr_pages)
> @@ -593,18 +595,18 @@ static void squashfs_readahead(struct readahead_control *ractl)
>  
>  		res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor);
>  
> -		squashfs_page_actor_free(actor);
> +		nr_used_pages = squashfs_page_actor_free(actor);
>  
>  		if (res == expected) {
>  			int bytes;
>  
>  			/* Last page (if present) may have trailing bytes not filled */
>  			bytes = res % PAGE_SIZE;
> -			if (pages[nr_pages - 1]->index == file_end && bytes)
> -				memzero_page(pages[nr_pages - 1], bytes,
> +			if (index == file_end && bytes && nr_used_pages > 0)
> +				memzero_page(pages[nr_used_pages - 1], bytes,
>  					     PAGE_SIZE - bytes);
>  
> -			for (i = 0; i < nr_pages; i++) {
> +			for (i = 0; i < nr_used_pages; i++) {
>  				flush_dcache_page(pages[i]);
>  				SetPageUptodate(pages[i]);
>  			}
> diff --git a/fs/squashfs/file_direct.c b/fs/squashfs/file_direct.c
> index f1ccad519e28..1bb0347f98b0 100644
> --- a/fs/squashfs/file_direct.c
> +++ b/fs/squashfs/file_direct.c
> @@ -30,10 +30,9 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize,
>  	int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
>  	int start_index = target_page->index & ~mask;
>  	int end_index = start_index | mask;
> -	int i, n, pages, bytes, res = -ENOMEM;
> +	int i, n, pages, used_pages, bytes, res = -ENOMEM;
>  	struct page **page;
>  	struct squashfs_page_actor *actor;
> -	void *pageaddr;
>  
>  	if (end_index > file_end)
>  		end_index = file_end;
> @@ -74,7 +73,7 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize,
>  	/* Decompress directly into the page cache buffers */
>  	res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor);
>  
> -	squashfs_page_actor_free(actor);
> +	used_pages = squashfs_page_actor_free(actor);
>  
>  	if (res < 0)
>  		goto mark_errored;
> @@ -86,16 +85,18 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize,
>  
>  	/* Last page (if present) may have trailing bytes not filled */
>  	bytes = res % PAGE_SIZE;
> -	if (page[pages - 1]->index == end_index && bytes) {
> -		pageaddr = kmap_local_page(page[pages - 1]);
> -		memset(pageaddr + bytes, 0, PAGE_SIZE - bytes);
> -		kunmap_local(pageaddr);
> +	if (used_pages > 0 && page[used_pages - 1]->index == end_index &&
> +	    bytes) {
> +		memzero_page(page[used_pages - 1], bytes,
> +			     PAGE_SIZE - bytes);
>  	}
>  
>  	/* Mark pages as uptodate, unlock and release */
>  	for (i = 0; i < pages; i++) {
> -		flush_dcache_page(page[i]);
> -		SetPageUptodate(page[i]);
> +		if (i < used_pages) {
> +			flush_dcache_page(page[i]);
> +			SetPageUptodate(page[i]);
> +		}
>  		unlock_page(page[i]);
>  		if (page[i] != target_page)
>  			put_page(page[i]);
> @@ -112,8 +113,10 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize,
>  	for (i = 0; i < pages; i++) {
>  		if (page[i] == NULL || page[i] == target_page)
>  			continue;
> -		flush_dcache_page(page[i]);
> -		SetPageError(page[i]);
> +		if (i < used_pages) {
> +			flush_dcache_page(page[i]);
> +			SetPageError(page[i]);
> +		}
>  		unlock_page(page[i]);
>  		put_page(page[i]);
>  	}
> diff --git a/fs/squashfs/page_actor.h b/fs/squashfs/page_actor.h
> index 95ffbb543d91..c2c5c3937ef9 100644
> --- a/fs/squashfs/page_actor.h
> +++ b/fs/squashfs/page_actor.h
> @@ -29,10 +29,12 @@ extern struct squashfs_page_actor *squashfs_page_actor_init(void **buffer,
>  extern struct squashfs_page_actor *squashfs_page_actor_init_special(
>  				struct squashfs_sb_info *msblk,
>  				struct page **page, int pages, int length);
> -static inline void squashfs_page_actor_free(struct squashfs_page_actor *actor)
> +static inline int squashfs_page_actor_free(struct squashfs_page_actor *actor)
>  {
> +	int res = actor->next_page;
>  	kfree(actor->tmp_buffer);
>  	kfree(actor);
> +	return res;
>  }
>  static inline void *squashfs_first_page(struct squashfs_page_actor *actor)
>  {

Hi Jintao,

Booting v6.1-rc1 with your patch applied, I got mixed results. On hello-world
snap, it runs without errors. On lxd, I got the Verneed regression as
originally reported. Sometimes I also get snapd panic.

Thanks.

-- 
An old man doll... just what I always wanted! - Clara

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ