Commit d9e9451c authored by Dan Carpenter's avatar Dan Carpenter Committed by Greg Kroah-Hartman

ubi: Fix an error pointer dereference in error handling code

commit 5d3805af upstream.

If "seen_pebs = init_seen(ubi);" fails then "seen_pebs" is an error pointer
and we try to kfree() it which results in an Oops.

This patch re-arranges the error handling so now it only frees things
which have been allocated successfully.

Fixes: daef3dd1 ("UBI: Fastmap: Add self check to detect absent PEBs")
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5fe3a95d
...@@ -1146,7 +1146,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1146,7 +1146,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
struct rb_node *tmp_rb; struct rb_node *tmp_rb;
int ret, i, j, free_peb_count, used_peb_count, vol_count; int ret, i, j, free_peb_count, used_peb_count, vol_count;
int scrub_peb_count, erase_peb_count; int scrub_peb_count, erase_peb_count;
unsigned long *seen_pebs = NULL; unsigned long *seen_pebs;
fm_raw = ubi->fm_buf; fm_raw = ubi->fm_buf;
memset(ubi->fm_buf, 0, ubi->fm_size); memset(ubi->fm_buf, 0, ubi->fm_size);
...@@ -1160,7 +1160,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1160,7 +1160,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
dvbuf = new_fm_vbuf(ubi, UBI_FM_DATA_VOLUME_ID); dvbuf = new_fm_vbuf(ubi, UBI_FM_DATA_VOLUME_ID);
if (!dvbuf) { if (!dvbuf) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_kfree; goto out_free_avbuf;
} }
avhdr = ubi_get_vid_hdr(avbuf); avhdr = ubi_get_vid_hdr(avbuf);
...@@ -1169,7 +1169,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1169,7 +1169,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
seen_pebs = init_seen(ubi); seen_pebs = init_seen(ubi);
if (IS_ERR(seen_pebs)) { if (IS_ERR(seen_pebs)) {
ret = PTR_ERR(seen_pebs); ret = PTR_ERR(seen_pebs);
goto out_kfree; goto out_free_dvbuf;
} }
spin_lock(&ubi->volumes_lock); spin_lock(&ubi->volumes_lock);
...@@ -1337,7 +1337,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1337,7 +1337,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avbuf); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avbuf);
if (ret) { if (ret) {
ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); ubi_err(ubi, "unable to write vid_hdr to fastmap SB!");
goto out_kfree; goto out_free_seen;
} }
for (i = 0; i < new_fm->used_blocks; i++) { for (i = 0; i < new_fm->used_blocks; i++) {
...@@ -1359,7 +1359,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1359,7 +1359,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
if (ret) { if (ret) {
ubi_err(ubi, "unable to write vid_hdr to PEB %i!", ubi_err(ubi, "unable to write vid_hdr to PEB %i!",
new_fm->e[i]->pnum); new_fm->e[i]->pnum);
goto out_kfree; goto out_free_seen;
} }
} }
...@@ -1369,7 +1369,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1369,7 +1369,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
if (ret) { if (ret) {
ubi_err(ubi, "unable to write fastmap to PEB %i!", ubi_err(ubi, "unable to write fastmap to PEB %i!",
new_fm->e[i]->pnum); new_fm->e[i]->pnum);
goto out_kfree; goto out_free_seen;
} }
} }
...@@ -1379,10 +1379,13 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ...@@ -1379,10 +1379,13 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
ret = self_check_seen(ubi, seen_pebs); ret = self_check_seen(ubi, seen_pebs);
dbg_bld("fastmap written!"); dbg_bld("fastmap written!");
out_kfree: out_free_seen:
ubi_free_vid_buf(avbuf);
ubi_free_vid_buf(dvbuf);
free_seen(seen_pebs); free_seen(seen_pebs);
out_free_dvbuf:
ubi_free_vid_buf(dvbuf);
out_free_avbuf:
ubi_free_vid_buf(avbuf);
out: out:
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment