Glibc change exposing bugs
Glibc change exposing bugs
Posted Oct 21, 2013 20:37 UTC (Mon) by nix (subscriber, #2304)In reply to: Glibc change exposing bugs by jzbiciak
Parent article: Glibc change exposing bugs
Your comment was interesting anyway. This is the relevant guarantee from C89 (C99 and C11 have similar wording):
If two pointers to object or incomplete types compare equal, they point to the same object. If two pointers to functions compare equal, they point to the same function. If two pointers point to the same object or function, they compare equal. If one of the operands is a pointer to an object or incomplete type and the other has type pointer to a qualified or unqualified version of void , the pointer to an object or incomplete type is converted to the type of the other operand.The problem here is that this does not guarantee that two pointers to the same object always compare equal, but rather that if they compare equal, they are pointers to the same object (and similarly for comparison operators). We can tell if two pointers definitely are pointers within the same object, but if the comparison fails we cannot conclude anything. This is unfortunately the opposite of the guarantee that memmove() needs if it is to transform itself into a memmove() when needed, so (in the absence of a Standard-blessed way to normalize pointers) you are indeed forced to do a double-copy at all times when writing memmove() in Standard C.
Posted Oct 21, 2013 20:49 UTC (Mon)
by khim (subscriber, #9252)
[Link] (4 responses)
Note that in real world there are no such guarantee (hint, hint) thus GLibC's memmove sometimes works and sometimes does not work.
Posted Oct 23, 2013 14:23 UTC (Wed)
by nix (subscriber, #2304)
[Link] (3 responses)
This behaviour is explicitly permitted by the Standard: segmented architectures like MS-DOS were like this decades ago. The guarantee that a == b returns nonzero only when a and b are pointers to the same object holds nonetheless. It's just a less useful guarantee than we might like.
Posted Oct 23, 2013 15:47 UTC (Wed)
by khim (subscriber, #9252)
[Link] (2 responses)
My point was that real-world GLibC-implemented memmove does not actually work when used on POSIX system. It compares pointers and assumes that if they are different then underlying memory is also different! Which means, strictly speaking, that memmove in GLibC is not standards-compliant :-)
Posted Oct 23, 2013 16:47 UTC (Wed)
by jzbiciak (guest, #5246)
[Link]
Posted Oct 23, 2013 18:09 UTC (Wed)
by nix (subscriber, #2304)
[Link]
... bloody hell, it does. Or many of the assembler versions do anyway. Or, rather, it assumes that distinct addresses cannot alias.
I suppose this is probably safe in practice, because if you *do* use mmap() to set up aliased regions at distinct addresses you are suddenly in hardware-dependent land (due to machines with VIPT caches such as, IIRC, MIPS, not being able to detect such aliasing at the caching level, so you suddenly need to introduce -- necessarily hardware-dependent -- cache flushes and memory barriers) so you have to know what you're doing anyway, and little things like memmove() falling back to memcpy() at unexpected times are things you're supposed to know about.
I hope.
Glibc change exposing bugs
This is unfortunately the opposite of the guarantee that memmove() needs if it is to transform itself into a memmove() when needed, so (in the absence of a Standard-blessed way to normalize pointers) you are indeed forced to do a double-copy at all times when writing memmove() in Standard C.
Glibc change exposing bugs
Glibc change exposing bugs
Glibc change exposing bugs
Glibc change exposing bugs