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] [day] [month] [year] [list]
Date:	Fri, 01 Dec 2006 13:14:07 -0600
From:	Russell Cattelan <cattelan@...hat.com>
To:	Steven Whitehouse <swhiteho@...hat.com>
Cc:	cluster-devel@...hat.com, linux-kernel@...r.kernel.org
Subject: Re: [GFS2] Fix page lock/glock deadlock [32/70]

On Thu, 2006-11-30 at 12:17 +0000, Steven Whitehouse wrote:
> >From 2ca99501fa5422e84f18333918a503433449e2b5 Mon Sep 17 00:00:00 2001
> From: Steven Whitehouse <swhiteho@...hat.com>
> Date: Wed, 8 Nov 2006 10:26:54 -0500
> Subject: [PATCH] [GFS2] Fix page lock/glock deadlock
> 
> This fixes a race between the glock and the page lock encountered
> during truncate in gfs2_readpage and gfs2_prepare_write. The gfs2_readpages
> function doesn't need the same fix since it only uses a try lock anyway, so
> it will fail back to gfs2_readpage in the case of a potential deadlock.
> 
> This bug was spotted by Russell Cattelan.\
This bug was fixed correctly by Russell Cattelan
and this is an incomplete version of my patch.


As I keep trying to point out readpages is still wrong in that
the stuffed case is not correct and results in a panic
if a file is being truncated down.
If nr_pages is calculated prior a truncate the stuffed inode
case will try to operate on pages that are no longer there.


The correct fix is to not try and handled the stuffed inode 
case at all in readpages and simply return AOP_TRUNCATED_PAGE
and let things things fall back to readpage.


> 
> Cc: Russell Cattelan <cattelan@...hat.com>
> Signed-off-by: Steven Whitehouse <swhiteho@...hat.com>
> ---
>  fs/gfs2/glock.h       |    1 -
>  fs/gfs2/ops_address.c |   13 +++++++++----
>  2 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
> index b985627..a331bf8 100644
> --- a/fs/gfs2/glock.h
> +++ b/fs/gfs2/glock.h
> @@ -27,7 +27,6 @@ #define GL_SKIP			0x00000100
>  #define GL_ATIME		0x00000200
>  #define GL_NOCACHE		0x00000400
>  #define GL_NOCANCEL		0x00001000
> -#define GL_AOP			0x00004000
>  
>  #define GLR_TRYFAILED		13
>  #define GLR_CANCELED		14
> diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
> index 5c3962c..3822189 100644
> --- a/fs/gfs2/ops_address.c
> +++ b/fs/gfs2/ops_address.c
> @@ -230,7 +230,7 @@ static int gfs2_readpage(struct file *fi
>  				/* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */
>  				goto skip_lock;
>  		}
> -		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh);
> +		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh);
>  		do_unlock = 1;
>  		error = gfs2_glock_nq_m_atime(1, &gh);
>  		if (unlikely(error))
> @@ -254,6 +254,8 @@ skip_lock:
>  out:
>  	return error;
>  out_unlock:
> +	if (error == GLR_TRYFAILED)
> +		error = AOP_TRUNCATED_PAGE;
>  	unlock_page(page);
>  	if (do_unlock)
>  		gfs2_holder_uninit(&gh);
> @@ -293,7 +295,7 @@ static int gfs2_readpages(struct file *f
>  				goto skip_lock;
>  		}
>  		gfs2_holder_init(ip->i_gl, LM_ST_SHARED,
> -				 LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh);
> +				 LM_FLAG_TRY_1CB|GL_ATIME, &gh);
>  		do_unlock = 1;
>  		ret = gfs2_glock_nq_m_atime(1, &gh);
>  		if (ret == GLR_TRYFAILED)
> @@ -366,10 +368,13 @@ static int gfs2_prepare_write(struct fil
>  	unsigned int write_len = to - from;
>  
> 
> -	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh);
> +	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|LM_FLAG_TRY_1CB, &ip->i_gh);
>  	error = gfs2_glock_nq_m_atime(1, &ip->i_gh);
> -	if (error)
> +	if (unlikely(error)) {
> +		if (error == GLR_TRYFAILED)
> +			error = AOP_TRUNCATED_PAGE;
>  		goto out_uninit;
> +	}
>  
>  	gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks);
>  
-- 
Russell Cattelan <cattelan@...hat.com>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ