[PATCH 3.2 012/152] UBI: Fix invalid vfree()
3.2.67-rc1 review patch. If anyone has any objections, please let me know. -- From: Richard Weinberger commit f38aed975c0c3645bbdfc5ebe35726e64caaf588 upstream. The logic of vfree()'ing vol->upd_buf is tied to vol->updating. In ubi_start_update() vol->updating is set long before vmalloc()'ing vol->upd_buf. If we encounter a write failure in ubi_start_update() before vmalloc() the UBI device release function will try to vfree() vol->upd_buf because vol->updating is set. Fix this by allocating vol->upd_buf directly after setting vol->updating. Fixes: [ 31.559338] UBI warning: vol_cdev_release: update of volume 2 not finished, volume is damaged [ 31.559340] [ cut here ] [ 31.559343] WARNING: CPU: 1 PID: 2747 at mm/vmalloc.c:1446 __vunmap+0xe3/0x110() [ 31.559344] Trying to vfree() nonexistent vm area (c90001f2b000) [ 31.559345] Modules linked in: [ 31.565620] 0bba 88002a0cbdb0 818f0497 88003b9ba148 [ 31.566347] 88002a0cbde0 8156f515 88003b9ba148 0bba [ 31.567073] 88002a0cbe88 8156c10a [ 31.567793] Call Trace: [ 31.568034] [] dump_stack+0x4e/0x7a [ 31.568510] [] ubi_io_write_vid_hdr+0x155/0x160 [ 31.569084] [] ubi_eba_write_leb+0x23a/0x870 [ 31.569628] [] vol_cdev_write+0x226/0x380 [ 31.570155] [] vfs_write+0xb5/0x1f0 [ 31.570627] [] SyS_pwrite64+0x6a/0xa0 [ 31.571123] [] system_call_fastpath+0x16/0x1b Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy Signed-off-by: Ben Hutchings --- drivers/mtd/ubi/upd.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -135,6 +135,10 @@ int ubi_start_update(struct ubi_device * ubi_assert(!vol->updating && !vol->changing_leb); vol->updating = 1; + vol->upd_buf = vmalloc(ubi->leb_size); + if (!vol->upd_buf) + return -ENOMEM; + err = set_update_marker(ubi, vol); if (err) return err; @@ -154,14 +158,12 @@ int ubi_start_update(struct ubi_device * err = clear_update_marker(ubi, vol, 0); if (err) return err; + + vfree(vol->upd_buf); vol->updating = 0; return 0; } - vol->upd_buf = vmalloc(ubi->leb_size); - if (!vol->upd_buf) - return -ENOMEM; - vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, vol->usable_leb_size); vol->upd_bytes = bytes; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3.2 012/152] UBI: Fix invalid vfree()
3.2.67-rc1 review patch. If anyone has any objections, please let me know. -- From: Richard Weinberger rich...@nod.at commit f38aed975c0c3645bbdfc5ebe35726e64caaf588 upstream. The logic of vfree()'ing vol-upd_buf is tied to vol-updating. In ubi_start_update() vol-updating is set long before vmalloc()'ing vol-upd_buf. If we encounter a write failure in ubi_start_update() before vmalloc() the UBI device release function will try to vfree() vol-upd_buf because vol-updating is set. Fix this by allocating vol-upd_buf directly after setting vol-updating. Fixes: [ 31.559338] UBI warning: vol_cdev_release: update of volume 2 not finished, volume is damaged [ 31.559340] [ cut here ] [ 31.559343] WARNING: CPU: 1 PID: 2747 at mm/vmalloc.c:1446 __vunmap+0xe3/0x110() [ 31.559344] Trying to vfree() nonexistent vm area (c90001f2b000) [ 31.559345] Modules linked in: [ 31.565620] 0bba 88002a0cbdb0 818f0497 88003b9ba148 [ 31.566347] 88002a0cbde0 8156f515 88003b9ba148 0bba [ 31.567073] 88002a0cbe88 8156c10a [ 31.567793] Call Trace: [ 31.568034] [818f0497] dump_stack+0x4e/0x7a [ 31.568510] [8156f515] ubi_io_write_vid_hdr+0x155/0x160 [ 31.569084] [8156c10a] ubi_eba_write_leb+0x23a/0x870 [ 31.569628] [81569b36] vol_cdev_write+0x226/0x380 [ 31.570155] [81179265] vfs_write+0xb5/0x1f0 [ 31.570627] [81179f8a] SyS_pwrite64+0x6a/0xa0 [ 31.571123] [818fde12] system_call_fastpath+0x16/0x1b Signed-off-by: Richard Weinberger rich...@nod.at Signed-off-by: Artem Bityutskiy artem.bityuts...@linux.intel.com Signed-off-by: Ben Hutchings b...@decadent.org.uk --- drivers/mtd/ubi/upd.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -135,6 +135,10 @@ int ubi_start_update(struct ubi_device * ubi_assert(!vol-updating !vol-changing_leb); vol-updating = 1; + vol-upd_buf = vmalloc(ubi-leb_size); + if (!vol-upd_buf) + return -ENOMEM; + err = set_update_marker(ubi, vol); if (err) return err; @@ -154,14 +158,12 @@ int ubi_start_update(struct ubi_device * err = clear_update_marker(ubi, vol, 0); if (err) return err; + + vfree(vol-upd_buf); vol-updating = 0; return 0; } - vol-upd_buf = vmalloc(ubi-leb_size); - if (!vol-upd_buf) - return -ENOMEM; - vol-upd_ebs = div_u64(bytes + vol-usable_leb_size - 1, vol-usable_leb_size); vol-upd_bytes = bytes; -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/