All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florin Malita <fmalita@gmail.com>
To: Satyam Sharma <satyam.sharma@gmail.com>
Cc: linux-mtd@lists.infradead.org,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] UBI: dereference after kfree in create_vtbl
Date: Fri, 04 May 2007 19:22:01 -0400	[thread overview]
Message-ID: <463BC019.40305@gmail.com> (raw)
In-Reply-To: <a781481a0705041442h37453fb6k26d04eb5356e9dc0@mail.gmail.com>

Hi Satyam,

Satyam Sharma wrote:
> Eeks ... no, wait. You found a (two, actually) bug alright, but fixed
> it wrong. When we fail a write, we *must* add it to the corrupted list
> and _then_ attempt to retry. So, the "if (++tries <= 5)" applies to
> "if (!err) goto retry;" and not to the ubi_scan_add_to_list(). The
> difference is quite subtle here ...

Not being familiar with the code, I was specifically trying to preserve 
the old semantics and only address the use-after-free issue. So if there 
was another bug... well, I guess I succeeded at preserving it ;)

> The correct fix should actually be as follows: (Artem, this is diffed
> on the original vtbl.c)
[snip]
> +    err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec, 
> &si->corr);
> +    kfree(new_seb);
> +    if (++tries <= 5)
>         if (!err)
>             goto retry;

There's a side effect to this change: by unconditionally overwriting err 
we lose the original error code. Then if we're exceeding the number of 
retries we'll end up returning 0 which is probably not what you want.

Return code aside, it seems the only thing ubi_scan_add_to_list() is 
doing is allocate a new struct ubi_scan_leb, initialize some fields with 
values passed from new_seb and then add it to the desired list. But 
copying new_seb to a newly allocated structure and then immediately 
freeing the old one seems redundant - why not just add new_seb to the 
corrupted list and be done? Then we don't have to deal with allocation 
failures in an error path anymore - something like this (diff against 
the original code):

Signed-off-by: Florin Malita <fmalita@gmail.com>
---

diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index b6fd6bb..2ad2d59 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -317,14 +317,10 @@ retry:
 	return err;
 
 write_error:
-	kfree(new_seb);
-	/* May be this physical eraseblock went bad, try to pick another one */
-	if (++tries <= 5) {
-		err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec,
-					   &si->corr);
-		if (!err)
-			goto retry;
-	}
+	/* Maybe this physical eraseblock went bad, try to pick another one */
+	list_add_tail(&new_seb->u.list, &si->corr);
+	if (++tries <= 5)
+		goto retry;
 out_free:
 	ubi_free_vid_hdr(ubi, vid_hdr);
 	return err;

WARNING: multiple messages have this Message-ID (diff)
From: Florin Malita <fmalita@gmail.com>
To: Satyam Sharma <satyam.sharma@gmail.com>
Cc: dedekind@infradead.org, linux-mtd@lists.infradead.org,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] UBI: dereference after kfree in create_vtbl
Date: Fri, 04 May 2007 19:22:01 -0400	[thread overview]
Message-ID: <463BC019.40305@gmail.com> (raw)
In-Reply-To: <a781481a0705041442h37453fb6k26d04eb5356e9dc0@mail.gmail.com>

Hi Satyam,

Satyam Sharma wrote:
> Eeks ... no, wait. You found a (two, actually) bug alright, but fixed
> it wrong. When we fail a write, we *must* add it to the corrupted list
> and _then_ attempt to retry. So, the "if (++tries <= 5)" applies to
> "if (!err) goto retry;" and not to the ubi_scan_add_to_list(). The
> difference is quite subtle here ...

Not being familiar with the code, I was specifically trying to preserve 
the old semantics and only address the use-after-free issue. So if there 
was another bug... well, I guess I succeeded at preserving it ;)

> The correct fix should actually be as follows: (Artem, this is diffed
> on the original vtbl.c)
[snip]
> +    err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec, 
> &si->corr);
> +    kfree(new_seb);
> +    if (++tries <= 5)
>         if (!err)
>             goto retry;

There's a side effect to this change: by unconditionally overwriting err 
we lose the original error code. Then if we're exceeding the number of 
retries we'll end up returning 0 which is probably not what you want.

Return code aside, it seems the only thing ubi_scan_add_to_list() is 
doing is allocate a new struct ubi_scan_leb, initialize some fields with 
values passed from new_seb and then add it to the desired list. But 
copying new_seb to a newly allocated structure and then immediately 
freeing the old one seems redundant - why not just add new_seb to the 
corrupted list and be done? Then we don't have to deal with allocation 
failures in an error path anymore - something like this (diff against 
the original code):

Signed-off-by: Florin Malita <fmalita@gmail.com>
---

diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index b6fd6bb..2ad2d59 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -317,14 +317,10 @@ retry:
 	return err;
 
 write_error:
-	kfree(new_seb);
-	/* May be this physical eraseblock went bad, try to pick another one */
-	if (++tries <= 5) {
-		err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec,
-					   &si->corr);
-		if (!err)
-			goto retry;
-	}
+	/* Maybe this physical eraseblock went bad, try to pick another one */
+	list_add_tail(&new_seb->u.list, &si->corr);
+	if (++tries <= 5)
+		goto retry;
 out_free:
 	ubi_free_vid_hdr(ubi, vid_hdr);
 	return err;


  reply	other threads:[~2007-05-04 23:23 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-03 15:49 [PATCH] UBI: dereference after kfree in create_vtbl Florin Malita
2007-05-04  7:17 ` Artem Bityutskiy
2007-05-04 21:42 ` Satyam Sharma
2007-05-04 21:42   ` Satyam Sharma
2007-05-04 23:22   ` Florin Malita [this message]
2007-05-04 23:22     ` Florin Malita
2007-05-05  3:55     ` Satyam Sharma
2007-05-05  3:55       ` Satyam Sharma
2007-05-05  7:55       ` Artem Bityutskiy
2007-05-05  7:55         ` Artem Bityutskiy
2007-05-05 12:26         ` Satyam Sharma
2007-05-05 12:26           ` Satyam Sharma
2007-05-05 13:18           ` Artem Bityutskiy
2007-05-05 13:18             ` Artem Bityutskiy
2007-05-05 13:48             ` Satyam Sharma
2007-05-05 13:48               ` Satyam Sharma
2007-05-05 13:59               ` Artem Bityutskiy
2007-05-05 13:59                 ` Artem Bityutskiy
2007-05-05 15:00                 ` Satyam Sharma
2007-05-05 15:00                   ` Satyam Sharma
2007-05-05 12:09       ` Artem Bityutskiy
2007-05-05 12:09         ` Artem Bityutskiy
2007-05-05 13:32         ` Satyam Sharma
2007-05-05 13:32           ` Satyam Sharma
2007-05-05 13:48           ` Artem Bityutskiy
2007-05-05 13:48             ` Artem Bityutskiy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=463BC019.40305@gmail.com \
    --to=fmalita@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=satyam.sharma@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.