[PATCH 3.2 012/152] UBI: Fix invalid vfree()

2015-02-16 Thread Ben Hutchings
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()

2015-02-16 Thread Ben Hutchings
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/