|
Message-ID: <20160112162243.GC13558@port70.net> Date: Tue, 12 Jan 2016 17:22:44 +0100 From: Szabolcs Nagy <nsz@...t70.net> To: musl@...ts.openwall.com Subject: Re: Possible infinite loop in qsort() * Alexander Cherepanov <ch3root@...nwall.com> [2016-01-12 17:31:31 +0300]: > On 2016-01-12 15:48, Szabolcs Nagy wrote: > >in musl things are documented in the git log for now, e.g.: > >http://git.musl-libc.org/cgit/musl/commit/?id=3cd6f5229f079f892411e82fce3fe15c78eef4d8 > > IMHO such things should be documented in user-facing documentation, not in > source code comments, git log or email posts. > yes, that would be a useful project > >i think if an implementation does not give this guarantee > >that should be considered a bug. > > Some consider it a bug, others -- a feature. > > But if you want to provide this guarantee it's not that easy. Compilers are > not under your control. Even with gcc (which tries to provide this > guarantee) you can create VLA 2.5GB in size and run it with `ulimit -s > unlimited` (at least as a 32-bit binary on a 64-bit host). > large vla sounds like a problem, the libc can guard against that by placing a guard page in the way on the main thread. but stack allocations are kind of outside the c language: stack limits are not admitted in the standard causing technical issues around correctness proofs. > Then, a user can create an object of any size via mmap with MAP_FIXED flag, > right? creating a single object by two mmaps that happen to be adjacent sounds like a grey area (not sure if that's strictly conforming in posix/c). the user can get a large object behind the libc (e.g. by using raw syscalls) but the portable ways are controlled by the libc. > >(glibc does not guarantee this and indeed it is full of invalid > >pointer arithmetics, > > Care to provide examples? > this is what i did: went to the glibc string directory looked for pointer - operations, there are already several in various argz_* functions so i didnt have to go further than the letter 'a' to find char *match = strstr (arg, str); ... size_t to_len = match - arg; in argz_replace, if arg is a large object and str only matches near the end, then match - arg is ub. i think the argz buffer is internally allocated by the libc so it could protect against large objects but i don't see such protection. the first obvious example i see is in memccpy void *p = memchr (src, c, n); ... return __mempcpy (dest, src, p - src + 1); again p - src can be ub. > >but more importantly a huge number of > >existing libraries depend on this) > > > >>BTW the support in compilers for working with objects larger than half the > >>address space is buggy -- see > >>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67999 . The same situation -- > >>it neither works nor documented. Somewhat puzzling... > > > >yes, but it's not possible to support reasonably > > Why is that? i guess it can be supported but you lose some useful transformations e.g. p < q can be transformed to p-q < 0 in the compiler if the diff cannot overflow i don't know how much this matters for optimization and how much harder it is to implement, but i do think there are easy mistakes to be made if p-q can overflow.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.