Commit 5d3805af authored by Dan Carpenter's avatar Dan Carpenter Committed by Richard Weinberger
Browse files

ubi: Fix an error pointer dereference in error handling code



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>
parent ff90bdfb
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -1137,7 +1137,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	struct rb_node *tmp_rb;
	int ret, i, j, free_peb_count, used_peb_count, vol_count;
	int scrub_peb_count, erase_peb_count;
	unsigned long *seen_pebs = NULL;
	unsigned long *seen_pebs;

	fm_raw = ubi->fm_buf;
	memset(ubi->fm_buf, 0, ubi->fm_size);
@@ -1151,7 +1151,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	dvbuf = new_fm_vbuf(ubi, UBI_FM_DATA_VOLUME_ID);
	if (!dvbuf) {
		ret = -ENOMEM;
		goto out_kfree;
		goto out_free_avbuf;
	}

	avhdr = ubi_get_vid_hdr(avbuf);
@@ -1160,7 +1160,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	seen_pebs = init_seen(ubi);
	if (IS_ERR(seen_pebs)) {
		ret = PTR_ERR(seen_pebs);
		goto out_kfree;
		goto out_free_dvbuf;
	}

	spin_lock(&ubi->volumes_lock);
@@ -1328,7 +1328,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avbuf);
	if (ret) {
		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++) {
@@ -1350,7 +1350,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
		if (ret) {
			ubi_err(ubi, "unable to write vid_hdr to PEB %i!",
				new_fm->e[i]->pnum);
			goto out_kfree;
			goto out_free_seen;
		}
	}

@@ -1360,7 +1360,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
		if (ret) {
			ubi_err(ubi, "unable to write fastmap to PEB %i!",
				new_fm->e[i]->pnum);
			goto out_kfree;
			goto out_free_seen;
		}
	}

@@ -1370,10 +1370,13 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	ret = self_check_seen(ubi, seen_pebs);
	dbg_bld("fastmap written!");

out_kfree:
	ubi_free_vid_buf(avbuf);
	ubi_free_vid_buf(dvbuf);
out_free_seen:
	free_seen(seen_pebs);
out_free_dvbuf:
	ubi_free_vid_buf(dvbuf);
out_free_avbuf:
	ubi_free_vid_buf(avbuf);

out:
	return ret;
}