From: Greg Kroah-Hartman Date: Tue, 11 Feb 2014 00:34:31 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.4.80~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f1a99c723f3c638b9fc187783b8ea6a119fa793;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: hpfs-deadlock-and-race-in-directory-lseek.patch --- diff --git a/queue-3.4/hpfs-deadlock-and-race-in-directory-lseek.patch b/queue-3.4/hpfs-deadlock-and-race-in-directory-lseek.patch new file mode 100644 index 00000000000..27f70d76df0 --- /dev/null +++ b/queue-3.4/hpfs-deadlock-and-race-in-directory-lseek.patch @@ -0,0 +1,61 @@ +From 31abdab9c11bb1694ecd1476a7edbe8e964d94ac Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sat, 18 May 2013 02:38:52 -0400 +Subject: hpfs: deadlock and race in directory lseek() + +From: Al Viro + +commit 31abdab9c11bb1694ecd1476a7edbe8e964d94ac upstream. + +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 +Cc: Mikulas Patocka +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hpfs/dir.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/hpfs/dir.c ++++ b/fs/hpfs/dir.c +@@ -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; + } + diff --git a/queue-3.4/series b/queue-3.4/series index b0930ed45f2..c86d09fae9e 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -20,3 +20,4 @@ drm-radeon-skip-colorbuffer-checking-if-color_info.format-is-set-to-invalid.patc drm-radeon-set-the-full-cache-bit-for-fences-on-r7xx.patch drm-radeon-dce4-clear-bios-scratch-dpms-bit-v2.patch pci-enable-ari-if-dev-and-upstream-bridge-support-it-disable-otherwise.patch +hpfs-deadlock-and-race-in-directory-lseek.patch