Re: [patch] Real-Time Preemption, -RT-2.6.9-rc4-mm1-U6

From: Ingo Molnar
Date: Tue Oct 19 2004 - 12:42:25 EST



* Ingo Molnar <mingo@xxxxxxx> wrote:

> enabling 8K stacks ought to help this one. I've made the limit a bit
> too conservative - there's still 1000 bytes left and the assert hits.
> Here's the full trace, the large footprint seems to be in zlib
> initialization:
>
> mcount: stack overflow: 1008

i've added a stackframe-size field to the end of every stack trace
entry:

mcount: stack overflow: 1008
[<c012cdaf>] ___trace+0x105/0x117 (12)
[<c012cde7>] __mcount+0x1d/0x1f (32)
[<c013e025>] cache_grow+0xe/0x1ab (4)
[<c013e3dd>] cache_alloc_refill+0x21b/0x253 (4)
[<c010effc>] mcount+0x14/0x18 (8)
[<c013e025>] cache_grow+0xe/0x1ab (20)
[<c013e3dd>] cache_alloc_refill+0x21b/0x253 (52)
[<c013e740>] __kmalloc+0x82/0x9f (48)
[<c03607c8>] malloc+0x1e/0x20 (28)
[<c01008c9>] huft_build+0x309/0x5e8 (16)
[<c0101bec>] inflate+0x4c/0xb0 (1444)
[<c010effc>] mcount+0x14/0x18 (8)
[<c0101279>] inflate_fixed+0xcb/0x1a4 (20)
[<c0101bec>] inflate+0x4c/0xb0 (1212)
[<c010effc>] mcount+0x14/0x18 (12)
[<c0101eae>] gunzip+0x1d4/0x396 (20)
[<c036130e>] unpack_to_rootfs+0x162/0x225 (28)
[<c010effc>] mcount+0x14/0x18 (8)
[<c0100434>] init+0x0/0x124 (4)
[<c03613fe>] populate_rootfs+0x2d/0x3f (16)
[<c010046b>] init+0x37/0x124 (20)
[<c0102365>] kernel_thread_helper+0x5/0xb (20)

as suspected, zlib's huft_build() is fun:

lib/inflate.c:

#define N_MAX 288 /* maximum number of codes in any set */

STATIC int huft_build(
...
{

unsigned v[N_MAX]; /* values in order of bit length */

a whopping 1152 bytes for this local variable alone! The patch below
fixes this, but there are other overflows as well, later in the bootup.

Ingo

--- linux/lib/inflate.c.orig
+++ linux/lib/inflate.c
@@ -300,7 +300,7 @@ STATIC int huft_build(
register struct huft *q; /* points to current table */
struct huft r; /* table entry for structure assignment */
struct huft *u[BMAX]; /* table stack */
- unsigned v[N_MAX]; /* values in order of bit length */
+ unsigned *v; /* values in order of bit length */
register int w; /* bits before this table == (l * h) */
unsigned x[BMAX+1]; /* bit offsets, then code stack */
unsigned *xp; /* pointer into x */
@@ -309,6 +309,10 @@ STATIC int huft_build(

DEBG("huft1 ");

+ /* allocate new table */
+ v = (unsigned *)malloc(sizeof(unsigned)*N_MAX);
+ if (!v)
+ return 3; /* not enough memory */
/* Generate counts for each bit length */
memzero(c, sizeof(c));
p = b; i = n;
@@ -322,6 +326,7 @@ DEBG("huft1 ");
{
*t = (struct huft *)NULL;
*m = 0;
+ free(v);
return 0;
}

@@ -347,10 +352,14 @@ DEBG("huft3 ");

/* Adjust last length count to fill out codes, if needed */
for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
+ if ((y -= c[j]) < 0) {
+ free(v);
return 2; /* bad input: more codes than bits */
- if ((y -= c[i]) < 0)
+ }
+ if ((y -= c[i]) < 0) {
+ free(v);
return 2;
+ }
c[i] += y;

DEBG("huft4 ");
@@ -422,6 +431,7 @@ DEBG1("3 ");
{
if (h)
huft_free(u[0]);
+ free(v);
return 3; /* not enough memory */
}
DEBG1("4 ");
@@ -485,6 +495,7 @@ DEBG("h6f ");

DEBG("huft7 ");

+ free(v);
/* Return true (1) if we were given an incomplete table */
return y != 0 && g != 1;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/