Re: [PATCH 3.9 and earlier] hpfs: deadlock and race in directory lseek()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Mon, 10 Feb 2014, Greg KH wrote:

> On Tue, Feb 11, 2014 at 12:06:58AM +0100, Mikulas Patocka wrote:
> > Hi
> > 
> > This is backport of patch 31abdab9c11bb1694ecd1476a7edbe8e964d94ac for 
> > stable kernels 3.9 and earlier.
> > 
> > Mikulas
> > 
> > 
> > commit 31abdab9c11bb1694ecd1476a7edbe8e964d94ac
> > Author: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> > Date:   Sat May 18 02:38:52 2013 -0400
> > 
> >     hpfs: deadlock and race in directory lseek()
> > 
> >     For one thing, there's an ABBA deadlock on hpfs fs-wide lock and i_mutex
> >     in hpfs_dir_lseek() - there's a lot of methods that grab the former with
> >     the caller already holding the latter, so it must take i_mutex first.
> > 
> >     For another, locking the damn thing, carefully validating the offset,
> >     then dropping locks and assigning the offset is obviously racy.
> > 
> >     Moreover, we _must_ do hpfs_add_pos(), or the machinery in dnode.c
> >     won't modify the sucker on B-tree surgeries.
> > 
> >     Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> > 
> > 
> > ---
> >  fs/hpfs/dir.c  |   10 ++++++----
> >  fs/hpfs/file.c |   36 ++++++++++++++++++++----------------
> >  2 files changed, 26 insertions(+), 20 deletions(-)
> 
> That diffstat does not match up with the patch below.
> 
> What went wrong?
> 
> I've just picked the original patch to backport to 3.4, if that is
> incorrect, please let me know.

I had two patches in one patch file and I split it manually - that's why 
diffstat shows also the file modified by the second patch - there is no 
problem with it, you can apply it.

Mikulas

> thanks,
> 
> greg k-h
> 
> > 
> > Index: linux-stable/fs/hpfs/dir.c
> > ===================================================================
> > --- linux-stable.orig/fs/hpfs/dir.c	2014-02-10 23:11:51.000000000 +0100
> > +++ linux-stable/fs/hpfs/dir.c	2014-02-10 23:14:53.000000000 +0100
> > @@ -33,25 +33,27 @@ static loff_t hpfs_dir_lseek(struct file
> >  	if (whence == SEEK_DATA || whence == SEEK_HOLE)
> >  		return -EINVAL;
> >  
> > +	mutex_lock(&i->i_mutex);
> >  	hpfs_lock(s);
> >  
> >  	/*printk("dir lseek\n");*/
> >  	if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
> > -	mutex_lock(&i->i_mutex);
> >  	pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1;
> >  	while (pos != new_off) {
> >  		if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh);
> >  		else goto fail;
> >  		if (pos == 12) goto fail;
> >  	}
> > -	mutex_unlock(&i->i_mutex);
> > +	hpfs_add_pos(i, &filp->f_pos);
> >  ok:
> > +	filp->f_pos = new_off;
> >  	hpfs_unlock(s);
> > -	return filp->f_pos = new_off;
> > -fail:
> >  	mutex_unlock(&i->i_mutex);
> > +	return new_off;
> > +fail:
> >  	/*printk("illegal lseek: %016llx\n", new_off);*/
> >  	hpfs_unlock(s);
> > +	mutex_unlock(&i->i_mutex);
> >  	return -ESPIPE;
> >  }
> >  
> > --
> > To unsubscribe from this list: send the line "unsubscribe stable" in
> > the body of a message to majordomo@xxxxxxxxxxxxxxx
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]