From 285227b68c8212a9b9bd37049335510dcff3a5ed Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Tue, 1 Feb 2011 12:21:31 -0500 Subject: [PATCH] Try to fix some obvious bugs in hfsplus mount failure handling (#673857) --- hfsplus-01-dont-leak-buffer.patch | 24 +++++++++++++++ hfsplus-02-fill-super-skip-cleanup.patch | 38 +++++++++++++++++++++++ hfsplus-03-zero-vhdr-on-free.patch | 39 ++++++++++++++++++++++++ hfsplus-04-check-for-vhdr.patch | 28 +++++++++++++++++ kernel.spec | 15 +++++++++ 5 files changed, 144 insertions(+) create mode 100644 hfsplus-01-dont-leak-buffer.patch create mode 100644 hfsplus-02-fill-super-skip-cleanup.patch create mode 100644 hfsplus-03-zero-vhdr-on-free.patch create mode 100644 hfsplus-04-check-for-vhdr.patch diff --git a/hfsplus-01-dont-leak-buffer.patch b/hfsplus-01-dont-leak-buffer.patch new file mode 100644 index 000000000..225166800 --- /dev/null +++ b/hfsplus-01-dont-leak-buffer.patch @@ -0,0 +1,24 @@ +hfsplus: Don't leak buffer on error + +Signed-Off-By: Chuck Ebbert + +--- vanilla-2.6.38-rc2-git9.orig/fs/hfsplus/part_tbl.c ++++ vanilla-2.6.38-rc2-git9/fs/hfsplus/part_tbl.c +@@ -134,7 +134,7 @@ int hfs_part_find(struct super_block *sb + res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, + data, READ); + if (res) +- return res; ++ goto out; + + switch (be16_to_cpu(*((__be16 *)data))) { + case HFS_OLD_PMAP_MAGIC: +@@ -147,7 +147,7 @@ int hfs_part_find(struct super_block *sb + res = -ENOENT; + break; + } +- ++out: + kfree(data); + return res; + } diff --git a/hfsplus-02-fill-super-skip-cleanup.patch b/hfsplus-02-fill-super-skip-cleanup.patch new file mode 100644 index 000000000..d81d51dcf --- /dev/null +++ b/hfsplus-02-fill-super-skip-cleanup.patch @@ -0,0 +1,38 @@ +hfsplus: Skip cleanup on early failures + +Signed-Off-By: Chuck Ebbert + +--- vanilla-2.6.38-rc2-git9.orig/fs/hfsplus/super.c ++++ vanilla-2.6.38-rc2-git9/fs/hfsplus/super.c +@@ -344,14 +344,13 @@ static int hfsplus_fill_super(struct sup + if (!sbi) + return -ENOMEM; + +- sb->s_fs_info = sbi; + mutex_init(&sbi->alloc_mutex); + mutex_init(&sbi->vh_mutex); + hfsplus_fill_defaults(sbi); + if (!hfsplus_parse_options(data, sbi)) { + printk(KERN_ERR "hfs: unable to parse mount options\n"); +- err = -EINVAL; +- goto cleanup; ++ kfree(sbi); ++ return -EINVAL; + } + + /* temporarily use utf8 to correctly find the hidden dir below */ +@@ -359,10 +358,12 @@ static int hfsplus_fill_super(struct sup + sbi->nls = load_nls("utf8"); + if (!sbi->nls) { + printk(KERN_ERR "hfs: unable to load nls for utf8\n"); +- err = -EINVAL; +- goto cleanup; ++ kfree(sbi); ++ return -EINVAL; + } + ++ sb->s_fs_info = sbi; ++ + /* Grab the volume header */ + if (hfsplus_read_wrapper(sb)) { + if (!silent) diff --git a/hfsplus-03-zero-vhdr-on-free.patch b/hfsplus-03-zero-vhdr-on-free.patch new file mode 100644 index 000000000..6d3f8df22 --- /dev/null +++ b/hfsplus-03-zero-vhdr-on-free.patch @@ -0,0 +1,39 @@ +hfsplus: Clear volume header pointers on failure + +The next patch will use NULL volume header to determine whether +to flush the superblock. Also fix two failure cases so they +clear the headers before exiting. + +Signed-Off-By: Chuck Ebbert + +--- vanilla-2.6.38-rc2-git9.orig/fs/hfsplus/wrapper.c ++++ vanilla-2.6.38-rc2-git9/fs/hfsplus/wrapper.c +@@ -167,7 +167,7 @@ reread: + break; + case cpu_to_be16(HFSP_WRAP_MAGIC): + if (!hfsplus_read_mdb(sbi->s_vhdr, &wd)) +- goto out; ++ goto out_free_backup_vhdr; + wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; + part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; + part_size = wd.embed_count * wd.ablk_size; +@@ -179,7 +179,7 @@ reread: + * (should do this only for cdrom/loop though) + */ + if (hfs_part_find(sb, &part_start, &part_size)) +- goto out; ++ goto out_free_backup_vhdr; + goto reread; + } + +@@ -230,8 +230,10 @@ reread: + + out_free_backup_vhdr: + kfree(sbi->s_backup_vhdr); ++ sbi->s_backup_vhdr = NULL; + out_free_vhdr: + kfree(sbi->s_vhdr); ++ sbi->s_vhdr = NULL; + out: + return error; + } diff --git a/hfsplus-04-check-for-vhdr.patch b/hfsplus-04-check-for-vhdr.patch new file mode 100644 index 000000000..b31e40d98 --- /dev/null +++ b/hfsplus-04-check-for-vhdr.patch @@ -0,0 +1,28 @@ +hfsplus: Check for NULL volume header + +If volume header is null there is not much to do in put_super(). + +Signed-Off-By: Chuck Ebbert + +--- vanilla-2.6.38-rc2-git9.orig/fs/hfsplus/super.c ++++ vanilla-2.6.38-rc2-git9/fs/hfsplus/super.c +@@ -237,7 +237,10 @@ static void hfsplus_put_super(struct sup + if (!sb->s_fs_info) + return; + +- if (!(sb->s_flags & MS_RDONLY) && sbi->s_vhdr) { ++ if (!sbi->s_vhdr) ++ goto out_unload_nls; ++ ++ if (!(sb->s_flags & MS_RDONLY)) { + struct hfsplus_vh *vhdr = sbi->s_vhdr; + + vhdr->modify_date = hfsp_now2mt(); +@@ -253,6 +256,7 @@ static void hfsplus_put_super(struct sup + iput(sbi->hidden_dir); + kfree(sbi->s_vhdr); + kfree(sbi->s_backup_vhdr); ++out_unload_nls: + unload_nls(sbi->nls); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; diff --git a/kernel.spec b/kernel.spec index 817820810..d3d6013c7 100644 --- a/kernel.spec +++ b/kernel.spec @@ -735,6 +735,12 @@ Patch12430: can-softing-depend-on-iomem.patch Patch12431: nfs-2.6.38-bugfixes.patch +# rhbz#673857 +Patch12432: hfsplus-01-dont-leak-buffer.patch +Patch12433: hfsplus-02-fill-super-skip-cleanup.patch +Patch12434: hfsplus-03-zero-vhdr-on-free.patch +Patch12435: hfsplus-04-check-for-vhdr.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1352,6 +1358,12 @@ ApplyPatch can-softing-depend-on-iomem.patch ApplyPatch nfs-2.6.38-bugfixes.patch +# rhbz#673857 +ApplyPatch hfsplus-01-dont-leak-buffer.patch +ApplyPatch hfsplus-02-fill-super-skip-cleanup.patch +ApplyPatch hfsplus-03-zero-vhdr-on-free.patch +ApplyPatch hfsplus-04-check-for-vhdr.patch + # END OF PATCH APPLICATIONS %endif @@ -1964,6 +1976,9 @@ fi # ||----w | # || || %changelog +* Mon Feb 01 2011 Chuck Ebbert +- Try to fix some obvious bugs in hfsplus mount failure handling (#673857) + * Mon Jan 31 2011 Chuck Ebbert 2.6.38-0.rc2.git9.1 - Linux 2.6.38-rc2-git9