From: Stephen Warren <swarren@wwwdotorg.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] malloc: handle free() before gd is set
Date: Fri, 4 Mar 2016 10:38:05 -0700 [thread overview]
Message-ID: <56D9C7FD.2050806@wwwdotorg.org> (raw)
In-Reply-To: <56D94B43.3020505@redhat.com>
On 03/04/2016 01:45 AM, Hans de Goede wrote:
> Hi,
>
> On 04-03-16 09:19, Stephen Warren wrote:
>> On at least Ubuntu Xenial, free() can be called before main(). In this
>> case, U-Boot won't have set gd, so dereferencing it will crash. Check
>> whether gd is set before using it.
>>
>> While at it, apply the same fix to other functions.
>>
>> Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
>> ---
>> common/dlmalloc.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/common/dlmalloc.c b/common/dlmalloc.c
>> index 5ea37dfb6e4c..7453e63d6bf4 100644
>> --- a/common/dlmalloc.c
>> +++ b/common/dlmalloc.c
>> @@ -2453,7 +2453,7 @@ void fREe(mem) Void_t* mem;
>>
>> #ifdef CONFIG_SYS_MALLOC_F_LEN
>> /* free() is a no-op - all the memory will be freed on
>> relocation */
>> - if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
>> + if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
>> return;
>> #endif
>>
>
> I believe you want:
>
> + if (!gd || !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
>
> Instead, so that you actually go into the return; path when there is no gd.
Hmm. Is the existing logic at the start of malloc() (which I copied)
incorrect too then? Perhaps so...
#ifdef CONFIG_SYS_MALLOC_F_LEN
if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
return malloc_simple(bytes);
#endif
/* check if mem_malloc_init() was run */
if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
/* not initialized yet */
return NULL;
}
I guess that works because "if (gd && ..." prevents gd from being
dereferenced, but doesn't actually return, and then presumably
"(mem_malloc_start == 0) && (mem_malloc_end == 0)" is true at that
point, so the function returns NULL immediately anyway.
For free() after my change:
#ifdef CONFIG_SYS_MALLOC_F_LEN
/* free() is a no-op - all the memory will be freed on relocation */
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
return;
#endif
if (mem == NULL) /* free(0) has no effect */
return;
I guess that "mem == NULL" is always true, since malloc() always
returned NULL, so everything works out somewhat accidentally in a
similar way. Still, as you say it's probably better to be a bit more
direct and add an explicit guard in malloc on gd leaving it:
+ if (!gd)
+ return NULL;
#ifdef CONFIG_SYS_MALLOC_F_LEN
- if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
+ if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)
return malloc_simple(bytes);
#endif
and free:
+ if (!gd)
+ return;
Or perhaps actually using malloc_simple() if (!gd) is the better option,
since obviously something[1] is actually trying to allocate memory?
[1] IIRC something in the dynamic loader, but I forget the complete
backtrace right now.
next prev parent reply other threads:[~2016-03-04 17:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-04 8:19 [U-Boot] [PATCH] malloc: handle free() before gd is set Stephen Warren
2016-03-04 8:45 ` Hans de Goede
2016-03-04 17:38 ` Stephen Warren [this message]
2016-03-06 10:08 ` Hans de Goede
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=56D9C7FD.2050806@wwwdotorg.org \
--to=swarren@wwwdotorg.org \
--cc=u-boot@lists.denx.de \
/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.