[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends |
Date: |
Mon, 07 Dec 2009 11:35:22 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) |
malc <address@hidden> writes:
> On Mon, 7 Dec 2009, Markus Armbruster wrote:
>
>> malc <address@hidden> writes:
>>
>> > On Sun, 6 Dec 2009, Markus Armbruster wrote:
>> >
>> >> malc <address@hidden> writes:
>> >>
>> >> > On Sun, 6 Dec 2009, Markus Armbruster wrote:
>> >> >
>> >> >> malc <address@hidden> writes:
>> >> >>
>> >> >
>> >> > [..snip..]
>> >> >
>> >> >>
>> >> >> read(fd, malloc(0), 0) is just fine, because read() doesn't touch the
>> >> >> buffer when the size is zero.
>> >> >>
>> >> >
>> >> > [..snip..]
>> >> >
>> >> > Yet under linux the address is checked even for zero case.
>> >>
>> >> Any value you can obtain from malloc() passes that check.
>> >>
>> >> Why does the fact that you can construct pointers that don't pass this
>> >> check matter for our discussion of malloc()?
>> >>
>> >> >> > I don't know what a "valid pointer" in this context represents.
>> >> >>
>> >> >> I can talk standardese, if you prefer :)
>> >> >>
>> >> >> malloc() either returns either a null pointer or a pointer to the
>> >> >> allocated space. In either case, you must not dereference the pointer.
>> >> >>
>> >> >> OpenBSD chooses to return a pointer to the allocated space. It chooses
>> >> >> to catch common ways to dereference the pointer.
>> >> >>
>> >> >> Your "p = (void *)-1" is neither a null pointer nor can it point to
>> >> >> allocated space on your particular system. Hence, it cannot be a value
>> >> >> of malloc() for any argument, and therefore what read() does with it on
>> >> >> that particular system doesn't matter.
>> >> >>
>> >> >
>> >> > Here, i believe, you are inventing artificial restrictions on how
>> >> > malloc behaves, i don't see anything that prevents the implementor
>> >> > from setting aside a range of addresses with 31st bit set as an
>> >> > indicator of "zero" allocations, and then happily giving it to the
>> >> > user of malloc and consumming it in free.
>> >>
>> >> Misunderstanding? Such behavior is indeed permissible, and I can't see
>> >> where I restricted it away. An implementation that behaves as you
>> >> describe returns "pointer to allocated space". That the pointer has
>> >> some funny bit set doesn't matter. That it can't be dereferenced is
>> >> just fine.
>> >>
>
> Here you agree that it's permissible.
We were talking about ISO C, so by "implementation" I meant an
implementation of ISO C, not an application program using it. Sorry if
I didn't make that sufficiently clear.
>> >> I'm not sure what your point is. If it is that malloc(0) can return a
>> >> value that cannot be passed to a zero-sized read(), then I fear you have
>> >> not made your point.
>> >
>> > One more attempt to make it clearer. If you agree that this behaviour
>> > is permissible then the game is lost as things stand now under Linux,
>> > since replacing [1]:
>> >
>> > void *p = (void *) -1
>> > with:
>> > void *p = (void *) 0x80000000
>> >
>> > or anything else with said bit set will yield EFAULT. Consequently the
>> > code you cited as a well behaving malloc(0) call site will bomb.
>> >
>> > [1] Under 32bit Linux that is, with the usual split.
>>
>> You can't just pull pointers out of your ear and expect stuff to work.
>
> And here you don't. Which renders whole discussion rather pointless.
And here we're talking about making up pointers in a portable
application program. Which QEMU is.
> Which renders whole discussion rather pointless.
It's only tangentially related to the question whether qemu_malloc()
should accept zero arguments anyway.
>> malloc() is free to return a pointer to allocated space that is set up
>> in a way that catches access beyond the allocated size. OpenBSD does
>> that for size zero; it allocates one byte then, from pages that are used
>> only for zero-sized allocations, and takes care to disable access to
>> these pages with mprotect(..., PROT_NONE)[*]. Since read(..., 0) does
>> not access beyond the allocated size, it still works just fine.
>>
>> If you replace glibc's malloc() to get OpenBSD-like behavior, you can't
>> just make up some pointer to a memory area you believe to be unused, you
>> have to do it right, like OpenBSD does.
>>
>>
>> [*] Check out omalloc_make_chunks() at
>> http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/malloc.c?rev=1.121;content-type=text%2Fplain
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, (continued)
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, Markus Armbruster, 2009/12/06
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, malc, 2009/12/06
- [Qemu-devel] Re: [PATCH] Permit zero-sized qemu_malloc() & friends, Paolo Bonzini, 2009/12/06
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, Kevin Wolf, 2009/12/07
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, Markus Armbruster, 2009/12/07
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, malc, 2009/12/07
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, Kevin Wolf, 2009/12/07
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends,
Markus Armbruster <=
- [Qemu-devel] Re: [PATCH] Permit zero-sized qemu_malloc() & friends, Paolo Bonzini, 2009/12/06
- Re: [Qemu-devel] Re: [PATCH] Permit zero-sized qemu_malloc() & friends, malc, 2009/12/06
- [Qemu-devel] Re: [PATCH] Permit zero-sized qemu_malloc() & friends, Paolo Bonzini, 2009/12/06
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, Blue Swirl, 2009/12/06
- Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, malc, 2009/12/06
Re: [Qemu-devel] [PATCH] Permit zero-sized qemu_malloc() & friends, Avi Kivity, 2009/12/05