llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp

//===-- sanitizer_platform_limits_posix.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of Sanitizer common code.
//
// Sizes and layouts of platform-specific POSIX data structures.
//===----------------------------------------------------------------------===//

#if defined(__linux__) || defined(__APPLE__)
// Tests in this file assume that off_t-dependent data structures match the
// libc ABI. For example, struct dirent here is what readdir() function (as
// exported from libc) returns, and not the user-facing "dirent", which
// depends on _FILE_OFFSET_BITS setting.
// To get this "true" dirent definition, we undefine _FILE_OFFSET_BITS below.
#undef _FILE_OFFSET_BITS
#undef _TIME_BITS
#endif

// Must go after undef _FILE_OFFSET_BITS.
#include "sanitizer_platform.h"

#if SANITIZER_LINUX || SANITIZER_APPLE
// Must go after undef _FILE_OFFSET_BITS.
#include "sanitizer_glibc_version.h"

#include <arpa/inet.h>
#include <dirent.h>
#include <grp.h>
#include <limits.h>
#include <net/if.h>
#include <netdb.h>
#include <poll.h>
#include <pthread.h>
#include <pwd.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <termios.h>
#include <time.h>
#include <wchar.h>
#include <regex.h>
#if !SANITIZER_APPLE
#include <utmp.h>
#endif

#if !SANITIZER_IOS
#include <net/route.h>
#endif

#if !SANITIZER_ANDROID
#include <sys/mount.h>
#include <sys/timeb.h>
#include <utmpx.h>
#endif

#if SANITIZER_LINUX
#include <malloc.h>
#include <mntent.h>
#include <netinet/ether.h>
#include <sys/sysinfo.h>
#include <sys/vt.h>
#include <linux/cdrom.h>
#include <linux/fd.h>
#if SANITIZER_ANDROID
#include <linux/fs.h>
#endif
#include <linux/hdreg.h>
#include <linux/input.h>
#include <linux/ioctl.h>
#include <linux/soundcard.h>
#include <linux/sysctl.h>
#include <linux/utsname.h>
#include <linux/posix_types.h>
#include <net/if_arp.h>
#endif

#if SANITIZER_IOS
#undef IOC_DIRMASK
#endif

#if SANITIZER_LINUX
# include <utime.h>
# include <sys/ptrace.h>
#    if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
        defined(__hexagon__) || defined(__loongarch__) ||SANITIZER_RISCV64
#      include <asm/ptrace.h>
#      ifdef __arm__
typedef struct user_fpregs elf_fpregset_t;
#define ARM_VFPREGS_SIZE_ASAN
#   if !defined(ARM_VFPREGS_SIZE)
#define ARM_VFPREGS_SIZE
#   endif
#  endif
# endif
# include <semaphore.h>
#endif

#if !SANITIZER_ANDROID
#include <ifaddrs.h>
#include <sys/ucontext.h>
#include <wordexp.h>
#endif

#if SANITIZER_LINUX
#if SANITIZER_GLIBC
#include <fstab.h>
#include <net/if_ppp.h>
#include <netax25/ax25.h>
#include <netipx/ipx.h>
#include <netrom/netrom.h>
#include <obstack.h>
#if HAVE_RPC_XDR_H
# include <rpc/xdr.h>
#endif
#include <scsi/scsi.h>
#else
#include <linux/if_ppp.h>
#include <linux/kd.h>
#include <linux/ppp_defs.h>
#endif  // SANITIZER_GLIBC

#if SANITIZER_ANDROID
#include <linux/mtio.h>
#else
#include <glob.h>
#include <mqueue.h>
#include <sys/kd.h>
#include <sys/mtio.h>
#include <sys/shm.h>
#include <sys/statvfs.h>
#include <sys/timex.h>
#if defined(__mips64)
# include <sys/procfs.h>
#endif
#include <sys/user.h>
#include <linux/if_eql.h>
#include <linux/if_plip.h>
#include <linux/lp.h>
#include <linux/mroute.h>
#include <linux/mroute6.h>
#include <linux/scc.h>
#include <linux/serial.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#endif  // SANITIZER_ANDROID

#include <link.h>
#include <sys/vfs.h>
#include <sys/epoll.h>
#include <linux/capability.h>
#else
#include <fstab.h>
#endif // SANITIZER_LINUX

#if SANITIZER_APPLE
#include <net/ethernet.h>
#include <sys/filio.h>
#include <sys/sockio.h>
#endif

// Include these after system headers to avoid name clashes and ambiguities.
#  include "sanitizer_common.h"
#  include "sanitizer_internal_defs.h"
#  include "sanitizer_platform_interceptors.h"
#  include "sanitizer_platform_limits_posix.h"

__sanitizer // namespace __sanitizer

usingnamespace__sanitizer;

COMPILER_CHECK();

COMPILER_CHECK();
CHECK_TYPE_SIZE();

#if SANITIZER_LINUX
// FIXME: We define those on Linux and Mac, but only check on Linux.
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
COMPILER_CHECK();
#endif // SANITIZER_LINUX

#if SANITIZER_LINUX || SANITIZER_FREEBSD
// There are more undocumented fields in dl_phdr_info that we are not interested
// in.
COMPILER_CHECK();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD

#if SANITIZER_GLIBC || SANITIZER_FREEBSD
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif  // SANITIZER_GLIBC || SANITIZER_FREEBSD

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

// In POSIX, int msg_iovlen; socklen_t msg_controllen; socklen_t cmsg_len; but
// many implementations don't conform to the standard. Since we pick the
// non-conforming glibc definition, exclude the checks for musl (incompatible
// sizes but compatible offsets).
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#if SANITIZER_GLIBC || SANITIZER_ANDROID
CHECK_SIZE_AND_OFFSET();
#endif
CHECK_SIZE_AND_OFFSET();
#if SANITIZER_GLIBC || SANITIZER_ANDROID
CHECK_SIZE_AND_OFFSET();
#endif
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();
#if SANITIZER_GLIBC || SANITIZER_ANDROID
CHECK_SIZE_AND_OFFSET();
#endif
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

#if SANITIZER_LINUX && (__ANDROID_API__ >= 21 || __GLIBC_PREREQ (2, 14))
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

COMPILER_CHECK();
CHECK_SIZE_AND_OFFSET();
#if SANITIZER_APPLE
CHECK_SIZE_AND_OFFSET(dirent, d_seekoff);
#elif SANITIZER_FREEBSD
// There is no 'd_off' field on FreeBSD.
#else
CHECK_SIZE_AND_OFFSET();
#endif
CHECK_SIZE_AND_OFFSET();

#if SANITIZER_GLIBC
COMPILER_CHECK();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();

CHECK_TYPE_SIZE();

COMPILER_CHECK();
// Can't write checks for sa_handler and sa_sigaction due to them being
// preprocessor macros.
CHECK_STRUCT_SIZE_AND_OFFSET();
#if !defined(__s390x__) || __GLIBC_PREREQ (2, 20)
// On s390x glibc 2.19 and earlier sa_flags was unsigned long, and sa_resv
// didn't exist.
CHECK_STRUCT_SIZE_AND_OFFSET();
#endif
#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32)
CHECK_STRUCT_SIZE_AND_OFFSET();
#endif

#if SANITIZER_HAS_SIGINFO
COMPILER_CHECK();
__sanitizer_siginfo_t;
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

#if SANITIZER_LINUX
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();
CHECK_TYPE_SIZE();

#if SANITIZER_USES_UID16_SYSCALLS
CHECK_TYPE_SIZE(__kernel_old_uid_t);
CHECK_TYPE_SIZE(__kernel_old_gid_t);
#endif

CHECK_TYPE_SIZE();
CHECK_TYPE_SIZE();
CHECK_TYPE_SIZE();
#endif

#if !SANITIZER_ANDROID
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

#if SANITIZER_LINUX
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

CHECK_TYPE_SIZE();

#if SANITIZER_GLIBC || SANITIZER_FREEBSD
CHECK_TYPE_SIZE();
# if SANITIZER_FREEBSD
CHECK_SIZE_AND_OFFSET(ipc_perm, key);
CHECK_SIZE_AND_OFFSET(ipc_perm, seq);
# else
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
# endif
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#if !SANITIZER_LINUX || __GLIBC_PREREQ (2, 31)
/* glibc 2.30 and earlier provided 16-bit mode field instead of 32-bit
   on many architectures.  */
CHECK_SIZE_AND_OFFSET();
#endif

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

CHECK_TYPE_SIZE();

#if SANITIZER_LINUX
CHECK_TYPE_SIZE();
#endif

#if !SANITIZER_ANDROID
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#if SANITIZER_LINUX || SANITIZER_FREEBSD
// Compare against the union, because we can't reach into the union in a
// compliant way.
#ifdef ifa_dstaddr
#undef ifa_dstaddr
#endif
# if SANITIZER_FREEBSD
CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
# else
COMPILER_CHECK();
COMPILER_CHECK();
# endif // SANITIZER_FREEBSD
#else
CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
#endif // SANITIZER_LINUX
CHECK_SIZE_AND_OFFSET();
#endif

#if SANITIZER_GLIBC || SANITIZER_ANDROID
COMPILER_CHECK();
#endif

#if !SANITIZER_ANDROID
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

#if !SANITIZER_ANDROID
CHECK_SIZE_AND_OFFSET();
#endif

#if SANITIZER_APPLE
CHECK_SIZE_AND_OFFSET(passwd, pw_change);
CHECK_SIZE_AND_OFFSET(passwd, pw_expire);
CHECK_SIZE_AND_OFFSET(passwd, pw_class);
#endif


CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

#if HAVE_RPC_XDR_H && !SANITIZER_APPLE
CHECK_TYPE_SIZE(XDR);
CHECK_SIZE_AND_OFFSET(XDR, x_op);
CHECK_SIZE_AND_OFFSET(XDR, x_ops);
CHECK_SIZE_AND_OFFSET(XDR, x_public);
CHECK_SIZE_AND_OFFSET(XDR, x_private);
CHECK_SIZE_AND_OFFSET(XDR, x_base);
CHECK_SIZE_AND_OFFSET(XDR, x_handy);
COMPILER_CHECK(__sanitizer_XDR_ENCODE == XDR_ENCODE);
COMPILER_CHECK(__sanitizer_XDR_DECODE == XDR_DECODE);
COMPILER_CHECK(__sanitizer_XDR_FREE == XDR_FREE);
#endif

#if SANITIZER_GLIBC
COMPILER_CHECK();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

COMPILER_CHECK();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();

CHECK_TYPE_SIZE();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
CHECK_SIZE_AND_OFFSET();
#endif  // SANITIZER_GLIBC

#if SANITIZER_LINUX || SANITIZER_FREEBSD
CHECK_TYPE_SIZE();
#endif

#if SANITIZER_LINUX && defined(__arm__)
COMPILER_CHECK(ARM_VFPREGS_SIZE == ARM_VFPREGS_SIZE_ASAN);
#endif

#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_APPLE