malc <av1...@comtv.ru> writes: > On Mon, 7 Dec 2009, Markus Armbruster wrote: > >> malc <av1...@comtv.ru> writes: >> >> > On Sun, 6 Dec 2009, Markus Armbruster wrote: >> > >> >> malc <av1...@comtv.ru> writes: >> >> >> >> > On Sun, 6 Dec 2009, Markus Armbruster wrote: >> >> > >> >> >> malc <av1...@comtv.ru> 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