Patch "mtd: ubi: fixup error correction in do_sync_erase()" has been added to the 4.3-stable tree
This is a note to let you know that I've just added the patch titled
mtd: ubi: fixup error correction in do_sync_erase()
to the 4.3-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mtd-ubi-fixup-error-correction-in-do_sync_erase.patch
and it can be found in the queue-4.3 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
1a31b20cd81d5cbc7ec6e24cb08066009a1ca32dMon Sep 17 00:00:00 2001
From: Sebastian Siewior <[email protected]>
Date: Thu, 26 Nov 2015 21:23:48 +0100
Subject: mtd: ubi: fixup error correction in do_sync_erase()
From: Sebastian Siewior <[email protected]>
commit 1a31b20cd81d5cbc7ec6e24cb08066009a1ca32d upstream.
Since fastmap we gained do_sync_erase(). This function can return an error and its error handling isn't obvious. First the memory allocation for struct ubi_work can fail and as such struct ubi_wl_entry is leaked. However if the memory allocation succeeds then the tail function takes care of the struct ubi_wl_entry. A free here could result in a double free.
To make the error handling simpler, I split the tail function into one piece which does the work and another which frees the struct ubi_work which is passed as argument. As result do_sync_erase() can keep the struct on stack and we get rid of one error source.
--- drivers/mtd/ubi/wl.c | 52 +++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-)
drivers/mtd/ubi/wl.c +28 -24
@@ -603,6 +603,7 @@ static int schedule_erase(struct ubi_devreturn 0 ; } +static int __erase_worker (struct ubi_device *ubi,struct ubi_work *wl_wrk);/** * do_sync_erase - run the erase worker synchronously. * @ubi: UBI device description object
@@ -615,20 +616,16 @@ static int schedule_erase(struct ubi_devstatic int do_sync_erase (struct ubi_device *ubi,struct ubi_wl_entry *e,int vol_id,int lnum,int torture) { -struct ubi_work *wl_wrk; +struct ubi_work wl_wrk;dbg_wl ("sync erase of PEB %i" , e->pnum); - wl_wrk =kmalloc (sizeof (struct ubi_work ),GFP_NOFS ); -if (!wl_wrk) -return -ENOMEM ; - - wl_wrk->e = e; - wl_wrk->vol_id = vol_id; - wl_wrk->lnum = lnum; - wl_wrk->torture = torture; + wl_wrk.e = e; + wl_wrk.vol_id = vol_id; + wl_wrk.lnum = lnum; + wl_wrk.torture = torture; -return erase_worker (ubi, wl_wrk,0 ); +return __erase_worker (ubi, &wl_wrk); }/**
@@ -1014,7 +1011,7 @@ out_unlock: }/** -* erase_worker - physical eraseblock erase worker function. +* __erase_worker - physical eraseblock erase worker function. * @ubi: UBI device description object * @wl_wrk: the work object * @shutdown: non-zero if the worker has to free memory and exit
@@ -1025,8 +1022,7 @@ out_unlock:* needed. Returns zero in case of success and a negative error code in case of * failure. */ -static int erase_worker (struct ubi_device *ubi,struct ubi_work *wl_wrk, -int shutdown) +static int __erase_worker (struct ubi_device *ubi,struct ubi_work *wl_wrk) {struct ubi_wl_entry *e = wl_wrk->e;int pnum = e->pnum;
@@ -1034,21 +1030,11 @@ static int erase_worker(struct ubi_devicint lnum = wl_wrk->lnum;int err, available_consumed =0 ; -if (shutdown) { -dbg_wl ("cancel erasure of PEB %d EC %d" , pnum, e->ec); -kfree (wl_wrk); -wl_entry_destroy (ubi, e); -return 0 ; - } -dbg_wl ("erase PEB %d EC %d LEB %d:%d" , pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum); err =sync_erase (ubi, e, wl_wrk->torture);if (!err) { -/* Fine, we've erased it successfully */ -kfree (wl_wrk); -spin_lock (&ubi->wl_lock);wl_tree_add (e, &ubi->free); ubi->free_count++;
@@ -1066,7 +1052,6 @@ static int erase_worker(struct ubi_devic }ubi_err (ubi,"failed to erase PEB %d, error %d" , pnum, err); -kfree (wl_wrk);if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || err == -EBUSY ) {
@@ -1150,6 +1135,25 @@ out_ro:return err; } +static int erase_worker (struct ubi_device *ubi,struct ubi_work *wl_wrk, +int shutdown) +{ +int ret; + +if (shutdown) { +struct ubi_wl_entry *e = wl_wrk->e; + +dbg_wl ("cancel erasure of PEB %d EC %d" , e->pnum, e->ec); +kfree (wl_wrk); +wl_entry_destroy (ubi, e); +return 0 ; + } + + ret =__erase_worker (ubi, wl_wrk); +kfree (wl_wrk); +return ret; +} +/** * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system. * @ubi: UBI device description object
Patches currently in stable-queue which might be from [email protected] are
queue-4.3/mtd-ubi-don-t-leak-e-if-schedule_erase-fails.patch queue-4.3/mtd-ubi-fixup-error-correction-in-do_sync_erase.patch queue-4.3/pci-host-mark-pcie-pci-msi-irq-cascade-handlers-as-irqf_no_thread.patch