2013-02-19 17:19:16 +08:00
|
|
|
//===-- sanitizer_platform_limits_posix.cc --------------------------------===//
|
2012-12-11 20:27:27 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2013-02-19 17:19:16 +08:00
|
|
|
// This file is a part of Sanitizer common code.
|
2012-12-11 20:27:27 +08:00
|
|
|
//
|
|
|
|
// Sizes and layouts of platform-specific POSIX data structures.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-03-19 22:33:38 +08:00
|
|
|
|
|
|
|
#include "sanitizer_platform.h"
|
|
|
|
#if SANITIZER_LINUX || SANITIZER_MAC
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-02-19 17:19:16 +08:00
|
|
|
#include "sanitizer_internal_defs.h"
|
|
|
|
#include "sanitizer_platform_limits_posix.h"
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-04-23 22:05:15 +08:00
|
|
|
#include <arpa/inet.h>
|
2013-02-19 17:19:16 +08:00
|
|
|
#include <dirent.h>
|
2013-04-23 20:01:20 +08:00
|
|
|
#include <grp.h>
|
2013-07-09 17:53:37 +08:00
|
|
|
#include <limits.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_arp.h>
|
|
|
|
#include <net/route.h>
|
|
|
|
#include <netdb.h>
|
2013-08-12 21:19:53 +08:00
|
|
|
#include <poll.h>
|
2013-03-13 17:01:40 +08:00
|
|
|
#include <pthread.h>
|
2013-04-01 22:47:21 +08:00
|
|
|
#include <pwd.h>
|
|
|
|
#include <signal.h>
|
2013-05-17 21:30:48 +08:00
|
|
|
#include <stddef.h>
|
2012-12-11 20:27:27 +08:00
|
|
|
#include <sys/resource.h>
|
2013-02-19 17:19:16 +08:00
|
|
|
#include <sys/socket.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#include <termios.h>
|
2013-02-19 17:19:16 +08:00
|
|
|
#include <time.h>
|
2013-07-10 22:17:46 +08:00
|
|
|
#include <wchar.h>
|
2013-02-19 17:19:16 +08:00
|
|
|
|
2013-06-07 21:00:47 +08:00
|
|
|
#if SANITIZER_LINUX
|
2013-06-28 19:02:43 +08:00
|
|
|
#include <sys/ptrace.h>
|
2013-06-24 22:25:33 +08:00
|
|
|
#include <sys/sysinfo.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#endif
|
|
|
|
|
2013-04-04 17:21:48 +08:00
|
|
|
#if !SANITIZER_ANDROID
|
|
|
|
#include <sys/ucontext.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
2013-07-02 22:08:52 +08:00
|
|
|
#include <glob.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#include <sys/mtio.h>
|
|
|
|
#include <sys/kd.h>
|
2013-06-28 22:18:10 +08:00
|
|
|
#include <sys/user.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
|
|
|
|
|
2013-03-19 22:33:38 +08:00
|
|
|
#if SANITIZER_LINUX
|
2013-05-17 20:51:13 +08:00
|
|
|
#include <link.h>
|
2012-12-11 20:27:27 +08:00
|
|
|
#include <sys/vfs.h>
|
|
|
|
#include <sys/epoll.h>
|
2013-04-03 15:24:35 +08:00
|
|
|
#endif // SANITIZER_LINUX
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-06-07 21:00:47 +08:00
|
|
|
#if SANITIZER_MAC
|
|
|
|
#include <netinet/ip_mroute.h>
|
2013-06-18 17:22:24 +08:00
|
|
|
#include <sys/filio.h>
|
|
|
|
#include <sys/sockio.h>
|
2013-06-07 21:00:47 +08:00
|
|
|
#endif
|
|
|
|
|
2013-02-19 17:19:16 +08:00
|
|
|
namespace __sanitizer {
|
2012-12-11 20:27:27 +08:00
|
|
|
unsigned struct_utsname_sz = sizeof(struct utsname);
|
|
|
|
unsigned struct_stat_sz = sizeof(struct stat);
|
|
|
|
unsigned struct_stat64_sz = sizeof(struct stat64);
|
2013-02-19 17:19:16 +08:00
|
|
|
unsigned struct_rusage_sz = sizeof(struct rusage);
|
|
|
|
unsigned struct_tm_sz = sizeof(struct tm);
|
2013-04-01 22:47:21 +08:00
|
|
|
unsigned struct_passwd_sz = sizeof(struct passwd);
|
2013-04-23 20:01:20 +08:00
|
|
|
unsigned struct_group_sz = sizeof(struct group);
|
2013-04-09 22:34:59 +08:00
|
|
|
unsigned siginfo_t_sz = sizeof(siginfo_t);
|
2013-04-01 22:47:21 +08:00
|
|
|
unsigned struct_sigaction_sz = sizeof(struct sigaction);
|
|
|
|
unsigned struct_itimerval_sz = sizeof(struct itimerval);
|
|
|
|
unsigned pthread_t_sz = sizeof(pthread_t);
|
2013-06-07 21:00:47 +08:00
|
|
|
unsigned pid_t_sz = sizeof(pid_t);
|
|
|
|
unsigned timeval_sz = sizeof(timeval);
|
|
|
|
unsigned uid_t_sz = sizeof(uid_t);
|
2013-07-10 22:17:46 +08:00
|
|
|
unsigned mbstate_t_sz = sizeof(mbstate_t);
|
2013-08-12 21:19:53 +08:00
|
|
|
unsigned sigset_t_sz = sizeof(sigset_t);
|
2013-04-04 17:21:48 +08:00
|
|
|
|
|
|
|
#if !SANITIZER_ANDROID
|
2013-04-04 17:03:56 +08:00
|
|
|
unsigned ucontext_t_sz = sizeof(ucontext_t);
|
2013-04-04 17:21:48 +08:00
|
|
|
#endif // !SANITIZER_ANDROID
|
2013-02-19 17:19:16 +08:00
|
|
|
|
2013-03-19 22:33:38 +08:00
|
|
|
#if SANITIZER_LINUX
|
2012-12-11 20:27:27 +08:00
|
|
|
unsigned struct_rlimit_sz = sizeof(struct rlimit);
|
|
|
|
unsigned struct_statfs_sz = sizeof(struct statfs);
|
|
|
|
unsigned struct_epoll_event_sz = sizeof(struct epoll_event);
|
2013-06-24 22:25:33 +08:00
|
|
|
unsigned struct_sysinfo_sz = sizeof(struct sysinfo);
|
2013-04-01 22:47:21 +08:00
|
|
|
unsigned struct_timespec_sz = sizeof(struct timespec);
|
2013-04-03 15:24:35 +08:00
|
|
|
#endif // SANITIZER_LINUX
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-03-19 22:33:38 +08:00
|
|
|
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
2013-02-19 19:06:41 +08:00
|
|
|
unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
|
|
|
|
unsigned struct_statfs64_sz = sizeof(struct statfs64);
|
2013-04-03 15:24:35 +08:00
|
|
|
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
|
2013-02-19 19:06:41 +08:00
|
|
|
|
2013-04-04 16:22:52 +08:00
|
|
|
uptr sig_ign = (uptr)SIG_IGN;
|
|
|
|
uptr sig_dfl = (uptr)SIG_DFL;
|
|
|
|
|
|
|
|
uptr __sanitizer_get_sigaction_sa_sigaction(void *act) {
|
|
|
|
struct sigaction *a = (struct sigaction *)act;
|
|
|
|
// Check that sa_sigaction and sa_handler are the same.
|
|
|
|
CHECK((void *)&(a->sa_sigaction) == (void *)&(a->sa_handler));
|
|
|
|
return (uptr) a->sa_sigaction;
|
|
|
|
}
|
|
|
|
void __sanitizer_set_sigaction_sa_sigaction(void *act, uptr cb) {
|
|
|
|
struct sigaction *a = (struct sigaction *)act;
|
|
|
|
a->sa_sigaction = (void (*)(int, siginfo_t *, void *))cb;
|
|
|
|
}
|
|
|
|
bool __sanitizer_get_sigaction_sa_siginfo(void *act) {
|
|
|
|
struct sigaction *a = (struct sigaction *)act;
|
|
|
|
return a->sa_flags & SA_SIGINFO;
|
|
|
|
}
|
2013-04-23 22:05:15 +08:00
|
|
|
|
2013-06-24 21:56:14 +08:00
|
|
|
int af_inet = (int)AF_INET;
|
|
|
|
int af_inet6 = (int)AF_INET6;
|
|
|
|
|
2013-04-23 22:05:15 +08:00
|
|
|
uptr __sanitizer_in_addr_sz(int af) {
|
|
|
|
if (af == AF_INET)
|
|
|
|
return sizeof(struct in_addr);
|
|
|
|
else if (af == AF_INET6)
|
|
|
|
return sizeof(struct in6_addr);
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
2013-06-07 21:00:47 +08:00
|
|
|
|
2013-07-02 22:08:52 +08:00
|
|
|
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
|
|
|
int glob_nomatch = GLOB_NOMATCH;
|
2013-07-09 20:07:59 +08:00
|
|
|
int glob_altdirfunc = GLOB_ALTDIRFUNC;
|
2013-07-02 22:08:52 +08:00
|
|
|
#endif
|
|
|
|
|
2013-07-05 16:57:47 +08:00
|
|
|
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
|
2013-07-16 00:11:39 +08:00
|
|
|
(defined(__i386) || defined (__x86_64)) // NOLINT
|
2013-06-28 19:02:43 +08:00
|
|
|
unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct);
|
|
|
|
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);
|
|
|
|
#if __WORDSIZE == 64
|
|
|
|
unsigned struct_user_fpxregs_struct_sz = 0;
|
|
|
|
#else
|
|
|
|
unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
|
|
|
|
#endif
|
2013-07-16 00:11:39 +08:00
|
|
|
|
2013-06-28 19:02:43 +08:00
|
|
|
int ptrace_getregs = PTRACE_GETREGS;
|
|
|
|
int ptrace_setregs = PTRACE_SETREGS;
|
|
|
|
int ptrace_getfpregs = PTRACE_GETFPREGS;
|
|
|
|
int ptrace_setfpregs = PTRACE_SETFPREGS;
|
|
|
|
int ptrace_getfpxregs = PTRACE_GETFPXREGS;
|
|
|
|
int ptrace_setfpxregs = PTRACE_SETFPXREGS;
|
|
|
|
int ptrace_getsiginfo = PTRACE_GETSIGINFO;
|
|
|
|
int ptrace_setsiginfo = PTRACE_SETSIGINFO;
|
2013-07-01 17:10:34 +08:00
|
|
|
#if defined(PTRACE_GETREGSET) && defined(PTRACE_SETREGSET)
|
2013-06-28 19:02:43 +08:00
|
|
|
int ptrace_getregset = PTRACE_GETREGSET;
|
|
|
|
int ptrace_setregset = PTRACE_SETREGSET;
|
2013-07-01 17:10:34 +08:00
|
|
|
#else
|
|
|
|
int ptrace_getregset = -1;
|
|
|
|
int ptrace_setregset = -1;
|
|
|
|
#endif
|
2013-06-28 19:02:43 +08:00
|
|
|
#endif
|
|
|
|
|
2013-07-09 17:53:37 +08:00
|
|
|
unsigned path_max = PATH_MAX;
|
|
|
|
|
2013-06-07 21:00:47 +08:00
|
|
|
// ioctl arguments
|
|
|
|
unsigned struct_arpreq_sz = sizeof(struct arpreq);
|
|
|
|
unsigned struct_ifreq_sz = sizeof(struct ifreq);
|
|
|
|
unsigned struct_termios_sz = sizeof(struct termios);
|
|
|
|
unsigned struct_winsize_sz = sizeof(struct winsize);
|
|
|
|
|
2013-08-14 21:34:14 +08:00
|
|
|
#if SANITIZER_MAC
|
2013-06-07 21:00:47 +08:00
|
|
|
unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
|
|
|
|
unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
|
|
|
|
#endif
|
2013-06-18 17:22:24 +08:00
|
|
|
|
2013-06-21 18:54:57 +08:00
|
|
|
unsigned IOCTL_NOT_PRESENT = 0;
|
|
|
|
|
2013-06-18 17:22:24 +08:00
|
|
|
unsigned IOCTL_FIOASYNC = FIOASYNC;
|
|
|
|
unsigned IOCTL_FIOCLEX = FIOCLEX;
|
|
|
|
unsigned IOCTL_FIOGETOWN = FIOGETOWN;
|
|
|
|
unsigned IOCTL_FIONBIO = FIONBIO;
|
|
|
|
unsigned IOCTL_FIONCLEX = FIONCLEX;
|
|
|
|
unsigned IOCTL_FIOSETOWN = FIOSETOWN;
|
|
|
|
unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI;
|
|
|
|
unsigned IOCTL_SIOCATMARK = SIOCATMARK;
|
|
|
|
unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI;
|
|
|
|
unsigned IOCTL_SIOCGIFADDR = SIOCGIFADDR;
|
|
|
|
unsigned IOCTL_SIOCGIFBRDADDR = SIOCGIFBRDADDR;
|
|
|
|
unsigned IOCTL_SIOCGIFCONF = SIOCGIFCONF;
|
|
|
|
unsigned IOCTL_SIOCGIFDSTADDR = SIOCGIFDSTADDR;
|
|
|
|
unsigned IOCTL_SIOCGIFFLAGS = SIOCGIFFLAGS;
|
|
|
|
unsigned IOCTL_SIOCGIFMETRIC = SIOCGIFMETRIC;
|
|
|
|
unsigned IOCTL_SIOCGIFMTU = SIOCGIFMTU;
|
|
|
|
unsigned IOCTL_SIOCGIFNETMASK = SIOCGIFNETMASK;
|
|
|
|
unsigned IOCTL_SIOCGPGRP = SIOCGPGRP;
|
|
|
|
unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR;
|
|
|
|
unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR;
|
|
|
|
unsigned IOCTL_SIOCSIFDSTADDR = SIOCSIFDSTADDR;
|
|
|
|
unsigned IOCTL_SIOCSIFFLAGS = SIOCSIFFLAGS;
|
|
|
|
unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC;
|
|
|
|
unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;
|
|
|
|
unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;
|
|
|
|
unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
|
|
|
|
unsigned IOCTL_TIOCCONS = TIOCCONS;
|
|
|
|
unsigned IOCTL_TIOCEXCL = TIOCEXCL;
|
|
|
|
unsigned IOCTL_TIOCGETD = TIOCGETD;
|
|
|
|
unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;
|
|
|
|
unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ;
|
|
|
|
unsigned IOCTL_TIOCMBIC = TIOCMBIC;
|
|
|
|
unsigned IOCTL_TIOCMBIS = TIOCMBIS;
|
|
|
|
unsigned IOCTL_TIOCMGET = TIOCMGET;
|
|
|
|
unsigned IOCTL_TIOCMSET = TIOCMSET;
|
|
|
|
unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;
|
|
|
|
unsigned IOCTL_TIOCNXCL = TIOCNXCL;
|
|
|
|
unsigned IOCTL_TIOCOUTQ = TIOCOUTQ;
|
|
|
|
unsigned IOCTL_TIOCPKT = TIOCPKT;
|
|
|
|
unsigned IOCTL_TIOCSCTTY = TIOCSCTTY;
|
|
|
|
unsigned IOCTL_TIOCSETD = TIOCSETD;
|
|
|
|
unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
|
|
|
|
unsigned IOCTL_TIOCSTI = TIOCSTI;
|
|
|
|
unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
|
2013-08-14 21:34:14 +08:00
|
|
|
#if SANITIZER_MAC
|
2013-06-18 17:22:24 +08:00
|
|
|
unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT;
|
|
|
|
unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT;
|
|
|
|
#endif
|
2013-08-14 21:34:14 +08:00
|
|
|
|
|
|
|
|
2013-02-19 17:19:16 +08:00
|
|
|
} // namespace __sanitizer
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-05-31 18:46:51 +08:00
|
|
|
#define CHECK_TYPE_SIZE(TYPE) \
|
|
|
|
COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))
|
|
|
|
|
|
|
|
#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \
|
|
|
|
COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *) NULL)->MEMBER) == \
|
|
|
|
sizeof(((CLASS *) NULL)->MEMBER)); \
|
|
|
|
COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \
|
|
|
|
offsetof(CLASS, MEMBER))
|
|
|
|
|
2013-03-13 17:01:40 +08:00
|
|
|
COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
|
2013-04-04 16:22:52 +08:00
|
|
|
COMPILER_CHECK(sizeof(__sanitizer::struct_sigaction_max_sz) >=
|
|
|
|
sizeof(__sanitizer::struct_sigaction_sz));
|
2013-05-17 20:51:13 +08:00
|
|
|
|
2013-05-29 19:30:00 +08:00
|
|
|
COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));
|
2013-07-05 20:31:07 +08:00
|
|
|
CHECK_TYPE_SIZE(pthread_key_t);
|
2013-05-29 19:30:00 +08:00
|
|
|
|
2013-05-31 18:46:51 +08:00
|
|
|
#if SANITIZER_LINUX
|
|
|
|
// There are more undocumented fields in dl_phdr_info that we are not interested
|
|
|
|
// in.
|
|
|
|
COMPILER_CHECK(sizeof(__sanitizer_dl_phdr_info) <= sizeof(dl_phdr_info));
|
|
|
|
CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr);
|
|
|
|
CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name);
|
|
|
|
CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);
|
|
|
|
CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);
|
2013-06-20 17:19:28 +08:00
|
|
|
|
|
|
|
COMPILER_CHECK(IOC_SIZE(0x12345678) == _IOC_SIZE(0x12345678));
|
2013-07-02 22:51:31 +08:00
|
|
|
#endif
|
2013-07-02 22:08:52 +08:00
|
|
|
|
2013-07-02 22:51:31 +08:00
|
|
|
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
2013-07-09 20:07:59 +08:00
|
|
|
CHECK_TYPE_SIZE(glob_t);
|
2013-07-02 22:08:52 +08:00
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
|
2013-07-09 20:07:59 +08:00
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_offs);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_flags);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat);
|
|
|
|
CHECK_SIZE_AND_OFFSET(glob_t, gl_stat);
|
2013-05-31 18:46:51 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
CHECK_TYPE_SIZE(addrinfo);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_family);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname);
|
|
|
|
CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr);
|
|
|
|
|
|
|
|
CHECK_TYPE_SIZE(hostent);
|
|
|
|
CHECK_SIZE_AND_OFFSET(hostent, h_name);
|
|
|
|
CHECK_SIZE_AND_OFFSET(hostent, h_aliases);
|
|
|
|
CHECK_SIZE_AND_OFFSET(hostent, h_addrtype);
|
|
|
|
CHECK_SIZE_AND_OFFSET(hostent, h_length);
|
|
|
|
CHECK_SIZE_AND_OFFSET(hostent, h_addr_list);
|
|
|
|
|
|
|
|
CHECK_TYPE_SIZE(iovec);
|
|
|
|
CHECK_SIZE_AND_OFFSET(iovec, iov_base);
|
|
|
|
CHECK_SIZE_AND_OFFSET(iovec, iov_len);
|
|
|
|
|
|
|
|
CHECK_TYPE_SIZE(msghdr);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_name);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_iov);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_control);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen);
|
|
|
|
CHECK_SIZE_AND_OFFSET(msghdr, msg_flags);
|
|
|
|
|
|
|
|
CHECK_TYPE_SIZE(cmsghdr);
|
|
|
|
CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);
|
|
|
|
CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
|
|
|
|
CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
|
2013-05-29 19:30:00 +08:00
|
|
|
|
Fix a veritable conucopia of bugs in the readdir_r interceptors.
First, the reason I came here: I forgot to look at readdir64_r which had
the exact same bug as readdir_r. However, upon applying the same
quick-fix and testing it I discovered that it still didn't work at all.
As a consequence, I spent some time studying the code and thinking about
it and fixed several other problems.
Second, the code was checking for a null entry and result pointer, but
there is no indication that null pointers are viable here. Certainly,
the spec makes it extremely clear that there is no non-error case where
the implementation of readdir_r fails to dereference the 'result'
pointer and store NULL to it. Thus, our checking for a non-null 'result'
pointer before reflecting that write in the instrumentation was
trivially dead. Remove it.
Third, the interceptor was marking the write to the actual dirent struct
by looking at the entry pointer, but nothing in the spec requires that
the dirent struct written is actually written into the entry structure
provided. A threadlocal buffer would be just as conforming, and the spec
goes out of its way to say the pointer to the *actual* result dirent
struct is stored into *result, so *that* is where the interceptor should
reflect a write occuring. This also obviates the need to even consider
whether the 'entry' parameter is null.
Fourth, I got to the bottom of why nothing at all worked in readdir64_r
-- the interceptor structure for dirent64 was completely wrong in that
it was the same as dirent. I fixed this struct to be correct (64-bit
inode and 64-bit offset! just a 64-bit offset isn't enough!) and added
several missing tests for the size and layout of this struct.
llvm-svn: 186109
2013-07-12 02:51:40 +08:00
|
|
|
COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
|
2013-06-27 17:37:27 +08:00
|
|
|
CHECK_SIZE_AND_OFFSET(dirent, d_ino);
|
2013-07-16 19:54:40 +08:00
|
|
|
#if SANITIZER_MAC
|
|
|
|
CHECK_SIZE_AND_OFFSET(dirent, d_seekoff);
|
|
|
|
#else
|
2013-06-27 17:37:27 +08:00
|
|
|
CHECK_SIZE_AND_OFFSET(dirent, d_off);
|
|
|
|
#endif
|
|
|
|
CHECK_SIZE_AND_OFFSET(dirent, d_reclen);
|
|
|
|
|
Fix a veritable conucopia of bugs in the readdir_r interceptors.
First, the reason I came here: I forgot to look at readdir64_r which had
the exact same bug as readdir_r. However, upon applying the same
quick-fix and testing it I discovered that it still didn't work at all.
As a consequence, I spent some time studying the code and thinking about
it and fixed several other problems.
Second, the code was checking for a null entry and result pointer, but
there is no indication that null pointers are viable here. Certainly,
the spec makes it extremely clear that there is no non-error case where
the implementation of readdir_r fails to dereference the 'result'
pointer and store NULL to it. Thus, our checking for a non-null 'result'
pointer before reflecting that write in the instrumentation was
trivially dead. Remove it.
Third, the interceptor was marking the write to the actual dirent struct
by looking at the entry pointer, but nothing in the spec requires that
the dirent struct written is actually written into the entry structure
provided. A threadlocal buffer would be just as conforming, and the spec
goes out of its way to say the pointer to the *actual* result dirent
struct is stored into *result, so *that* is where the interceptor should
reflect a write occuring. This also obviates the need to even consider
whether the 'entry' parameter is null.
Fourth, I got to the bottom of why nothing at all worked in readdir64_r
-- the interceptor structure for dirent64 was completely wrong in that
it was the same as dirent. I fixed this struct to be correct (64-bit
inode and 64-bit offset! just a 64-bit offset isn't enough!) and added
several missing tests for the size and layout of this struct.
llvm-svn: 186109
2013-07-12 02:51:40 +08:00
|
|
|
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
|
|
|
COMPILER_CHECK(sizeof(__sanitizer_dirent64) <= sizeof(dirent64));
|
|
|
|
CHECK_SIZE_AND_OFFSET(dirent64, d_ino);
|
|
|
|
CHECK_SIZE_AND_OFFSET(dirent64, d_off);
|
|
|
|
CHECK_SIZE_AND_OFFSET(dirent64, d_reclen);
|
|
|
|
#endif
|
|
|
|
|
2013-06-19 21:21:38 +08:00
|
|
|
CHECK_TYPE_SIZE(ifconf);
|
|
|
|
CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
|
|
|
|
CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
|
|
|
|
|
2013-08-12 21:19:53 +08:00
|
|
|
CHECK_TYPE_SIZE(pollfd);
|
|
|
|
CHECK_SIZE_AND_OFFSET(pollfd, fd);
|
|
|
|
CHECK_SIZE_AND_OFFSET(pollfd, events);
|
|
|
|
CHECK_SIZE_AND_OFFSET(pollfd, revents);
|
|
|
|
CHECK_TYPE_SIZE(nfds_t);
|
|
|
|
|
2013-04-03 15:24:35 +08:00
|
|
|
#endif // SANITIZER_LINUX || SANITIZER_MAC
|
2013-06-19 21:21:38 +08:00
|
|
|
|