From 745dd0d296e7bef712df4b5c7f86c72534953738 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Fri, 7 Jun 2013 13:00:47 +0000 Subject: [sanitizer] ioctl interceptor. ASan: disabled by default MSan: enabled by default TSan: disabled git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@183517 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/asan/asan_rtl.cc | 1 + lib/asan/lit_tests/TestCases/ioctl.cc | 24 + lib/msan/lit_tests/ioctl.cc | 20 + lib/msan/msan.cc | 1 + .../sanitizer_common_interceptors.inc | 7 +- .../sanitizer_common_interceptors_ioctl.inc | 546 +++++++++++++++++++++ lib/sanitizer_common/sanitizer_flags.cc | 1 + lib/sanitizer_common/sanitizer_flags.h | 2 + .../sanitizer_platform_interceptors.h | 1 + .../sanitizer_platform_limits_posix.cc | 128 ++++- .../sanitizer_platform_limits_posix.h | 78 +++ lib/tsan/rtl/tsan_stat.cc | 1 + lib/tsan/rtl/tsan_stat.h | 1 + 13 files changed, 803 insertions(+), 8 deletions(-) create mode 100644 lib/asan/lit_tests/TestCases/ioctl.cc create mode 100644 lib/msan/lit_tests/ioctl.cc create mode 100755 lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc index b0cf702a5..d5834aea7 100644 --- a/lib/asan/asan_rtl.cc +++ b/lib/asan/asan_rtl.cc @@ -136,6 +136,7 @@ void InitializeFlags(Flags *f, const char *env) { cf->fast_unwind_on_fatal = false; cf->fast_unwind_on_malloc = true; cf->strip_path_prefix = ""; + cf->handle_ioctl = false; internal_memset(f, 0, sizeof(*f)); f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; diff --git a/lib/asan/lit_tests/TestCases/ioctl.cc b/lib/asan/lit_tests/TestCases/ioctl.cc new file mode 100644 index 000000000..040ab42e5 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/ioctl.cc @@ -0,0 +1,24 @@ +// RUN: %clangxx_asan -m64 -O0 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -m64 -O3 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 %t 2>&1 | %symbolize | FileCheck %s + +// RUN: %clangxx_asan -m64 -O0 -g %s -o %t && %t +// RUN: %clangxx_asan -m64 -O3 -g %s -o %t && %t + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + int fd = socket(AF_INET, SOCK_DGRAM, 0); + + int nonblock; + int res = ioctl(fd, FIONBIO, &nonblock + 1); + // CHECK: AddressSanitizer: stack-buffer-overflow + // CHECK: READ of size 4 at + // CHECK: #{{.*}} in main {{.*}}/ioctl.cc:[[@LINE-3]] + assert(res == 0); + close(fd); + return 0; +} diff --git a/lib/msan/lit_tests/ioctl.cc b/lib/msan/lit_tests/ioctl.cc new file mode 100644 index 000000000..caff80c2e --- /dev/null +++ b/lib/msan/lit_tests/ioctl.cc @@ -0,0 +1,20 @@ +// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %t +// RUN: %clangxx_msan -m64 -O3 -g %s -o %t && %t + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + int fd = socket(AF_INET, SOCK_DGRAM, 0); + + unsigned int z; + int res = ioctl(fd, FIOGETOWN, &z); + assert(res == 0); + close(fd); + if (z) + exit(0); + return 0; +} diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index cf7b01c3d..0f62ef2e8 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -137,6 +137,7 @@ static void InitializeFlags(Flags *f, const char *options) { cf->fast_unwind_on_fatal = false; cf->fast_unwind_on_malloc = true; cf->malloc_context_size = 20; + cf->handle_ioctl = true; internal_memset(f, 0, sizeof(*f)); f->poison_heap_with_zeroes = false; diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 7586cacea..db787f5ed 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -429,6 +429,10 @@ SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) #define INIT_SCANF #endif + +#include "sanitizer_common_interceptors_ioctl.inc" + + #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS INTERCEPTOR(void *, getpwnam, const char *name) { void *ctx; @@ -1123,4 +1127,5 @@ INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { INIT_ACCEPT4; \ INIT_MODF; \ INIT_RECVMSG; \ - INIT_GETPEERNAME; + INIT_GETPEERNAME; \ + INIT_IOCTL; diff --git a/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc new file mode 100755 index 000000000..114841f76 --- /dev/null +++ b/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -0,0 +1,546 @@ +//===-- sanitizer_common_interceptors_ioctl.inc -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Ioctl handling in common sanitizer interceptors. +//===----------------------------------------------------------------------===// + +#include "sanitizer_flags.h" + +struct ioctl_desc { + unsigned req; + // FIXME: support read+write arguments. Those are currently marked as WRITE. + enum { + NONE, + READ, + WRITE, + CUSTOM + } type : 2; + unsigned size : 30; +}; + +const unsigned ioctl_table_max = 500; +static ioctl_desc ioctl_table[ioctl_table_max]; +static unsigned ioctl_table_size = 0; + +// This can not be declared as a global, because references to struct_*_sz +// require a global initializer. And this table must be available before global +// initializers are run. +static void ioctl_table_fill() { +#define _(rq, tp, sz) \ + CHECK(ioctl_table_size < ioctl_table_max); \ + ioctl_table[ioctl_table_size].req = rq; \ + ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \ + ioctl_table[ioctl_table_size].size = sz; \ + ++ioctl_table_size; + + _(0x0000540C, NONE, 0); // TIOCEXCL + _(0x0000540D, NONE, 0); // TIOCNXCL + _(0x0000540E, NONE, 0); // TIOCSCTTY + _(0x0000540F, WRITE, pid_t_sz); // TIOCGPGRP + _(0x00005410, READ, pid_t_sz); // TIOCSPGRP + _(0x00005411, WRITE, sizeof(int)); // TIOCOUTQ + _(0x00005412, READ, sizeof(char)); // TIOCSTI + _(0x00005413, WRITE, struct_winsize_sz); // TIOCGWINSZ + _(0x00005414, READ, struct_winsize_sz); // TIOCSWINSZ + _(0x00005415, WRITE, sizeof(int)); // TIOCMGET + _(0x00005416, READ, sizeof(int)); // TIOCMBIS + _(0x00005417, READ, sizeof(int)); // TIOCMBIC + _(0x00005418, READ, sizeof(int)); // TIOCMSET + _(0x0000541D, NONE, 0); // TIOCCONS + _(0x00005420, READ, sizeof(int)); // TIOCPKT + _(0x00005421, READ, sizeof(int)); // FIONBIO + _(0x00005422, NONE, 0); // TIOCNOTTY + _(0x00005423, READ, sizeof(int)); // TIOCSETD + _(0x00005424, WRITE, sizeof(int)); // TIOCGETD + _(0x00005450, NONE, 0); // FIONCLEX + _(0x00005451, NONE, 0); // FIOCLEX + _(0x00005452, READ, sizeof(int)); // FIOASYNC + _(0x00008901, READ, sizeof(int)); // FIOSETOWN + _(0x00008902, READ, sizeof(int)); // SIOCSPGRP + _(0x00008903, WRITE, sizeof(int)); // FIOGETOWN + _(0x00008904, WRITE, sizeof(int)); // SIOCGPGRP + _(0x00008905, WRITE, sizeof(int)); // SIOCATMAR + _(0x00008912, WRITE, struct_ifconf_sz); // SIOCGIFCONF + _(0x00008913, WRITE, struct_ifreq_sz); // SIOCGIFFLAGS + _(0x00008914, READ, struct_ifreq_sz); // SIOCSIFFLAGS + _(0x00008915, WRITE, struct_ifreq_sz); // SIOCGIFADDR + _(0x00008916, READ, struct_ifreq_sz); // SIOCSIFADDR + _(0x00008917, WRITE, struct_ifreq_sz); // SIOCGIFDSTADDR + _(0x00008918, READ, struct_ifreq_sz); // SIOCSIFDSTADDR + _(0x00008919, WRITE, struct_ifreq_sz); // SIOCGIFBRDADDR + _(0x0000891A, READ, struct_ifreq_sz); // SIOCSIFBRDADDR + _(0x0000891B, WRITE, struct_ifreq_sz); // SIOCGIFNETMASK + _(0x0000891C, READ, struct_ifreq_sz); // SIOCSIFNETMASK + _(0x0000891D, WRITE, struct_ifreq_sz); // SIOCGIFMETRIC + _(0x0000891E, READ, struct_ifreq_sz); // SIOCSIFMETRIC + _(0x00008921, WRITE, struct_ifreq_sz); // SIOCGIFMTU + _(0x00008922, READ, struct_ifreq_sz); // SIOCSIFMTU + _(0x00008931, READ, struct_ifreq_sz); // SIOCADDMULTI + _(0x00008932, READ, struct_ifreq_sz); // SIOCDELMULTI + _(0x00008940, NONE, 0); // SIOCADDRTOLD + _(0x00008941, NONE, 0); // SIOCDELRTOLD + _(0x000089E0, WRITE, struct_sioc_vif_req_sz); // SIOCGETVIFCNT + _(0x000089E1, WRITE, struct_sioc_sg_req_sz); // SIOCGETSGCNT + +#if SANITIZER_LINUX + _(0x00000000, NONE, 0); // FDCLRPRM + _(0x00000001, READ, struct_floppy_struct_sz); // FDSETPRM + _(0x00000002, READ, struct_floppy_struct_sz); // FDDEFPRM + _(0x00000003, WRITE, struct_floppy_struct_sz); // FDGETPRM + _(0x00000004, NONE, 0); // FDMSGON + _(0x00000005, NONE, 0); // FDMSGOFF + _(0x00000006, NONE, 0); // FDFMTBEG + _(0x00000007, READ, struct_format_descr_sz); // FDFMTTRK + _(0x00000008, NONE, 0); // FDFMTEND + _(0x0000000A, NONE, 0); // FDSETEMSGTRESH + _(0x0000000B, NONE, 0); // FDFLUSH + _(0x0000000C, READ, struct_floppy_max_errors_sz); // FDSETMAXERRS + _(0x0000000E, WRITE, struct_floppy_max_errors_sz); // FDGETMAXERRS + _(0x00000010, WRITE, 16); // FDGETDRVTYP + _(0x00000014, READ, struct_floppy_drive_params_sz); // FDSETDRVPRM + _(0x00000015, WRITE, struct_floppy_drive_params_sz); // FDGETDRVPRM + _(0x00000016, WRITE, struct_floppy_drive_struct_sz); // FDGETDRVSTAT + _(0x00000017, WRITE, struct_floppy_drive_struct_sz); // FDPOLLDRVSTAT + _(0x00000018, NONE, 0); // FDRESET + _(0x00000019, WRITE, struct_floppy_fdc_state_sz); // FDGETFDCSTAT + _(0x0000001B, NONE, 0); // FDWERRORCLR + _(0x0000001C, WRITE, struct_floppy_write_errors_sz); // FDWERRORGET + _(0x0000001E, WRITE, struct_floppy_raw_cmd_sz); // FDRAWCMD + _(0x00000028, NONE, 0); // FDTWADDLE + _(0x00000301, WRITE, struct_hd_geometry_sz); // HDIO_GETGEO + _(0x00000302, WRITE, sizeof(int)); // HDIO_GET_UNMASKINTR + _(0x00000304, WRITE, sizeof(int)); // HDIO_GET_MULTCOUNT + _(0x00000307, WRITE, struct_hd_driveid_sz); // HDIO_GET_IDENTITY + _(0x00000308, WRITE, sizeof(int)); // HDIO_GET_KEEPSETTINGS + _(0x00000309, WRITE, sizeof(int)); // HDIO_GET_CHIPSET + _(0x0000030A, WRITE, sizeof(int)); // HDIO_GET_NOWERR + _(0x0000030B, WRITE, sizeof(int)); // HDIO_GET_DMA + _(0x0000031F, WRITE, sizeof(int)); // HDIO_DRIVE_CMD + _(0x00000321, NONE, 0); // HDIO_SET_MULTCOUNT + _(0x00000322, NONE, 0); // HDIO_SET_UNMASKINTR + _(0x00000323, NONE, 0); // HDIO_SET_KEEPSETTINGS + _(0x00000324, NONE, 0); // HDIO_SET_CHIPSET + _(0x00000325, NONE, 0); // HDIO_SET_NOWERR + _(0x00000326, NONE, 0); // HDIO_SET_DMA + _(0x00000601, NONE, 0); // LPCHAR + _(0x00000602, NONE, 0); // LPTIME + _(0x00000604, NONE, 0); // LPABORT + _(0x00000605, NONE, 0); // LPSETIRQ + _(0x00000606, WRITE, sizeof(int)); // LPGETIRQ + _(0x00000608, NONE, 0); // LPWAIT + _(0x00000609, NONE, 0); // LPCAREFUL + _(0x0000060A, NONE, 0); // LPABORTOPEN + _(0x0000060B, WRITE, sizeof(int)); // LPGETSTATUS + _(0x0000060C, NONE, 0); // LPRESET + _(0x0000125D, READ, sizeof(int)); // BLKROSET + _(0x0000125E, WRITE, sizeof(int)); // BLKROGET + _(0x0000125F, NONE, 0); // BLKRRPART + _(0x00001260, WRITE, sizeof(uptr)); // BLKGETSIZE + _(0x00001261, NONE, 0); // BLKFLSBUF + _(0x00001262, NONE, 0); // BLKRASET + _(0x00001263, WRITE, sizeof(int)); // BLKRAGET + _(0x00004300, NONE, 0); // SNDCTL_COPR_RESET + _(0x00005000, NONE, 0); // SNDCTL_DSP_RESET + _(0x00005001, NONE, 0); // SNDCTL_DSP_SYNC + _(0x00005008, NONE, 0); // SNDCTL_DSP_POST + _(0x0000500E, NONE, 0); // SNDCTL_DSP_NONBLOCK + _(0x00005100, NONE, 0); // SNDCTL_SEQ_RESET + _(0x00005101, NONE, 0); // SNDCTL_SEQ_SYNC + _(0x00005111, NONE, 0); // SNDCTL_SEQ_PANIC + _(0x00005301, NONE, 0); // CDROMPAUSE + _(0x00005302, NONE, 0); // CDROMRESUME + _(0x00005303, READ, struct_cdrom_msf_sz); // CDROMPLAYMSF + _(0x00005304, READ, struct_cdrom_ti_sz); // CDROMPLAYTRKIND + _(0x00005305, WRITE, struct_cdrom_tochdr_sz); // CDROMREADTOCHDR + _(0x00005306, WRITE, struct_cdrom_tocentry_sz); // CDROMREADTOCENTRY + _(0x00005307, NONE, 0); // CDROMSTOP + _(0x00005308, NONE, 0); // CDROMSTART + _(0x00005309, NONE, 0); // CDROMEJECT + _(0x0000530A, READ, struct_cdrom_volctrl_sz); // CDROMVOLCTRL + _(0x0000530B, WRITE, struct_cdrom_subchnl_sz); // CDROMSUBCHNL + _(0x0000530C, READ, struct_cdrom_msf_sz); // CDROMREADMODE2 + _(0x0000530D, READ, struct_cdrom_msf_sz); // CDROMREADMODE1 + _(0x0000530E, READ, struct_cdrom_read_audio_sz); // CDROMREADAUDIO + _(0x0000530F, NONE, 0); // CDROMEJECT_SW + _(0x00005310, WRITE, struct_cdrom_multisession_sz); // CDROMMULTISESSION + _(0x00005311, WRITE, 8); // CDROM_GET_UPC + _(0x00005312, NONE, 0); // CDROMRESET + _(0x00005313, WRITE, struct_cdrom_volctrl_sz); // CDROMVOLREAD + _(0x00005314, READ, struct_cdrom_msf_sz); // CDROMREADRAW + _(0x00005315, READ, struct_cdrom_msf_sz); // CDROMREADCOOKED + _(0x00005316, READ, struct_cdrom_msf_sz); // CDROMSEEK + // Conflicting request id. + // _(0x00005382, NONE, 0); // CDROMAUDIOBUFSIZ + // _(0x00005382, WRITE, 2 * sizeof(int)); // SCSI_IOCTL_GET_IDLUN + _(0x00005383, NONE, 0); // SCSI_IOCTL_TAGGED_ENABLE + _(0x00005384, NONE, 0); // SCSI_IOCTL_TAGGED_DISABLE + _(0x00005385, READ, sizeof(int)); // SCSI_IOCTL_PROBE_HOST + _(0x00005401, WRITE, struct_termios_sz); // TCGETS + _(0x00005402, READ, struct_termios_sz); // TCSETS + _(0x00005403, READ, struct_termios_sz); // TCSETSW + _(0x00005404, READ, struct_termios_sz); // TCSETSF + _(0x00005405, WRITE, struct_termio_sz); // TCGETA + _(0x00005406, READ, struct_termio_sz); // TCSETA + _(0x00005407, READ, struct_termio_sz); // TCSETAW + _(0x00005408, READ, struct_termio_sz); // TCSETAF + _(0x00005409, NONE, 0); // TCSBRK + _(0x0000540A, NONE, 0); // TCXONC + _(0x0000540B, NONE, 0); // TCFLSH + // Conflicting request id. + // _(0x00005402, NONE, 0); // SNDCTL_TMR_START + // _(0x00005403, NONE, 0); // SNDCTL_TMR_STOP + // _(0x00005404, NONE, 0); // SNDCTL_TMR_CONTINUE + _(0x00005419, WRITE, sizeof(int)); // TIOCGSOFTCAR + _(0x0000541A, READ, sizeof(int)); // TIOCSSOFTCAR + _(0x0000541B, WRITE, sizeof(int)); // TIOCINQ + _(0x0000541C, READ, sizeof(char)); // TIOCLINUX + _(0x00005425, NONE, 0); // TCSBRKP + _(0x00005453, NONE, 0); // TIOCSERCONFIG + _(0x00005454, WRITE, sizeof(int)); // TIOCSERGWILD + _(0x00005455, READ, sizeof(int)); // TIOCSERSWILD + _(0x00005456, WRITE, struct_termios_sz); // TIOCGLCKTRMIOS + _(0x00005457, READ, struct_termios_sz); // TIOCSLCKTRMIOS + _(0x00005459, WRITE, sizeof(int)); // TIOCSERGETLSR + _(0x00005470, NONE, 0); // TIOCSCCINI + _(0x00005490, WRITE, sizeof(int)); // PPPIOCGFLAGS + _(0x00005491, READ, sizeof(int)); // PPPIOCSFLAGS + _(0x00005492, WRITE, sizeof(int)); // PPPIOCGASYNCMAP + _(0x00005493, READ, sizeof(int)); // PPPIOCSASYNCMAP + _(0x00005494, WRITE, sizeof(int)); // PPPIOCGUNIT + _(0x00005495, READ, sizeof(int)); // PPPIOCSINPSIG + _(0x00005497, READ, sizeof(int)); // PPPIOCSDEBUG + _(0x00005498, WRITE, sizeof(int)); // PPPIOCGDEBUG + _(0x0000549B, WRITE, sizeof(int) * 8); // PPPIOCGXASYNCMAP + _(0x0000549C, READ, sizeof(int) * 8); // PPPIOCSXASYNCMAP + _(0x0000549D, READ, sizeof(int)); // PPPIOCSMRU + _(0x0000549E, READ, sizeof(int)); // PPPIOCRASYNCMAP + _(0x0000549F, READ, sizeof(int)); // PPPIOCSMAXCID + _(0x00005600, WRITE, sizeof(int)); // VT_OPENQRY + _(0x00005601, WRITE, struct_vt_mode_sz); // VT_GETMODE + _(0x00005602, READ, struct_vt_mode_sz); // VT_SETMODE + _(0x00005603, WRITE, struct_vt_stat_sz); // VT_GETSTATE + _(0x00005604, NONE, 0); // VT_SENDSIG + _(0x00005605, NONE, 0); // VT_RELDISP + _(0x00005606, NONE, 0); // VT_ACTIVATE + _(0x00005607, NONE, 0); // VT_WAITACTIVE + _(0x00005608, NONE, 0); // VT_DISALLOCATE + _(0x00005609, READ, struct_vt_sizes_sz); // VT_RESIZE + _(0x0000560A, READ, struct_vt_consize_sz); // VT_RESIZEX + _(0x00007314, NONE, 0); // STL_BINTR + _(0x00007315, NONE, 0); // STL_BSTART + _(0x00007316, NONE, 0); // STL_BSTOP + _(0x00007317, NONE, 0); // STL_BRESET + _(0x00008906, WRITE, timeval_sz); // SIOCGSTAMP + _(0x0000890B, READ, struct_rtentry_sz); // SIOCADDRT + _(0x0000890C, READ, struct_rtentry_sz); // SIOCDELRT + _(0x00008910, NONE, 0); // SIOCGIFNAME + _(0x00008911, NONE, 0); // SIOCSIFLINK + _(0x0000891F, WRITE, struct_ifreq_sz); // SIOCGIFMEM + _(0x00008920, READ, struct_ifreq_sz); // SIOCSIFMEM + _(0x00008923, WRITE, struct_ifreq_sz); // OLD_SIOCGIFHWADDR + _(0x00008924, READ, struct_ifreq_sz); // SIOCSIFHWADDR + _(0x00008925, WRITE, sizeof(int)); // SIOCGIFENCAP + _(0x00008926, READ, sizeof(int)); // SIOCSIFENCAP + _(0x00008927, WRITE, struct_ifreq_sz); // SIOCGIFHWADDR + _(0x00008929, NONE, 0); // SIOCGIFSLAVE + _(0x00008930, NONE, 0); // SIOCSIFSLAVE + _(0x00008950, READ, struct_arpreq_sz); // SIOCDARP + _(0x00008951, WRITE, struct_arpreq_sz); // SIOCGARP + _(0x00008952, READ, struct_arpreq_sz); // SIOCSARP + _(0x00008960, READ, struct_arpreq_sz); // SIOCDRARP + _(0x00008961, WRITE, struct_arpreq_sz); // SIOCGRARP + _(0x00008962, READ, struct_arpreq_sz); // SIOCSRARP + _(0x00008970, WRITE, struct_ifreq_sz); // SIOCGIFMAP + _(0x00008971, READ, struct_ifreq_sz); // SIOCSIFMAP + _(0x000089F0, WRITE, struct_ifreq_sz); // SIOCDEVPLIP and EQL_ENSLAVE + _(0x000089F1, WRITE, struct_ifreq_sz); // EQL_EMANCIPATE + _(0x000089F2, WRITE, struct_ifreq_sz); // EQL_GETSLAVECFG + _(0x000089F3, WRITE, struct_ifreq_sz); // EQL_SETSLAVECFG + _(0x000089F4, WRITE, struct_ifreq_sz); // EQL_GETMASTRCFG + _(0x000089F5, WRITE, struct_ifreq_sz); // EQL_SETMASTRCFG + _(0x00009000, READ, sizeof(int)); // DDIOCSDBG + _(0x40045106, NONE, 0); // SNDCTL_SEQ_PERCMODE + _(0x40045108, READ, sizeof(int)); // SNDCTL_SEQ_TESTMIDI + _(0x40045109, READ, sizeof(int)); // SNDCTL_SEQ_RESETSAMPLES + _(0x4004510D, READ, sizeof(int)); // SNDCTL_SEQ_THRESHOLD + _(0x4004510F, READ, sizeof(int)); // SNDCTL_FM_4OP_ENABLE + _(0x40045407, READ, sizeof(int)); // SNDCTL_TMR_METRONOME + _(0x40045408, WRITE, sizeof(int)); // SNDCTL_TMR_SELECT + _(0x40046602, READ, sizeof(int)); // EXT2_IOC_SETFLAGS + _(0x40047602, READ, sizeof(int)); // EXT2_IOC_SETVERSION + _(0x40085112, READ, struct_seq_event_rec_sz); // SNDCTL_SEQ_OUTOFBAND + _(0x40086D01, READ, struct_mtop_sz); // MTIOCTOP + _(0x40144304, READ, struct_copr_debug_buf_sz); // SNDCTL_COPR_WDATA + _(0x40144305, READ, struct_copr_debug_buf_sz); // SNDCTL_COPR_WCODE + _(0x40285107, READ, struct_sbi_instrument_sz); // SNDCTL_FM_LOAD_INSTR + _(0x4FA44308, READ, struct_copr_msg_sz); // SNDCTL_COPR_SENDMSG + _(0x80027501, WRITE, uid_t_sz); // SMB_IOC_GETMOUNTUID + _(0x80044D00, WRITE, sizeof(int)); // SOUND_MIXER_READ_VOLUME + _(0x80044D01, WRITE, sizeof(int)); // SOUND_MIXER_READ_BASS + _(0x80044D02, WRITE, sizeof(int)); // SOUND_MIXER_READ_TREBLE + _(0x80044D03, WRITE, sizeof(int)); // SOUND_MIXER_READ_SYNTH + _(0x80044D04, WRITE, sizeof(int)); // SOUND_MIXER_READ_PCM + _(0x80044D05, WRITE, sizeof(int)); // SOUND_MIXER_READ_SPEAKER + _(0x80044D06, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE + _(0x80044D07, WRITE, sizeof(int)); // SOUND_MIXER_READ_MIC + _(0x80044D08, WRITE, sizeof(int)); // SOUND_MIXER_READ_CD + _(0x80044D09, WRITE, sizeof(int)); // SOUND_MIXER_READ_IMIX + _(0x80044D0A, WRITE, sizeof(int)); // SOUND_MIXER_READ_ALTPCM + _(0x80044D0B, WRITE, sizeof(int)); // SOUND_MIXER_READ_RECLEV + _(0x80044D0C, WRITE, sizeof(int)); // SOUND_MIXER_READ_IGAIN + _(0x80044D0D, WRITE, sizeof(int)); // SOUND_MIXER_READ_OGAIN + _(0x80044D0E, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE1 + _(0x80044D0F, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE2 + _(0x80044D10, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE3 + _(0x80044D1C, WRITE, sizeof(int)); // SOUND_MIXER_READ_MUTE + _(0x80044D1D, WRITE, sizeof(int)); // SOUND_MIXER_READ_ENHANCE + _(0x80044D1E, WRITE, sizeof(int)); // SOUND_MIXER_READ_LOUD + _(0x80044DFB, WRITE, sizeof(int)); // SOUND_MIXER_READ_STEREODEVS + _(0x80044DFC, WRITE, sizeof(int)); // SOUND_MIXER_READ_CAPS + _(0x80044DFD, WRITE, sizeof(int)); // SOUND_MIXER_READ_RECMASK + _(0x80044DFE, WRITE, sizeof(int)); // SOUND_MIXER_READ_DEVMASK + _(0x80044DFF, WRITE, sizeof(int)); // SOUND_MIXER_READ_RECSRC + _(0x80045002, WRITE, sizeof(int)); // SOUND_PCM_READ_RATE + _(0x80045005, WRITE, sizeof(int)); // SOUND_PCM_READ_BITS + _(0x80045006, WRITE, sizeof(int)); // SOUND_PCM_READ_CHANNELS + _(0x80045007, WRITE, sizeof(int)); // SOUND_PCM_READ_FILTER + _(0x8004500B, WRITE, sizeof(int)); // SNDCTL_DSP_GETFMTS + _(0x80045104, WRITE, sizeof(int)); // SNDCTL_SEQ_GETOUTCOUNT + _(0x80045105, WRITE, sizeof(int)); // SNDCTL_SEQ_GETINCOUNT + _(0x8004510A, WRITE, sizeof(int)); // SNDCTL_SEQ_NRSYNTHS + _(0x8004510B, WRITE, sizeof(int)); // SNDCTL_SEQ_NRMIDIS + _(0x80046601, WRITE, sizeof(int)); // EXT2_IOC_GETFLAGS + _(0x80046D03, WRITE, struct_mtpos_sz); // MTIOCPOS + _(0x80047601, WRITE, sizeof(int)); // EXT2_IOC_GETVERSION + _(0x801C6D02, WRITE, struct_mtget_sz); // MTIOCGET + _(0x8FA44309, WRITE, struct_copr_msg_sz); // SNDCTL_COPR_RCVMSG + _(0xC0044D00, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_VOLUME + _(0xC0044D01, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_BASS + _(0xC0044D02, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_TREBLE + _(0xC0044D03, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_SYNTH + _(0xC0044D04, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_PCM + _(0xC0044D05, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_SPEAKER + _(0xC0044D06, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE + _(0xC0044D07, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_MIC + _(0xC0044D08, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_CD + _(0xC0044D09, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_IMIX + _(0xC0044D0A, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_ALTPCM + _(0xC0044D0B, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_RECLEV + _(0xC0044D0C, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_IGAIN + _(0xC0044D0D, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_OGAIN + _(0xC0044D0E, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE1 + _(0xC0044D0F, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE2 + _(0xC0044D10, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE3 + _(0xC0044D1C, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_MUTE + _(0xC0044D1D, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_ENHANCE + _(0xC0044D1E, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LOUD + _(0xC0044DFF, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_RECSRC + _(0xC0045002, WRITE, sizeof(int)); // SNDCTL_DSP_SPEED + _(0xC0045003, WRITE, sizeof(int)); // SNDCTL_DSP_STEREO + _(0xC0045004, WRITE, sizeof(int)); // SNDCTL_DSP_GETBLKSIZE + _(0xC0045005, WRITE, sizeof(int)); // SNDCTL_DSP_SETFMT + _(0xC0045006, WRITE, sizeof(int)); // SOUND_PCM_WRITE_CHANNELS + _(0xC0045007, WRITE, sizeof(int)); // SOUND_PCM_WRITE_FILTER + _(0xC0045009, WRITE, sizeof(int)); // SNDCTL_DSP_SUBDIVIDE + _(0xC004500A, WRITE, sizeof(int)); // SNDCTL_DSP_SETFRAGMENT + _(0xC0045103, WRITE, sizeof(int)); // SNDCTL_SEQ_CTRLRATE + _(0xC004510E, WRITE, sizeof(int)); // SNDCTL_SYNTH_MEMAVL + _(0xC0045401, WRITE, sizeof(int)); // SNDCTL_TMR_TIMEBASE + _(0xC0045405, WRITE, sizeof(int)); // SNDCTL_TMR_TEMPO + _(0xC0045406, WRITE, sizeof(int)); // SNDCTL_TMR_SOURCE + _(0xC0046D00, WRITE, sizeof(int)); // SNDCTL_MIDI_PRETIME + _(0xC0046D01, READ, sizeof(int)); // SNDCTL_MIDI_MPUMODE + _(0xC0144302, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_RDATA + _(0xC0144303, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_RCODE + _(0xC0144306, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_RUN + _(0xC0144307, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_HALT + _(0xC074510C, WRITE, struct_midi_info_sz); // SNDCTL_MIDI_INFO + _(0xC08C5102, WRITE, struct_synth_info_sz); // SNDCTL_SYNTH_INFO + _(0xCFB04301, READ, struct_copr_buffer_sz); // SNDCTL_COPR_LOAD +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID + _(0x00005499, WRITE, struct_ppp_stats_sz); // PPPIOCGSTAT + + _(0x00004B2F, NONE, 0); // KIOCSOUND + _(0x00004B30, NONE, 0); // KDMKTONE + _(0x00004B31, WRITE, 1); // KDGETLED + _(0x00004B32, NONE, 0); // KDSETLED + _(0x00004B33, WRITE, 1); // KDGKBTYPE + _(0x00004B34, NONE, 0); // KDADDIO + _(0x00004B35, NONE, 0); // KDDELIO + _(0x00004B36, NONE, 0); // KDENABIO + _(0x00004B37, NONE, 0); // KDDISABIO + _(0x00004B3A, NONE, 0); // KDSETMODE + _(0x00004B3B, WRITE, sizeof(int)); // KDGETMODE + _(0x00004B3C, NONE, 0); // KDMAPDISP + _(0x00004B3D, NONE, 0); // KDUNMAPDISP + _(0x00004B40, WRITE, e_tabsz); // GIO_SCRNMAP + _(0x00004B41, READ, e_tabsz); // PIO_SCRNMAP + _(0x00004B44, WRITE, sizeof(int)); // KDGKBMODE + _(0x00004B45, NONE, 0); // KDSKBMODE + _(0x00004B46, WRITE, struct_kbentry_sz); // KDGKBENT + _(0x00004B47, READ, struct_kbentry_sz); // KDSKBENT + _(0x00004B48, WRITE, struct_kbsentry_sz); // KDGKBSENT + _(0x00004B49, READ, struct_kbsentry_sz); // KDSKBSENT + _(0x00004B4A, WRITE, struct_kbdiacrs_sz); // KDGKBDIACR + _(0x00004B4B, READ, struct_kbdiacrs_sz); // KDSKBDIACR + _(0x00004B4C, WRITE, struct_kbkeycode_sz); // KDGETKEYCODE + _(0x00004B4D, READ, struct_kbkeycode_sz); // KDSETKEYCODE + _(0x00004B4E, NONE, 0); // KDSIGACCEPT + _(0x00004B60, WRITE, 8192); // GIO_FONT + _(0x00004B61, READ, 8192); // PIO_FONT + _(0x00004B62, WRITE, sizeof(int)); // KDGKBMETA + _(0x00004B63, NONE, 0); // KDSKBMETA + _(0x00004B64, WRITE, sizeof(int)); // KDGKBLED + _(0x00004B65, NONE, 0); // KDSKBLED + _(0x00004B66, WRITE, struct_unimapdesc_sz); // GIO_UNIMAP + _(0x00004B67, READ, struct_unimapdesc_sz); // PIO_UNIMAP + _(0x00004B68, READ, struct_unimapinit_sz); // PIO_UNIMAPCLR + _(0x00004B69, WRITE, sizeof(short) * e_tabsz); // GIO_UNISCRNMAP + _(0x00004B6A, READ, sizeof(short) * e_tabsz); // PIO_UNISCRNMAP + _(0x00004B70, WRITE, 48); // GIO_CMAP + _(0x00004B71, NONE, 0); // PIO_CMAP + + // Missing struct definition on Android. + _(0x0000541E, WRITE, struct_serial_struct_sz); // TIOCGSERIAL + _(0x0000541F, READ, struct_serial_struct_sz); // TIOCSSERIAL + _(0x0000545A, WRITE, struct_serial_multiport_struct_sz); // TIOCSERGETMULTI + _(0x0000545B, READ, struct_serial_multiport_struct_sz); // TIOCSERSETMULTI + _(0x00005471, READ, struct_scc_modem_sz); // TIOCCHANINI + _(0x00005474, WRITE, struct_scc_stat_sz); // TIOCSCCSTAT + + // The following ioctl requests are shared between AX25, IPX, netrom and + // mrouted. + // _(0x000089E0, READ, sizeof(char)); // SIOCAIPXITFCRT + // _(0x000089E0, READ, struct_sockaddr_ax25_sz); // SIOCAX25GETUID + // _(0x000089E0, WRITE, struct_nr_parms_struct_sz); // SIOCNRGETPARMS + // _(0x000089E1, READ, sizeof(char)); // SIOCAIPXPRISLT + // _(0x000089E1, READ, struct_nr_parms_struct_sz); // SIOCNRSETPARMS + // _(0x000089E1, READ, struct_sockaddr_ax25_sz); // SIOCAX25ADDUID + // _(0x000089E2, NONE, 0); // SIOCNRDECOBS + // _(0x000089E2, READ, struct_sockaddr_ax25_sz); // SIOCAX25DELUID + // _(0x000089E2, WRITE, struct_ipx_config_data_sz); // SIOCIPXCFGDATA + // _(0x000089E3, READ, sizeof(int)); // SIOCAX25NOUID + // _(0x000089E3, READ, sizeof(int)); // SIOCNRRTCTL + // _(0x000089E4, READ, sizeof(int)); // SIOCAX25DIGCTL + // _(0x000089E5, WRITE, struct_ax25_parms_struct_sz); // SIOCAX25GETPARMS + // _(0x000089E6, READ, struct_ax25_parms_struct_sz); // SIOCAX25SETPARMS + + _(0x00435901, WRITE, struct_cyclades_monitor_sz); // CYGETMON + _(0x00435902, WRITE, sizeof(int)); // CYGETTHRESH + _(0x00435903, NONE, 0); // CYSETTHRESH + _(0x00435904, WRITE, sizeof(int)); // CYGETDEFTHRESH + _(0x00435905, NONE, 0); // CYSETDEFTHRESH + _(0x00435906, WRITE, sizeof(int)); // CYGETTIMEOUT + _(0x00435907, NONE, 0); // CYSETTIMEOUT + _(0x00435908, WRITE, sizeof(int)); // CYGETDEFTIMEOUT + _(0x00435909, NONE, 0); // CYSETDEFTIMEOUT + + // Missing definition of mtconfiginfo + _(0x40206D05, READ, struct_mtconfiginfo_sz); // MTIOCSETCONFIG + _(0x80206D04, WRITE, struct_mtconfiginfo_sz); // MTIOCGETCONFIG + + _(0x800C500C, WRITE, struct_audio_buf_info_sz); // SNDCTL_DSP_GETOSPACE + _(0x800C500D, WRITE, struct_audio_buf_info_sz); // SNDCTL_DSP_GETISPACE +#endif +#undef _ + // FIXME: missing USB ioctls (EVIOxx...x). +} + +static bool ioctl_initialized = false; + +struct ioctl_desc_compare { + bool operator()(const ioctl_desc& left, const ioctl_desc& right) const { + return left.req < right.req; + } +}; + +static void ioctl_init() { + ioctl_table_fill(); + InternalSort(&ioctl_table, ioctl_table_size, ioctl_desc_compare()); + + for (unsigned i = 0; i < ioctl_table_size - 1; ++i) { + if (ioctl_table[i].req >= ioctl_table[i + 1].req) { + Printf("Duplicate or unsorted ioctl request id %x >= %x\n", + ioctl_table[i].req, ioctl_table[i + 1].req); + Die(); + } + } + + ioctl_initialized = true; +} + +static const ioctl_desc *ioctl_lookup(unsigned req) { + int left = 0; + int right = sizeof(ioctl_table) / sizeof(*ioctl_table); + while (left < right) { + int mid = (left + right) / 2; + if (ioctl_table[mid].req < req) + left = mid + 1; + else + right = mid; + } + if (left == right && ioctl_table[left].req == req) + return ioctl_table + left; + else + return 0; +} + +static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d, + unsigned request, void *arg) { + if (desc->type == ioctl_desc::READ) + COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, desc->size); + if (desc->type != ioctl_desc::CUSTOM) + return; + // FIXME: add some ioctls of "CUSTOM" type and handle them here. + return; +} + +static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d, + unsigned request, void *arg) { + if (desc->type == ioctl_desc::WRITE) { + // FIXME: add verbose output + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, desc->size); + } + if (desc->type != ioctl_desc::CUSTOM) + return; + return; // FIXME +} + +#if SANITIZER_INTERCEPT_IOCTL +#define INIT_IOCTL \ + ioctl_init(); \ + INTERCEPT_FUNCTION(ioctl); +INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); + + CHECK(ioctl_initialized); + + // Note: TSan does not use common flags, and they are zero-initialized. + // This effectively disables ioctl handling in TSan. + if (!common_flags()->handle_ioctl) + return REAL(ioctl)(d, request, arg); + + const ioctl_desc *desc = ioctl_lookup(request); + if (!desc) + Printf("WARNING: unknown ioctl %x\n", request); + + if (desc) + ioctl_common_pre(ctx, desc, d, request, arg); + int res = REAL(ioctl)(d, request, arg); + // FIXME: some ioctls have different return values for success and failure. + if (desc && res != -1) + ioctl_common_post(ctx, desc, res, d, request, arg); + return res; +} +#else +#define INIT_IOCTL +#endif diff --git a/lib/sanitizer_common/sanitizer_flags.cc b/lib/sanitizer_common/sanitizer_flags.cc index 803d47056..95c6feeb9 100644 --- a/lib/sanitizer_common/sanitizer_flags.cc +++ b/lib/sanitizer_common/sanitizer_flags.cc @@ -27,6 +27,7 @@ void ParseCommonFlagsFromString(const char *str) { ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal"); ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc"); ParseFlag(str, &f->symbolize, "symbolize"); + ParseFlag(str, &f->handle_ioctl, "handle_ioctl"); } static bool GetFlagValue(const char *env, const char *name, diff --git a/lib/sanitizer_common/sanitizer_flags.h b/lib/sanitizer_common/sanitizer_flags.h index e97ce6a87..12c4270cb 100644 --- a/lib/sanitizer_common/sanitizer_flags.h +++ b/lib/sanitizer_common/sanitizer_flags.h @@ -33,6 +33,8 @@ struct CommonFlags { bool fast_unwind_on_fatal; // Use fast (frame-pointer-based) unwinder on malloc/free (if available). bool fast_unwind_on_malloc; + // Intercept and handle ioctl requests. + bool handle_ioctl; // Max number of stack frames kept for each allocation/deallocation. int malloc_context_size; }; diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 310ef8a4f..ab16ddba5 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -80,5 +80,6 @@ # define SANITIZER_INTERCEPT_MODF SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_RECVMSG SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_GETPEERNAME SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_IOCTL SI_NOT_WINDOWS #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 1df8b9252..bc20fda12 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -22,23 +22,55 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#if SANITIZER_LINUX +#include +#include +#include +#include +#include +#endif + #if !SANITIZER_ANDROID #include -#endif // !SANITIZER_ANDROID +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // SANITIZER_LINUX && !SANITIZER_ANDROID + +#if SANITIZER_ANDROID +#include +#endif #if SANITIZER_LINUX #include @@ -46,6 +78,10 @@ #include #endif // SANITIZER_LINUX +#if SANITIZER_MAC +#include +#endif + namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); @@ -58,6 +94,9 @@ namespace __sanitizer { unsigned struct_sigaction_sz = sizeof(struct sigaction); unsigned struct_itimerval_sz = sizeof(struct itimerval); unsigned pthread_t_sz = sizeof(pthread_t); + unsigned pid_t_sz = sizeof(pid_t); + unsigned timeval_sz = sizeof(timeval); + unsigned uid_t_sz = sizeof(uid_t); #if !SANITIZER_ANDROID unsigned ucontext_t_sz = sizeof(ucontext_t); @@ -80,6 +119,10 @@ namespace __sanitizer { uptr sig_ign = (uptr)SIG_IGN; uptr sig_dfl = (uptr)SIG_DFL; +#if SANITIZER_LINUX + int e_tabsz = (int)E_TABSZ; +#endif + uptr __sanitizer_get_sigaction_sa_sigaction(void *act) { struct sigaction *a = (struct sigaction *)act; // Check that sa_sigaction and sa_handler are the same. @@ -103,6 +146,77 @@ namespace __sanitizer { else return 0; } + + // ioctl arguments + unsigned struct_arpreq_sz = sizeof(struct arpreq); + unsigned struct_ifconf_sz = sizeof(struct ifconf); + unsigned struct_ifreq_sz = sizeof(struct ifreq); + unsigned struct_termios_sz = sizeof(struct termios); + unsigned struct_winsize_sz = sizeof(struct winsize); + +#if SANITIZER_LINUX + unsigned struct_cdrom_msf_sz = sizeof(struct cdrom_msf); + unsigned struct_cdrom_multisession_sz = sizeof(struct cdrom_multisession); + unsigned struct_cdrom_read_audio_sz = sizeof(struct cdrom_read_audio); + unsigned struct_cdrom_subchnl_sz = sizeof(struct cdrom_subchnl); + unsigned struct_cdrom_ti_sz = sizeof(struct cdrom_ti); + unsigned struct_cdrom_tocentry_sz = sizeof(struct cdrom_tocentry); + unsigned struct_cdrom_tochdr_sz = sizeof(struct cdrom_tochdr); + unsigned struct_cdrom_volctrl_sz = sizeof(struct cdrom_volctrl); + unsigned struct_copr_buffer_sz = sizeof(struct copr_buffer); + unsigned struct_copr_debug_buf_sz = sizeof(struct copr_debug_buf); + unsigned struct_copr_msg_sz = sizeof(struct copr_msg); + unsigned struct_floppy_drive_params_sz = sizeof(struct floppy_drive_params); + unsigned struct_floppy_drive_struct_sz = sizeof(struct floppy_drive_struct); + unsigned struct_floppy_fdc_state_sz = sizeof(struct floppy_fdc_state); + unsigned struct_floppy_max_errors_sz = sizeof(struct floppy_max_errors); + unsigned struct_floppy_raw_cmd_sz = sizeof(struct floppy_raw_cmd); + unsigned struct_floppy_struct_sz = sizeof(struct floppy_struct); + unsigned struct_floppy_write_errors_sz = sizeof(struct floppy_write_errors); + unsigned struct_format_descr_sz = sizeof(struct format_descr); + unsigned struct_hd_driveid_sz = sizeof(struct hd_driveid); + unsigned struct_hd_geometry_sz = sizeof(struct hd_geometry); + unsigned struct_midi_info_sz = sizeof(struct midi_info); + unsigned struct_mtget_sz = sizeof(struct mtget); + unsigned struct_mtop_sz = sizeof(struct mtop); + unsigned struct_mtpos_sz = sizeof(struct mtpos); + unsigned struct_rtentry_sz = sizeof(struct rtentry); + unsigned struct_sbi_instrument_sz = sizeof(struct sbi_instrument); + unsigned struct_seq_event_rec_sz = sizeof(struct seq_event_rec); + unsigned struct_synth_info_sz = sizeof(struct synth_info); + unsigned struct_termio_sz = sizeof(struct termio); + unsigned struct_vt_consize_sz = sizeof(struct vt_consize); + unsigned struct_vt_mode_sz = sizeof(struct vt_mode); + unsigned struct_vt_sizes_sz = sizeof(struct vt_sizes); + unsigned struct_vt_stat_sz = sizeof(struct vt_stat); +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID + unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info); + unsigned struct_ax25_parms_struct_sz = sizeof(struct ax25_parms_struct); + unsigned struct_cyclades_monitor_sz = sizeof(struct cyclades_monitor); + unsigned struct_ipx_config_data_sz = sizeof(struct ipx_config_data); + unsigned struct_kbdiacrs_sz = sizeof(struct kbdiacrs); + unsigned struct_kbentry_sz = sizeof(struct kbentry); + unsigned struct_kbkeycode_sz = sizeof(struct kbkeycode); + unsigned struct_kbsentry_sz = sizeof(struct kbsentry); + unsigned mpu_command_rec_sz = sizeof(mpu_command_rec); + unsigned struct_mtconfiginfo_sz = sizeof(struct mtconfiginfo); + unsigned struct_nr_parms_struct_sz = sizeof(struct nr_parms_struct); + unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); + unsigned struct_scc_modem_sz = sizeof(struct scc_modem); + unsigned struct_scc_stat_sz = sizeof(struct scc_stat); + unsigned struct_serial_multiport_struct_sz = sizeof(struct serial_multiport_struct); + unsigned struct_serial_struct_sz = sizeof(struct serial_struct); + unsigned struct_sockaddr_ax25_sz = sizeof(struct sockaddr_ax25); + unsigned struct_unimapdesc_sz = sizeof(struct unimapdesc); + unsigned struct_unimapinit_sz = sizeof(struct unimapinit); +#endif + +#if !SANITIZER_ANDROID + unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); + unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); +#endif } // namespace __sanitizer #define CHECK_TYPE_SIZE(TYPE) \ diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 8cb4bb6d4..cef6862d4 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -29,6 +29,9 @@ namespace __sanitizer { extern unsigned siginfo_t_sz; extern unsigned struct_itimerval_sz; extern unsigned pthread_t_sz; + extern unsigned pid_t_sz; + extern unsigned timeval_sz; + extern unsigned uid_t_sz; #if !SANITIZER_ANDROID extern unsigned ucontext_t_sz; @@ -105,6 +108,10 @@ namespace __sanitizer { extern uptr sig_ign; extern uptr sig_dfl; +#if SANITIZER_LINUX + extern int e_tabsz; +#endif + uptr __sanitizer_in_addr_sz(int af); #if SANITIZER_LINUX @@ -141,6 +148,77 @@ namespace __sanitizer { char **h_addr_list; }; + // ioctl arguments + extern unsigned struct_arpreq_sz; + extern unsigned struct_ifconf_sz; + extern unsigned struct_ifreq_sz; + extern unsigned struct_termios_sz; + extern unsigned struct_winsize_sz; + +#if SANITIZER_LINUX + extern unsigned struct_cdrom_msf_sz; + extern unsigned struct_cdrom_multisession_sz; + extern unsigned struct_cdrom_read_audio_sz; + extern unsigned struct_cdrom_subchnl_sz; + extern unsigned struct_cdrom_ti_sz; + extern unsigned struct_cdrom_tocentry_sz; + extern unsigned struct_cdrom_tochdr_sz; + extern unsigned struct_cdrom_volctrl_sz; + extern unsigned struct_copr_buffer_sz; + extern unsigned struct_copr_debug_buf_sz; + extern unsigned struct_copr_msg_sz; + extern unsigned struct_floppy_drive_params_sz; + extern unsigned struct_floppy_drive_struct_sz; + extern unsigned struct_floppy_fdc_state_sz; + extern unsigned struct_floppy_max_errors_sz; + extern unsigned struct_floppy_raw_cmd_sz; + extern unsigned struct_floppy_struct_sz; + extern unsigned struct_floppy_write_errors_sz; + extern unsigned struct_format_descr_sz; + extern unsigned struct_hd_driveid_sz; + extern unsigned struct_hd_geometry_sz; + extern unsigned struct_midi_info_sz; + extern unsigned struct_mtget_sz; + extern unsigned struct_mtop_sz; + extern unsigned struct_mtpos_sz; + extern unsigned struct_rtentry_sz; + extern unsigned struct_sbi_instrument_sz; + extern unsigned struct_seq_event_rec_sz; + extern unsigned struct_synth_info_sz; + extern unsigned struct_termio_sz; + extern unsigned struct_vt_consize_sz; + extern unsigned struct_vt_mode_sz; + extern unsigned struct_vt_sizes_sz; + extern unsigned struct_vt_stat_sz; +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID + extern unsigned struct_audio_buf_info_sz; + extern unsigned struct_ax25_parms_struct_sz; + extern unsigned struct_cyclades_monitor_sz; + extern unsigned struct_ipx_config_data_sz; + extern unsigned struct_kbdiacrs_sz; + extern unsigned struct_kbentry_sz; + extern unsigned struct_kbkeycode_sz; + extern unsigned struct_kbsentry_sz; + extern unsigned mpu_command_rec_sz; + extern unsigned struct_mtconfiginfo_sz; + extern unsigned struct_nr_parms_struct_sz; + extern unsigned struct_ppp_stats_sz; + extern unsigned struct_scc_modem_sz; + extern unsigned struct_scc_stat_sz; + extern unsigned struct_serial_multiport_struct_sz; + extern unsigned struct_serial_struct_sz; + extern unsigned struct_sockaddr_ax25_sz; + extern unsigned struct_unimapdesc_sz; + extern unsigned struct_unimapinit_sz; +#endif + +#if !SANITIZER_ANDROID + extern unsigned struct_sioc_sg_req_sz; + extern unsigned struct_sioc_vif_req_sz; +#endif } // namespace __sanitizer #endif + diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc index e0c8879ab..e64cac4b9 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cc @@ -326,6 +326,7 @@ void StatOutput(u64 *stat) { name[StatInt_modff] = " modff "; name[StatInt_modfl] = " modfl "; name[StatInt_getpeername] = " getpeername "; + name[StatInt_ioctl] = " ioctl "; name[StatAnnotation] = "Dynamic annotations "; name[StatAnnotateHappensBefore] = " HappensBefore "; diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h index d44aaa5e4..e30d91d0b 100644 --- a/lib/tsan/rtl/tsan_stat.h +++ b/lib/tsan/rtl/tsan_stat.h @@ -321,6 +321,7 @@ enum StatType { StatInt_modff, StatInt_modfl, StatInt_getpeername, + StatInt_ioctl, // Dynamic annotations. StatAnnotation, -- cgit v1.2.1