Re: Stale expression reference causing use-after-free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

It would seem that this issue is responsible for the crash I've seen
randomly happening with gconf (2.6.36-rc6, before my generalization's
branch). So far, I've traced it to the following line in
menu_finalize():

sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));

The crash happen in expr_copy(). expr_transform() is never being
called. The trace is the following:

Program received signal SIGSEGV, Segmentation fault.
0xbb1f085c in ?? () from /usr/lib/libc.so.12
(gdb) bt
#0  0xbb1f085c in ?? () from /usr/lib/libc.so.12
#1  0xbb1f0e4b in malloc () from /usr/lib/libc.so.12
#2  0x0805277f in expr_copy (org=0xba790fd0) at scripts/kconfig/expr.c:79
#3  0x080527e9 in expr_copy (org=0xba790fd0) at scripts/kconfig/expr.c:86
#4  0x00000001 in ?? ()
#5  0x00000000 in ?? ()

however, with the small patch attached, we get a bit more information:

(gdb) print expr_copy_nest
$1 = 43391

After reducing the stack size from 2048k (default) to 1024k:

(gdb) print expr_copy_nest
$1 = 21545

and bumping it to 4096k:

(gdb) print expr_copy_nest
$1 = 87081

so we're dying from stack exhaustion, because expr_copy() is given a
really nasty symbol:

(gdb) print org
$5 = (struct expr *) 0xba790fd0
(gdb) print *org
$6 = {type = E_NOT, left = {expr = 0xba790fd0, sym = 0xba790fd0},
right = {expr = 0x0, sym = 0x0}}

Reverting 246cf9c26bf11f2bffbecea6e5bd222eee7b1df8 fixes the crash.

 - Arnaud


On Sun, Sep 19, 2010 at 12:56 AM, Arnaud Lacombe <lacombar@xxxxxxxxx> wrote:
> Hi,
>
> I've been experiencing a use-after-free with the current kconfig (from
> for-next, but I believe mainline is affected too), related to the
> introduction of commit 246cf9c26bf11f2bffbecea6e5bd222eee7b1df8. The
> symptoms with the attached test case and patch to highlight the
> problem is the following:
>
> % scripts/kconfig/mconf Kconfig.testcase
> [...]
> Invalid expr 0xbb9124a0 at scripts/kconfig/menu.c:295 in
> menu_finalize(): 41414141
> zsh: abort (core dumped)  scripts/kconfig/mconf Kconfig.testcase
>
> The backtrace is not really surprising:
>
> #2  0xbbb9fbd6 in abort () from /usr/lib/libc.so.12
> #3  0x0804f23a in menu_finalize (parent=0xbb911e20) at
> scripts/kconfig/menu.c:295
> #4  0x0804eb6d in menu_finalize (parent=0xbb911df0) at
> scripts/kconfig/menu.c:292
> #5  0x0804f166 in menu_finalize (parent=0xbb911d60) at
> scripts/kconfig/menu.c:320
> #6  0x0804eb6d in menu_finalize (parent=0xbb911c10) at
> scripts/kconfig/menu.c:292
> #7  0x0804eb6d in menu_finalize (parent=0x8069ea0) at scripts/kconfig/menu.c:292
> #8  0x080535d7 in conf_parse (name=0x804aa61 "Ç\004$") at
> scripts/kconfig/zconf.tab.c:2242
> #9  0x0804aa61 in main (ac=Cannot access memory at address 0x0
>
> (gdb) frame 3
> #3  0x0804f23a in menu_finalize (parent=0xbb911e20) at
> scripts/kconfig/menu.c:295
> 295                     EXPR_CHECK(parent->dir_dep);
>
> So far, I tracked this issue down to the faulty expression being freed
> by expr_eliminate_dups1() in the previous iteration of
> menu_initialize(), on the following line
>
> basedep = expr_eliminate_dups(basedep);
>
> The testcase is a stripped down Kconfig from the tree.
>
>  - Arnaud
>
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index ccd6563..e2b7f01 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -63,12 +59,18 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
 	return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
 }
 
+int expr_copy_nest = 0;
+
 struct expr *expr_copy(struct expr *org)
 {
 	struct expr *e;
 
-	if (!org)
-		return NULL;
+	expr_copy_nest++;
+
+	if (!org) {
+		e = NULL;
+		goto bail_out;
+	}
 
 	e = malloc(sizeof(*org));
 	memcpy(e, org, sizeof(*org));
@@ -97,6 +99,9 @@ struct expr *expr_copy(struct expr *org)
 		break;
 	}
 
+bail_out:
+	expr_copy_nest--;
+
 	return e;
 }
 

[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux