Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Dec 2001 10:08:48 +0100
From:      Poul-Henning Kamp <phk@critter.freebsd.dk>
To:        Peter Wemm <peter@wemm.org>
Cc:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/lib/libc/stdlib malloc.c 
Message-ID:  <455.1008234528@critter.freebsd.dk>
In-Reply-To: Your message of "Wed, 12 Dec 2001 15:42:54 PST." <20011212234254.2BEA53810@overcee.netplex.com.au> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <20011212234254.2BEA53810@overcee.netplex.com.au>, Peter Wemm writes
:
>>   If zero bytes are allocated, return pointer to the middle of page-zero
>>   (which is protected) so that the program will crash if it dereferences
>>   this illgotten pointer.
>
>  ISO/IEC 9899:1999 7.20.3#1:
>  If the size of the space requested is zero, the behavior is implementation-
>  defined: either a null pointer is returned, or the behavior is as if the
>  size were some nonzero value, except that the returned pointer shall not
>  be used to access an object.

>  char *a, *b;
>  a = malloc(0);
>  b = malloc(0);
>  if (a && b && a == b)
>    abort ();
>
>shall not abort.

I know.

The reason for this change was Theo pushing it hard.  He claims that
some hole somewhere exists which exploits this, and consequently
others may exist as well.

I'm not in love with the !=NULL return for zero size, but last time
I tried to default to the 'V' malloc_option I got more coredumps
than I care to count.  Things could have improved.

>Now, you _can_ make the returned pointer point to a PROT_NONE page,
>but you still have to preserve identity of individual allocations.

This is basically what Theo did.

The problem as I see it is this: since people are deref'ing a pointer
they shouldn't, God knows what offset they use relative to the pointer
and consequently how wide a moat do I have to put around the pointer
I return ?

So I tried this "quick&dirty" check with the intent to hear how much
breakage would be reported before deciding on a future course of action.

My current preference is to switch FreeBSD to the NULL return, it makes
a lot more sense.

>The bug in binutils that tripped this up was that they were doing
>object->ptr = malloc(size);	// where size == 0
>....
>if (object->ptr)
>	free(object->ptr);
>
>Yes it was ``broken'' as such but is compatable with a compliant malloc().

Uhm, that code is OK for all I know...

>They've changed bfd_alloc(size) (the wrapper around all malloc() calls)
>to do this:
>  if (size == 0)
>    size = 1;
>.. which bypasses all these checks and any implementation defined behavior.

Yech!

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk@FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?455.1008234528>