On MacOS, several functions including memcpy
, memmove
, memset
, and others are implemented as such, making use of a mysterious __darwin_obsz0()
function:
#if __has_builtin(__builtin___memcpy_chk) || defined(__GNUC__)
#undef memcpy
#define memcpy(dest, src, len) \
__builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest))
#endif
#if __has_builtin(__builtin___memmove_chk) || defined(__GNUC__)
#undef memmove
#define memmove(dest, src, len) \
__builtin___memmove_chk (dest, src, len, __darwin_obsz0 (dest))
#endif
#if __has_builtin(__builtin___memset_chk) || defined(__GNUC__)
#undef memset
#define memset(dest, val, len) \
__builtin___memset_chk (dest, val, len, __darwin_obsz0 (dest))
#endif
Similarly, strcpy
makes use of a mysterious __darwin_obsz
function:
#if __has_builtin(__builtin___strcpy_chk) || defined(__GNUC__)
#undef strcpy
#define strcpy(dest, src) \
__builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
#endif
What are these (macros?) functions and what do they do? I could not find any documentation about them.
CodePudding user response:
Seems to me like they are simple macros that expand to compiler built-ins to calculate the size of an object at compile time. This file include/secure/_common.h
from Apple Open Source has their definition:
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)
__builtin_object_size
should be equivalent between Clang and GCC. The GCC documentation describes it in this page.
These sizes are passed as last argument to the *_chk()
alternative of common memory copying functions such as memcpy()
and strcpy()
, supposedly in an effort to make the code more secure, trying to avoid memory corruption in case the wrong size is passed by the user, since the destination object size is checked by those functions.