Page MenuHomeFreeBSD

memcpy.3: remove BUGS section allowing overlapping strings
ClosedPublic

Authored by emaste on Jul 15 2021, 2:12 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Nov 6, 7:17 PM
Unknown Object (File)
Sun, Oct 27, 4:39 PM
Unknown Object (File)
Wed, Oct 16, 10:23 PM
Unknown Object (File)
Tue, Oct 15, 2:54 AM
Unknown Object (File)
Sep 26 2024, 11:04 AM
Unknown Object (File)
Sep 26 2024, 6:55 AM
Unknown Object (File)
Sep 25 2024, 4:38 PM
Unknown Object (File)
Sep 25 2024, 1:00 AM
Subscribers

Details

Summary

The removed text claimed that memcpy is implemented using bcopy and thus strings may overlap. That was not actually true (although the implementation may have behaved as if so).

In any case it is undefined behavior according to the C standard, and this man page already claimed that src and dst may not overlap. Just remove the extra text that permits overlapping.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

emaste created this revision.

I do not object, but we need to coordinate due to D31180

This revision is now accepted and ready to land.Jul 15 2021, 2:34 PM

Mentioning how it is implemented is definitely a manpage bug, but ultimately the implementation allows for overlapping strings and this can't be changed because userspace expects it. There is a famous glibc bugreport where memcpy was patched to no longer allow overlapping stores and that broke tons of stuff. This had to get worse since then.

I think a note that overlapping stores are supported due to overall breakage is prudent, but I don't know how to nicely word it.

one such bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=12518

glibc man page: http://manpages.ubuntu.com/manpages/xenial/man3/memcpy.3.html

Failure to observe the requirement that the memory areas  do  not  overlap  has  been  the
source of real bugs.  (POSIX and the C standards are explicit that employing memcpy() with
overlapping areas produces undefined behavior.)  Most notably, in glibc 2.13 a performance
optimization  of memcpy() on some platforms (including x86-64) included changing the order
in which bytes were copied from src to dest.

This change revealed breakages in a number of applications  that  performed  copying  with
overlapping  areas.   Under the previous implementation, the order in which the bytes were
copied had fortuitously hidden the bug, which was revealed  when  the  copying  order  was
reversed.   In  glibc 2.14, a versioned symbol was added so that old binaries (i.e., those
linked against glibc versions earlier than 2.14) employed a memcpy()  implementation  that
safely   handles   the   overlapping  buffers  case  (by  providing  an  "older"  memcpy()
implementation that was aliased to memmove(3)).