Page MenuHomeFreeBSD

Remove some compatability with Seventh Edition UNIX realloc().
ClosedPublic

Authored by brooks on Aug 17 2019, 12:00 AM.
Tags
None
Referenced Files
Unknown Object (File)
Oct 10 2024, 9:57 AM
Unknown Object (File)
Oct 4 2024, 10:00 PM
Unknown Object (File)
Oct 2 2024, 10:11 PM
Unknown Object (File)
Oct 2 2024, 7:48 AM
Unknown Object (File)
Oct 2 2024, 4:57 AM
Unknown Object (File)
Sep 30 2024, 10:09 AM
Unknown Object (File)
Sep 26 2024, 8:18 PM
Unknown Object (File)
Sep 21 2024, 4:54 AM
Subscribers

Details

Summary

In Seventh Edition UNIX, the last pointer passed to free() was
guaranteed to not actually have been freed allowing memory to be
"compacted" via the following pattern:

free(foo);
foo = realloc(foo, newsize);

Further, Andrew Koenig reports in "C Traps and Pitfalls" that the
original realloc() implementation required this pattern.

The C standard is clear that this is Undefined Behavior. Modern
allocators don't support it and no portable code could rely on it so
remove this support.

Note: the removed implementation contains an off-by-one error and if
an item isn't found on the freelist, then twice as much memory as the
largest possible allocation will be copied.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

This is good, and good commit message. V7 was released 40 years ago this past January. It flourished in the late 70s and early 80s as a platform people ported to (I'm aware of maybe a dozen such ports too 4 or 5 different architectures)... then all those ports migrated to System III or System V by maybe 1989 or so. The last time I saw this software pattern was in the mid 90s when I updated the program in question to not do that.... I doubt this code path has been execute in the last decade or two except by pedants testing V7 compatibility.

This revision is now accepted and ready to land.Aug 17 2019, 1:59 AM
pstef added inline comments.
libexec/rtld-elf/rtld_malloc.c
318 ↗(On Diff #60921)

Is this comment (rtld_malloc.c:318) talking about the same compacting as you mentioned in the commit message?

libexec/rtld-elf/rtld_malloc.c
257 ↗(On Diff #60921)

This var should be removed ...

273 ↗(On Diff #60921)

... and this condition as well, executing the code under it unconditionally.

288 ↗(On Diff #60921)

Note that cp is already freed at this point. If you claim that __crt_realloc() does not support/does not rely on accessibility of the block freed just before, then this copy should be done before __crt_free(cp).

  • Always follow the allocated path, don't free prematurely.
This revision now requires review to proceed.Aug 19 2019, 10:13 AM
brooks edited the summary of this revision. (Show Details)

Please fix two style issues, no need to re-post the updated patch.

libexec/rtld-elf/rtld_malloc.c
264 ↗(On Diff #60989)

I would express this as

if (op->ov_magic != MAGIC)
   return (NULL);
i = op->ov_index;

I considered should we change the if (... != MAGIC) to assert, esp. because the only consumers of this malloc are rtld and libthr, but decided that we do not.

271 ↗(On Diff #60989)

if (i != 0) {

This revision is now accepted and ready to land.Aug 19 2019, 12:18 PM