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