|  | From e57e0d8e818512047fe379157c3f77f1b9fabffb Mon Sep 17 00:00:00 2001 | 
|  | From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 
|  | Date: Thu, 5 Jan 2012 10:47:18 +0200 | 
|  | Subject: UBI: fix use-after-free on error path | 
|  |  | 
|  | From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 
|  |  | 
|  | commit e57e0d8e818512047fe379157c3f77f1b9fabffb upstream. | 
|  |  | 
|  | When we fail to erase a PEB, we free the corresponding erase entry object, | 
|  | but then re-schedule this object if the error code was something like -EAGAIN. | 
|  | Obviously, it is a bug to use the object after we have freed it. | 
|  |  | 
|  | Reported-by: Emese Revfy <re.emese@gmail.com> | 
|  | Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 
|  | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | 
|  |  | 
|  | --- | 
|  | drivers/mtd/ubi/wl.c |    7 ++++--- | 
|  | 1 file changed, 4 insertions(+), 3 deletions(-) | 
|  |  | 
|  | --- a/drivers/mtd/ubi/wl.c | 
|  | +++ b/drivers/mtd/ubi/wl.c | 
|  | @@ -1049,7 +1049,6 @@ static int erase_worker(struct ubi_devic | 
|  |  | 
|  | ubi_err("failed to erase PEB %d, error %d", pnum, err); | 
|  | kfree(wl_wrk); | 
|  | -	kmem_cache_free(ubi_wl_entry_slab, e); | 
|  |  | 
|  | if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || | 
|  | err == -EBUSY) { | 
|  | @@ -1062,14 +1061,16 @@ static int erase_worker(struct ubi_devic | 
|  | goto out_ro; | 
|  | } | 
|  | return err; | 
|  | -	} else if (err != -EIO) { | 
|  | +	} | 
|  | + | 
|  | +	kmem_cache_free(ubi_wl_entry_slab, e); | 
|  | +	if (err != -EIO) | 
|  | /* | 
|  | * If this is not %-EIO, we have no idea what to do. Scheduling | 
|  | * this physical eraseblock for erasure again would cause | 
|  | * errors again and again. Well, lets switch to R/O mode. | 
|  | */ | 
|  | goto out_ro; | 
|  | -	} | 
|  |  | 
|  | /* It is %-EIO, the PEB went bad */ | 
|  |  |