Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 1 | //===-- sanitizer_common_interceptors_ioctl.inc -----------------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // Ioctl handling in common sanitizer interceptors. |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "sanitizer_flags.h" |
| 14 | |
| 15 | struct ioctl_desc { |
| 16 | unsigned req; |
| 17 | // FIXME: support read+write arguments. Those are currently marked as WRITE. |
| 18 | enum { |
| 19 | NONE, |
| 20 | READ, |
| 21 | WRITE, |
| 22 | CUSTOM |
| 23 | } type : 2; |
| 24 | unsigned size : 30; |
| 25 | }; |
| 26 | |
| 27 | const unsigned ioctl_table_max = 500; |
| 28 | static ioctl_desc ioctl_table[ioctl_table_max]; |
| 29 | static unsigned ioctl_table_size = 0; |
| 30 | |
| 31 | // This can not be declared as a global, because references to struct_*_sz |
| 32 | // require a global initializer. And this table must be available before global |
| 33 | // initializers are run. |
| 34 | static void ioctl_table_fill() { |
| 35 | #define _(rq, tp, sz) \ |
| 36 | CHECK(ioctl_table_size < ioctl_table_max); \ |
| 37 | ioctl_table[ioctl_table_size].req = rq; \ |
| 38 | ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \ |
| 39 | ioctl_table[ioctl_table_size].size = sz; \ |
| 40 | ++ioctl_table_size; |
| 41 | |
| 42 | _(0x0000540C, NONE, 0); // TIOCEXCL |
| 43 | _(0x0000540D, NONE, 0); // TIOCNXCL |
| 44 | _(0x0000540E, NONE, 0); // TIOCSCTTY |
| 45 | _(0x0000540F, WRITE, pid_t_sz); // TIOCGPGRP |
| 46 | _(0x00005410, READ, pid_t_sz); // TIOCSPGRP |
| 47 | _(0x00005411, WRITE, sizeof(int)); // TIOCOUTQ |
| 48 | _(0x00005412, READ, sizeof(char)); // TIOCSTI |
| 49 | _(0x00005413, WRITE, struct_winsize_sz); // TIOCGWINSZ |
| 50 | _(0x00005414, READ, struct_winsize_sz); // TIOCSWINSZ |
| 51 | _(0x00005415, WRITE, sizeof(int)); // TIOCMGET |
| 52 | _(0x00005416, READ, sizeof(int)); // TIOCMBIS |
| 53 | _(0x00005417, READ, sizeof(int)); // TIOCMBIC |
| 54 | _(0x00005418, READ, sizeof(int)); // TIOCMSET |
| 55 | _(0x0000541D, NONE, 0); // TIOCCONS |
| 56 | _(0x00005420, READ, sizeof(int)); // TIOCPKT |
| 57 | _(0x00005421, READ, sizeof(int)); // FIONBIO |
| 58 | _(0x00005422, NONE, 0); // TIOCNOTTY |
| 59 | _(0x00005423, READ, sizeof(int)); // TIOCSETD |
| 60 | _(0x00005424, WRITE, sizeof(int)); // TIOCGETD |
| 61 | _(0x00005450, NONE, 0); // FIONCLEX |
| 62 | _(0x00005451, NONE, 0); // FIOCLEX |
| 63 | _(0x00005452, READ, sizeof(int)); // FIOASYNC |
| 64 | _(0x00008901, READ, sizeof(int)); // FIOSETOWN |
| 65 | _(0x00008902, READ, sizeof(int)); // SIOCSPGRP |
| 66 | _(0x00008903, WRITE, sizeof(int)); // FIOGETOWN |
| 67 | _(0x00008904, WRITE, sizeof(int)); // SIOCGPGRP |
| 68 | _(0x00008905, WRITE, sizeof(int)); // SIOCATMAR |
| 69 | _(0x00008912, WRITE, struct_ifconf_sz); // SIOCGIFCONF |
| 70 | _(0x00008913, WRITE, struct_ifreq_sz); // SIOCGIFFLAGS |
| 71 | _(0x00008914, READ, struct_ifreq_sz); // SIOCSIFFLAGS |
| 72 | _(0x00008915, WRITE, struct_ifreq_sz); // SIOCGIFADDR |
| 73 | _(0x00008916, READ, struct_ifreq_sz); // SIOCSIFADDR |
| 74 | _(0x00008917, WRITE, struct_ifreq_sz); // SIOCGIFDSTADDR |
| 75 | _(0x00008918, READ, struct_ifreq_sz); // SIOCSIFDSTADDR |
| 76 | _(0x00008919, WRITE, struct_ifreq_sz); // SIOCGIFBRDADDR |
| 77 | _(0x0000891A, READ, struct_ifreq_sz); // SIOCSIFBRDADDR |
| 78 | _(0x0000891B, WRITE, struct_ifreq_sz); // SIOCGIFNETMASK |
| 79 | _(0x0000891C, READ, struct_ifreq_sz); // SIOCSIFNETMASK |
| 80 | _(0x0000891D, WRITE, struct_ifreq_sz); // SIOCGIFMETRIC |
| 81 | _(0x0000891E, READ, struct_ifreq_sz); // SIOCSIFMETRIC |
| 82 | _(0x00008921, WRITE, struct_ifreq_sz); // SIOCGIFMTU |
| 83 | _(0x00008922, READ, struct_ifreq_sz); // SIOCSIFMTU |
| 84 | _(0x00008931, READ, struct_ifreq_sz); // SIOCADDMULTI |
| 85 | _(0x00008932, READ, struct_ifreq_sz); // SIOCDELMULTI |
| 86 | _(0x00008940, NONE, 0); // SIOCADDRTOLD |
| 87 | _(0x00008941, NONE, 0); // SIOCDELRTOLD |
Evgeniy Stepanov | 4ce6f79 | 2013-06-07 14:56:54 +0000 | [diff] [blame^] | 88 | |
| 89 | #if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_MAC |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 90 | _(0x000089E0, WRITE, struct_sioc_vif_req_sz); // SIOCGETVIFCNT |
| 91 | _(0x000089E1, WRITE, struct_sioc_sg_req_sz); // SIOCGETSGCNT |
Evgeniy Stepanov | 4ce6f79 | 2013-06-07 14:56:54 +0000 | [diff] [blame^] | 92 | #endif |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 93 | |
| 94 | #if SANITIZER_LINUX |
| 95 | _(0x00000000, NONE, 0); // FDCLRPRM |
| 96 | _(0x00000001, READ, struct_floppy_struct_sz); // FDSETPRM |
| 97 | _(0x00000002, READ, struct_floppy_struct_sz); // FDDEFPRM |
| 98 | _(0x00000003, WRITE, struct_floppy_struct_sz); // FDGETPRM |
| 99 | _(0x00000004, NONE, 0); // FDMSGON |
| 100 | _(0x00000005, NONE, 0); // FDMSGOFF |
| 101 | _(0x00000006, NONE, 0); // FDFMTBEG |
| 102 | _(0x00000007, READ, struct_format_descr_sz); // FDFMTTRK |
| 103 | _(0x00000008, NONE, 0); // FDFMTEND |
| 104 | _(0x0000000A, NONE, 0); // FDSETEMSGTRESH |
| 105 | _(0x0000000B, NONE, 0); // FDFLUSH |
| 106 | _(0x0000000C, READ, struct_floppy_max_errors_sz); // FDSETMAXERRS |
| 107 | _(0x0000000E, WRITE, struct_floppy_max_errors_sz); // FDGETMAXERRS |
| 108 | _(0x00000010, WRITE, 16); // FDGETDRVTYP |
| 109 | _(0x00000014, READ, struct_floppy_drive_params_sz); // FDSETDRVPRM |
| 110 | _(0x00000015, WRITE, struct_floppy_drive_params_sz); // FDGETDRVPRM |
| 111 | _(0x00000016, WRITE, struct_floppy_drive_struct_sz); // FDGETDRVSTAT |
| 112 | _(0x00000017, WRITE, struct_floppy_drive_struct_sz); // FDPOLLDRVSTAT |
| 113 | _(0x00000018, NONE, 0); // FDRESET |
| 114 | _(0x00000019, WRITE, struct_floppy_fdc_state_sz); // FDGETFDCSTAT |
| 115 | _(0x0000001B, NONE, 0); // FDWERRORCLR |
| 116 | _(0x0000001C, WRITE, struct_floppy_write_errors_sz); // FDWERRORGET |
| 117 | _(0x0000001E, WRITE, struct_floppy_raw_cmd_sz); // FDRAWCMD |
| 118 | _(0x00000028, NONE, 0); // FDTWADDLE |
| 119 | _(0x00000301, WRITE, struct_hd_geometry_sz); // HDIO_GETGEO |
| 120 | _(0x00000302, WRITE, sizeof(int)); // HDIO_GET_UNMASKINTR |
| 121 | _(0x00000304, WRITE, sizeof(int)); // HDIO_GET_MULTCOUNT |
| 122 | _(0x00000307, WRITE, struct_hd_driveid_sz); // HDIO_GET_IDENTITY |
| 123 | _(0x00000308, WRITE, sizeof(int)); // HDIO_GET_KEEPSETTINGS |
| 124 | _(0x00000309, WRITE, sizeof(int)); // HDIO_GET_CHIPSET |
| 125 | _(0x0000030A, WRITE, sizeof(int)); // HDIO_GET_NOWERR |
| 126 | _(0x0000030B, WRITE, sizeof(int)); // HDIO_GET_DMA |
| 127 | _(0x0000031F, WRITE, sizeof(int)); // HDIO_DRIVE_CMD |
| 128 | _(0x00000321, NONE, 0); // HDIO_SET_MULTCOUNT |
| 129 | _(0x00000322, NONE, 0); // HDIO_SET_UNMASKINTR |
| 130 | _(0x00000323, NONE, 0); // HDIO_SET_KEEPSETTINGS |
| 131 | _(0x00000324, NONE, 0); // HDIO_SET_CHIPSET |
| 132 | _(0x00000325, NONE, 0); // HDIO_SET_NOWERR |
| 133 | _(0x00000326, NONE, 0); // HDIO_SET_DMA |
| 134 | _(0x00000601, NONE, 0); // LPCHAR |
| 135 | _(0x00000602, NONE, 0); // LPTIME |
| 136 | _(0x00000604, NONE, 0); // LPABORT |
| 137 | _(0x00000605, NONE, 0); // LPSETIRQ |
| 138 | _(0x00000606, WRITE, sizeof(int)); // LPGETIRQ |
| 139 | _(0x00000608, NONE, 0); // LPWAIT |
| 140 | _(0x00000609, NONE, 0); // LPCAREFUL |
| 141 | _(0x0000060A, NONE, 0); // LPABORTOPEN |
| 142 | _(0x0000060B, WRITE, sizeof(int)); // LPGETSTATUS |
| 143 | _(0x0000060C, NONE, 0); // LPRESET |
| 144 | _(0x0000125D, READ, sizeof(int)); // BLKROSET |
| 145 | _(0x0000125E, WRITE, sizeof(int)); // BLKROGET |
| 146 | _(0x0000125F, NONE, 0); // BLKRRPART |
| 147 | _(0x00001260, WRITE, sizeof(uptr)); // BLKGETSIZE |
| 148 | _(0x00001261, NONE, 0); // BLKFLSBUF |
| 149 | _(0x00001262, NONE, 0); // BLKRASET |
| 150 | _(0x00001263, WRITE, sizeof(int)); // BLKRAGET |
| 151 | _(0x00004300, NONE, 0); // SNDCTL_COPR_RESET |
| 152 | _(0x00005000, NONE, 0); // SNDCTL_DSP_RESET |
| 153 | _(0x00005001, NONE, 0); // SNDCTL_DSP_SYNC |
| 154 | _(0x00005008, NONE, 0); // SNDCTL_DSP_POST |
| 155 | _(0x0000500E, NONE, 0); // SNDCTL_DSP_NONBLOCK |
| 156 | _(0x00005100, NONE, 0); // SNDCTL_SEQ_RESET |
| 157 | _(0x00005101, NONE, 0); // SNDCTL_SEQ_SYNC |
| 158 | _(0x00005111, NONE, 0); // SNDCTL_SEQ_PANIC |
| 159 | _(0x00005301, NONE, 0); // CDROMPAUSE |
| 160 | _(0x00005302, NONE, 0); // CDROMRESUME |
| 161 | _(0x00005303, READ, struct_cdrom_msf_sz); // CDROMPLAYMSF |
| 162 | _(0x00005304, READ, struct_cdrom_ti_sz); // CDROMPLAYTRKIND |
| 163 | _(0x00005305, WRITE, struct_cdrom_tochdr_sz); // CDROMREADTOCHDR |
| 164 | _(0x00005306, WRITE, struct_cdrom_tocentry_sz); // CDROMREADTOCENTRY |
| 165 | _(0x00005307, NONE, 0); // CDROMSTOP |
| 166 | _(0x00005308, NONE, 0); // CDROMSTART |
| 167 | _(0x00005309, NONE, 0); // CDROMEJECT |
| 168 | _(0x0000530A, READ, struct_cdrom_volctrl_sz); // CDROMVOLCTRL |
| 169 | _(0x0000530B, WRITE, struct_cdrom_subchnl_sz); // CDROMSUBCHNL |
| 170 | _(0x0000530C, READ, struct_cdrom_msf_sz); // CDROMREADMODE2 |
| 171 | _(0x0000530D, READ, struct_cdrom_msf_sz); // CDROMREADMODE1 |
| 172 | _(0x0000530E, READ, struct_cdrom_read_audio_sz); // CDROMREADAUDIO |
| 173 | _(0x0000530F, NONE, 0); // CDROMEJECT_SW |
| 174 | _(0x00005310, WRITE, struct_cdrom_multisession_sz); // CDROMMULTISESSION |
| 175 | _(0x00005311, WRITE, 8); // CDROM_GET_UPC |
| 176 | _(0x00005312, NONE, 0); // CDROMRESET |
| 177 | _(0x00005313, WRITE, struct_cdrom_volctrl_sz); // CDROMVOLREAD |
| 178 | _(0x00005314, READ, struct_cdrom_msf_sz); // CDROMREADRAW |
| 179 | _(0x00005315, READ, struct_cdrom_msf_sz); // CDROMREADCOOKED |
| 180 | _(0x00005316, READ, struct_cdrom_msf_sz); // CDROMSEEK |
| 181 | // Conflicting request id. |
| 182 | // _(0x00005382, NONE, 0); // CDROMAUDIOBUFSIZ |
| 183 | // _(0x00005382, WRITE, 2 * sizeof(int)); // SCSI_IOCTL_GET_IDLUN |
| 184 | _(0x00005383, NONE, 0); // SCSI_IOCTL_TAGGED_ENABLE |
| 185 | _(0x00005384, NONE, 0); // SCSI_IOCTL_TAGGED_DISABLE |
| 186 | _(0x00005385, READ, sizeof(int)); // SCSI_IOCTL_PROBE_HOST |
| 187 | _(0x00005401, WRITE, struct_termios_sz); // TCGETS |
| 188 | _(0x00005402, READ, struct_termios_sz); // TCSETS |
| 189 | _(0x00005403, READ, struct_termios_sz); // TCSETSW |
| 190 | _(0x00005404, READ, struct_termios_sz); // TCSETSF |
| 191 | _(0x00005405, WRITE, struct_termio_sz); // TCGETA |
| 192 | _(0x00005406, READ, struct_termio_sz); // TCSETA |
| 193 | _(0x00005407, READ, struct_termio_sz); // TCSETAW |
| 194 | _(0x00005408, READ, struct_termio_sz); // TCSETAF |
| 195 | _(0x00005409, NONE, 0); // TCSBRK |
| 196 | _(0x0000540A, NONE, 0); // TCXONC |
| 197 | _(0x0000540B, NONE, 0); // TCFLSH |
| 198 | // Conflicting request id. |
| 199 | // _(0x00005402, NONE, 0); // SNDCTL_TMR_START |
| 200 | // _(0x00005403, NONE, 0); // SNDCTL_TMR_STOP |
| 201 | // _(0x00005404, NONE, 0); // SNDCTL_TMR_CONTINUE |
| 202 | _(0x00005419, WRITE, sizeof(int)); // TIOCGSOFTCAR |
| 203 | _(0x0000541A, READ, sizeof(int)); // TIOCSSOFTCAR |
| 204 | _(0x0000541B, WRITE, sizeof(int)); // TIOCINQ |
| 205 | _(0x0000541C, READ, sizeof(char)); // TIOCLINUX |
| 206 | _(0x00005425, NONE, 0); // TCSBRKP |
| 207 | _(0x00005453, NONE, 0); // TIOCSERCONFIG |
| 208 | _(0x00005454, WRITE, sizeof(int)); // TIOCSERGWILD |
| 209 | _(0x00005455, READ, sizeof(int)); // TIOCSERSWILD |
| 210 | _(0x00005456, WRITE, struct_termios_sz); // TIOCGLCKTRMIOS |
| 211 | _(0x00005457, READ, struct_termios_sz); // TIOCSLCKTRMIOS |
| 212 | _(0x00005459, WRITE, sizeof(int)); // TIOCSERGETLSR |
| 213 | _(0x00005470, NONE, 0); // TIOCSCCINI |
| 214 | _(0x00005490, WRITE, sizeof(int)); // PPPIOCGFLAGS |
| 215 | _(0x00005491, READ, sizeof(int)); // PPPIOCSFLAGS |
| 216 | _(0x00005492, WRITE, sizeof(int)); // PPPIOCGASYNCMAP |
| 217 | _(0x00005493, READ, sizeof(int)); // PPPIOCSASYNCMAP |
| 218 | _(0x00005494, WRITE, sizeof(int)); // PPPIOCGUNIT |
| 219 | _(0x00005495, READ, sizeof(int)); // PPPIOCSINPSIG |
| 220 | _(0x00005497, READ, sizeof(int)); // PPPIOCSDEBUG |
| 221 | _(0x00005498, WRITE, sizeof(int)); // PPPIOCGDEBUG |
| 222 | _(0x0000549B, WRITE, sizeof(int) * 8); // PPPIOCGXASYNCMAP |
| 223 | _(0x0000549C, READ, sizeof(int) * 8); // PPPIOCSXASYNCMAP |
| 224 | _(0x0000549D, READ, sizeof(int)); // PPPIOCSMRU |
| 225 | _(0x0000549E, READ, sizeof(int)); // PPPIOCRASYNCMAP |
| 226 | _(0x0000549F, READ, sizeof(int)); // PPPIOCSMAXCID |
| 227 | _(0x00005600, WRITE, sizeof(int)); // VT_OPENQRY |
| 228 | _(0x00005601, WRITE, struct_vt_mode_sz); // VT_GETMODE |
| 229 | _(0x00005602, READ, struct_vt_mode_sz); // VT_SETMODE |
| 230 | _(0x00005603, WRITE, struct_vt_stat_sz); // VT_GETSTATE |
| 231 | _(0x00005604, NONE, 0); // VT_SENDSIG |
| 232 | _(0x00005605, NONE, 0); // VT_RELDISP |
| 233 | _(0x00005606, NONE, 0); // VT_ACTIVATE |
| 234 | _(0x00005607, NONE, 0); // VT_WAITACTIVE |
| 235 | _(0x00005608, NONE, 0); // VT_DISALLOCATE |
| 236 | _(0x00005609, READ, struct_vt_sizes_sz); // VT_RESIZE |
| 237 | _(0x0000560A, READ, struct_vt_consize_sz); // VT_RESIZEX |
| 238 | _(0x00007314, NONE, 0); // STL_BINTR |
| 239 | _(0x00007315, NONE, 0); // STL_BSTART |
| 240 | _(0x00007316, NONE, 0); // STL_BSTOP |
| 241 | _(0x00007317, NONE, 0); // STL_BRESET |
| 242 | _(0x00008906, WRITE, timeval_sz); // SIOCGSTAMP |
| 243 | _(0x0000890B, READ, struct_rtentry_sz); // SIOCADDRT |
| 244 | _(0x0000890C, READ, struct_rtentry_sz); // SIOCDELRT |
| 245 | _(0x00008910, NONE, 0); // SIOCGIFNAME |
| 246 | _(0x00008911, NONE, 0); // SIOCSIFLINK |
| 247 | _(0x0000891F, WRITE, struct_ifreq_sz); // SIOCGIFMEM |
| 248 | _(0x00008920, READ, struct_ifreq_sz); // SIOCSIFMEM |
| 249 | _(0x00008923, WRITE, struct_ifreq_sz); // OLD_SIOCGIFHWADDR |
| 250 | _(0x00008924, READ, struct_ifreq_sz); // SIOCSIFHWADDR |
| 251 | _(0x00008925, WRITE, sizeof(int)); // SIOCGIFENCAP |
| 252 | _(0x00008926, READ, sizeof(int)); // SIOCSIFENCAP |
| 253 | _(0x00008927, WRITE, struct_ifreq_sz); // SIOCGIFHWADDR |
| 254 | _(0x00008929, NONE, 0); // SIOCGIFSLAVE |
| 255 | _(0x00008930, NONE, 0); // SIOCSIFSLAVE |
| 256 | _(0x00008950, READ, struct_arpreq_sz); // SIOCDARP |
| 257 | _(0x00008951, WRITE, struct_arpreq_sz); // SIOCGARP |
| 258 | _(0x00008952, READ, struct_arpreq_sz); // SIOCSARP |
| 259 | _(0x00008960, READ, struct_arpreq_sz); // SIOCDRARP |
| 260 | _(0x00008961, WRITE, struct_arpreq_sz); // SIOCGRARP |
| 261 | _(0x00008962, READ, struct_arpreq_sz); // SIOCSRARP |
| 262 | _(0x00008970, WRITE, struct_ifreq_sz); // SIOCGIFMAP |
| 263 | _(0x00008971, READ, struct_ifreq_sz); // SIOCSIFMAP |
| 264 | _(0x000089F0, WRITE, struct_ifreq_sz); // SIOCDEVPLIP and EQL_ENSLAVE |
| 265 | _(0x000089F1, WRITE, struct_ifreq_sz); // EQL_EMANCIPATE |
| 266 | _(0x000089F2, WRITE, struct_ifreq_sz); // EQL_GETSLAVECFG |
| 267 | _(0x000089F3, WRITE, struct_ifreq_sz); // EQL_SETSLAVECFG |
| 268 | _(0x000089F4, WRITE, struct_ifreq_sz); // EQL_GETMASTRCFG |
| 269 | _(0x000089F5, WRITE, struct_ifreq_sz); // EQL_SETMASTRCFG |
| 270 | _(0x00009000, READ, sizeof(int)); // DDIOCSDBG |
| 271 | _(0x40045106, NONE, 0); // SNDCTL_SEQ_PERCMODE |
| 272 | _(0x40045108, READ, sizeof(int)); // SNDCTL_SEQ_TESTMIDI |
| 273 | _(0x40045109, READ, sizeof(int)); // SNDCTL_SEQ_RESETSAMPLES |
| 274 | _(0x4004510D, READ, sizeof(int)); // SNDCTL_SEQ_THRESHOLD |
| 275 | _(0x4004510F, READ, sizeof(int)); // SNDCTL_FM_4OP_ENABLE |
| 276 | _(0x40045407, READ, sizeof(int)); // SNDCTL_TMR_METRONOME |
| 277 | _(0x40045408, WRITE, sizeof(int)); // SNDCTL_TMR_SELECT |
| 278 | _(0x40046602, READ, sizeof(int)); // EXT2_IOC_SETFLAGS |
| 279 | _(0x40047602, READ, sizeof(int)); // EXT2_IOC_SETVERSION |
| 280 | _(0x40085112, READ, struct_seq_event_rec_sz); // SNDCTL_SEQ_OUTOFBAND |
| 281 | _(0x40086D01, READ, struct_mtop_sz); // MTIOCTOP |
| 282 | _(0x40144304, READ, struct_copr_debug_buf_sz); // SNDCTL_COPR_WDATA |
| 283 | _(0x40144305, READ, struct_copr_debug_buf_sz); // SNDCTL_COPR_WCODE |
| 284 | _(0x40285107, READ, struct_sbi_instrument_sz); // SNDCTL_FM_LOAD_INSTR |
| 285 | _(0x4FA44308, READ, struct_copr_msg_sz); // SNDCTL_COPR_SENDMSG |
| 286 | _(0x80027501, WRITE, uid_t_sz); // SMB_IOC_GETMOUNTUID |
| 287 | _(0x80044D00, WRITE, sizeof(int)); // SOUND_MIXER_READ_VOLUME |
| 288 | _(0x80044D01, WRITE, sizeof(int)); // SOUND_MIXER_READ_BASS |
| 289 | _(0x80044D02, WRITE, sizeof(int)); // SOUND_MIXER_READ_TREBLE |
| 290 | _(0x80044D03, WRITE, sizeof(int)); // SOUND_MIXER_READ_SYNTH |
| 291 | _(0x80044D04, WRITE, sizeof(int)); // SOUND_MIXER_READ_PCM |
| 292 | _(0x80044D05, WRITE, sizeof(int)); // SOUND_MIXER_READ_SPEAKER |
| 293 | _(0x80044D06, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE |
| 294 | _(0x80044D07, WRITE, sizeof(int)); // SOUND_MIXER_READ_MIC |
| 295 | _(0x80044D08, WRITE, sizeof(int)); // SOUND_MIXER_READ_CD |
| 296 | _(0x80044D09, WRITE, sizeof(int)); // SOUND_MIXER_READ_IMIX |
| 297 | _(0x80044D0A, WRITE, sizeof(int)); // SOUND_MIXER_READ_ALTPCM |
| 298 | _(0x80044D0B, WRITE, sizeof(int)); // SOUND_MIXER_READ_RECLEV |
| 299 | _(0x80044D0C, WRITE, sizeof(int)); // SOUND_MIXER_READ_IGAIN |
| 300 | _(0x80044D0D, WRITE, sizeof(int)); // SOUND_MIXER_READ_OGAIN |
| 301 | _(0x80044D0E, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE1 |
| 302 | _(0x80044D0F, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE2 |
| 303 | _(0x80044D10, WRITE, sizeof(int)); // SOUND_MIXER_READ_LINE3 |
| 304 | _(0x80044D1C, WRITE, sizeof(int)); // SOUND_MIXER_READ_MUTE |
| 305 | _(0x80044D1D, WRITE, sizeof(int)); // SOUND_MIXER_READ_ENHANCE |
| 306 | _(0x80044D1E, WRITE, sizeof(int)); // SOUND_MIXER_READ_LOUD |
| 307 | _(0x80044DFB, WRITE, sizeof(int)); // SOUND_MIXER_READ_STEREODEVS |
| 308 | _(0x80044DFC, WRITE, sizeof(int)); // SOUND_MIXER_READ_CAPS |
| 309 | _(0x80044DFD, WRITE, sizeof(int)); // SOUND_MIXER_READ_RECMASK |
| 310 | _(0x80044DFE, WRITE, sizeof(int)); // SOUND_MIXER_READ_DEVMASK |
| 311 | _(0x80044DFF, WRITE, sizeof(int)); // SOUND_MIXER_READ_RECSRC |
| 312 | _(0x80045002, WRITE, sizeof(int)); // SOUND_PCM_READ_RATE |
| 313 | _(0x80045005, WRITE, sizeof(int)); // SOUND_PCM_READ_BITS |
| 314 | _(0x80045006, WRITE, sizeof(int)); // SOUND_PCM_READ_CHANNELS |
| 315 | _(0x80045007, WRITE, sizeof(int)); // SOUND_PCM_READ_FILTER |
| 316 | _(0x8004500B, WRITE, sizeof(int)); // SNDCTL_DSP_GETFMTS |
| 317 | _(0x80045104, WRITE, sizeof(int)); // SNDCTL_SEQ_GETOUTCOUNT |
| 318 | _(0x80045105, WRITE, sizeof(int)); // SNDCTL_SEQ_GETINCOUNT |
| 319 | _(0x8004510A, WRITE, sizeof(int)); // SNDCTL_SEQ_NRSYNTHS |
| 320 | _(0x8004510B, WRITE, sizeof(int)); // SNDCTL_SEQ_NRMIDIS |
| 321 | _(0x80046601, WRITE, sizeof(int)); // EXT2_IOC_GETFLAGS |
| 322 | _(0x80046D03, WRITE, struct_mtpos_sz); // MTIOCPOS |
| 323 | _(0x80047601, WRITE, sizeof(int)); // EXT2_IOC_GETVERSION |
| 324 | _(0x801C6D02, WRITE, struct_mtget_sz); // MTIOCGET |
| 325 | _(0x8FA44309, WRITE, struct_copr_msg_sz); // SNDCTL_COPR_RCVMSG |
| 326 | _(0xC0044D00, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_VOLUME |
| 327 | _(0xC0044D01, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_BASS |
| 328 | _(0xC0044D02, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_TREBLE |
| 329 | _(0xC0044D03, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_SYNTH |
| 330 | _(0xC0044D04, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_PCM |
| 331 | _(0xC0044D05, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_SPEAKER |
| 332 | _(0xC0044D06, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE |
| 333 | _(0xC0044D07, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_MIC |
| 334 | _(0xC0044D08, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_CD |
| 335 | _(0xC0044D09, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_IMIX |
| 336 | _(0xC0044D0A, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_ALTPCM |
| 337 | _(0xC0044D0B, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_RECLEV |
| 338 | _(0xC0044D0C, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_IGAIN |
| 339 | _(0xC0044D0D, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_OGAIN |
| 340 | _(0xC0044D0E, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE1 |
| 341 | _(0xC0044D0F, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE2 |
| 342 | _(0xC0044D10, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LINE3 |
| 343 | _(0xC0044D1C, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_MUTE |
| 344 | _(0xC0044D1D, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_ENHANCE |
| 345 | _(0xC0044D1E, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_LOUD |
| 346 | _(0xC0044DFF, WRITE, sizeof(int)); // SOUND_MIXER_WRITE_RECSRC |
| 347 | _(0xC0045002, WRITE, sizeof(int)); // SNDCTL_DSP_SPEED |
| 348 | _(0xC0045003, WRITE, sizeof(int)); // SNDCTL_DSP_STEREO |
| 349 | _(0xC0045004, WRITE, sizeof(int)); // SNDCTL_DSP_GETBLKSIZE |
| 350 | _(0xC0045005, WRITE, sizeof(int)); // SNDCTL_DSP_SETFMT |
| 351 | _(0xC0045006, WRITE, sizeof(int)); // SOUND_PCM_WRITE_CHANNELS |
| 352 | _(0xC0045007, WRITE, sizeof(int)); // SOUND_PCM_WRITE_FILTER |
| 353 | _(0xC0045009, WRITE, sizeof(int)); // SNDCTL_DSP_SUBDIVIDE |
| 354 | _(0xC004500A, WRITE, sizeof(int)); // SNDCTL_DSP_SETFRAGMENT |
| 355 | _(0xC0045103, WRITE, sizeof(int)); // SNDCTL_SEQ_CTRLRATE |
| 356 | _(0xC004510E, WRITE, sizeof(int)); // SNDCTL_SYNTH_MEMAVL |
| 357 | _(0xC0045401, WRITE, sizeof(int)); // SNDCTL_TMR_TIMEBASE |
| 358 | _(0xC0045405, WRITE, sizeof(int)); // SNDCTL_TMR_TEMPO |
| 359 | _(0xC0045406, WRITE, sizeof(int)); // SNDCTL_TMR_SOURCE |
| 360 | _(0xC0046D00, WRITE, sizeof(int)); // SNDCTL_MIDI_PRETIME |
| 361 | _(0xC0046D01, READ, sizeof(int)); // SNDCTL_MIDI_MPUMODE |
| 362 | _(0xC0144302, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_RDATA |
| 363 | _(0xC0144303, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_RCODE |
| 364 | _(0xC0144306, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_RUN |
| 365 | _(0xC0144307, WRITE, struct_copr_debug_buf_sz); // SNDCTL_COPR_HALT |
| 366 | _(0xC074510C, WRITE, struct_midi_info_sz); // SNDCTL_MIDI_INFO |
| 367 | _(0xC08C5102, WRITE, struct_synth_info_sz); // SNDCTL_SYNTH_INFO |
| 368 | _(0xCFB04301, READ, struct_copr_buffer_sz); // SNDCTL_COPR_LOAD |
| 369 | #endif |
| 370 | |
| 371 | #if SANITIZER_LINUX && !SANITIZER_ANDROID |
| 372 | _(0x00005499, WRITE, struct_ppp_stats_sz); // PPPIOCGSTAT |
| 373 | |
| 374 | _(0x00004B2F, NONE, 0); // KIOCSOUND |
| 375 | _(0x00004B30, NONE, 0); // KDMKTONE |
| 376 | _(0x00004B31, WRITE, 1); // KDGETLED |
| 377 | _(0x00004B32, NONE, 0); // KDSETLED |
| 378 | _(0x00004B33, WRITE, 1); // KDGKBTYPE |
| 379 | _(0x00004B34, NONE, 0); // KDADDIO |
| 380 | _(0x00004B35, NONE, 0); // KDDELIO |
| 381 | _(0x00004B36, NONE, 0); // KDENABIO |
| 382 | _(0x00004B37, NONE, 0); // KDDISABIO |
| 383 | _(0x00004B3A, NONE, 0); // KDSETMODE |
| 384 | _(0x00004B3B, WRITE, sizeof(int)); // KDGETMODE |
| 385 | _(0x00004B3C, NONE, 0); // KDMAPDISP |
| 386 | _(0x00004B3D, NONE, 0); // KDUNMAPDISP |
| 387 | _(0x00004B40, WRITE, e_tabsz); // GIO_SCRNMAP |
| 388 | _(0x00004B41, READ, e_tabsz); // PIO_SCRNMAP |
| 389 | _(0x00004B44, WRITE, sizeof(int)); // KDGKBMODE |
| 390 | _(0x00004B45, NONE, 0); // KDSKBMODE |
| 391 | _(0x00004B46, WRITE, struct_kbentry_sz); // KDGKBENT |
| 392 | _(0x00004B47, READ, struct_kbentry_sz); // KDSKBENT |
| 393 | _(0x00004B48, WRITE, struct_kbsentry_sz); // KDGKBSENT |
| 394 | _(0x00004B49, READ, struct_kbsentry_sz); // KDSKBSENT |
| 395 | _(0x00004B4A, WRITE, struct_kbdiacrs_sz); // KDGKBDIACR |
| 396 | _(0x00004B4B, READ, struct_kbdiacrs_sz); // KDSKBDIACR |
| 397 | _(0x00004B4C, WRITE, struct_kbkeycode_sz); // KDGETKEYCODE |
| 398 | _(0x00004B4D, READ, struct_kbkeycode_sz); // KDSETKEYCODE |
| 399 | _(0x00004B4E, NONE, 0); // KDSIGACCEPT |
| 400 | _(0x00004B60, WRITE, 8192); // GIO_FONT |
| 401 | _(0x00004B61, READ, 8192); // PIO_FONT |
| 402 | _(0x00004B62, WRITE, sizeof(int)); // KDGKBMETA |
| 403 | _(0x00004B63, NONE, 0); // KDSKBMETA |
| 404 | _(0x00004B64, WRITE, sizeof(int)); // KDGKBLED |
| 405 | _(0x00004B65, NONE, 0); // KDSKBLED |
| 406 | _(0x00004B66, WRITE, struct_unimapdesc_sz); // GIO_UNIMAP |
| 407 | _(0x00004B67, READ, struct_unimapdesc_sz); // PIO_UNIMAP |
| 408 | _(0x00004B68, READ, struct_unimapinit_sz); // PIO_UNIMAPCLR |
| 409 | _(0x00004B69, WRITE, sizeof(short) * e_tabsz); // GIO_UNISCRNMAP |
| 410 | _(0x00004B6A, READ, sizeof(short) * e_tabsz); // PIO_UNISCRNMAP |
| 411 | _(0x00004B70, WRITE, 48); // GIO_CMAP |
| 412 | _(0x00004B71, NONE, 0); // PIO_CMAP |
| 413 | |
| 414 | // Missing struct definition on Android. |
| 415 | _(0x0000541E, WRITE, struct_serial_struct_sz); // TIOCGSERIAL |
| 416 | _(0x0000541F, READ, struct_serial_struct_sz); // TIOCSSERIAL |
| 417 | _(0x0000545A, WRITE, struct_serial_multiport_struct_sz); // TIOCSERGETMULTI |
| 418 | _(0x0000545B, READ, struct_serial_multiport_struct_sz); // TIOCSERSETMULTI |
| 419 | _(0x00005471, READ, struct_scc_modem_sz); // TIOCCHANINI |
| 420 | _(0x00005474, WRITE, struct_scc_stat_sz); // TIOCSCCSTAT |
| 421 | |
| 422 | // The following ioctl requests are shared between AX25, IPX, netrom and |
| 423 | // mrouted. |
| 424 | // _(0x000089E0, READ, sizeof(char)); // SIOCAIPXITFCRT |
| 425 | // _(0x000089E0, READ, struct_sockaddr_ax25_sz); // SIOCAX25GETUID |
| 426 | // _(0x000089E0, WRITE, struct_nr_parms_struct_sz); // SIOCNRGETPARMS |
| 427 | // _(0x000089E1, READ, sizeof(char)); // SIOCAIPXPRISLT |
| 428 | // _(0x000089E1, READ, struct_nr_parms_struct_sz); // SIOCNRSETPARMS |
| 429 | // _(0x000089E1, READ, struct_sockaddr_ax25_sz); // SIOCAX25ADDUID |
| 430 | // _(0x000089E2, NONE, 0); // SIOCNRDECOBS |
| 431 | // _(0x000089E2, READ, struct_sockaddr_ax25_sz); // SIOCAX25DELUID |
| 432 | // _(0x000089E2, WRITE, struct_ipx_config_data_sz); // SIOCIPXCFGDATA |
| 433 | // _(0x000089E3, READ, sizeof(int)); // SIOCAX25NOUID |
| 434 | // _(0x000089E3, READ, sizeof(int)); // SIOCNRRTCTL |
| 435 | // _(0x000089E4, READ, sizeof(int)); // SIOCAX25DIGCTL |
| 436 | // _(0x000089E5, WRITE, struct_ax25_parms_struct_sz); // SIOCAX25GETPARMS |
| 437 | // _(0x000089E6, READ, struct_ax25_parms_struct_sz); // SIOCAX25SETPARMS |
| 438 | |
| 439 | _(0x00435901, WRITE, struct_cyclades_monitor_sz); // CYGETMON |
| 440 | _(0x00435902, WRITE, sizeof(int)); // CYGETTHRESH |
| 441 | _(0x00435903, NONE, 0); // CYSETTHRESH |
| 442 | _(0x00435904, WRITE, sizeof(int)); // CYGETDEFTHRESH |
| 443 | _(0x00435905, NONE, 0); // CYSETDEFTHRESH |
| 444 | _(0x00435906, WRITE, sizeof(int)); // CYGETTIMEOUT |
| 445 | _(0x00435907, NONE, 0); // CYSETTIMEOUT |
| 446 | _(0x00435908, WRITE, sizeof(int)); // CYGETDEFTIMEOUT |
| 447 | _(0x00435909, NONE, 0); // CYSETDEFTIMEOUT |
| 448 | |
| 449 | // Missing definition of mtconfiginfo |
| 450 | _(0x40206D05, READ, struct_mtconfiginfo_sz); // MTIOCSETCONFIG |
| 451 | _(0x80206D04, WRITE, struct_mtconfiginfo_sz); // MTIOCGETCONFIG |
| 452 | |
| 453 | _(0x800C500C, WRITE, struct_audio_buf_info_sz); // SNDCTL_DSP_GETOSPACE |
| 454 | _(0x800C500D, WRITE, struct_audio_buf_info_sz); // SNDCTL_DSP_GETISPACE |
| 455 | #endif |
| 456 | #undef _ |
| 457 | // FIXME: missing USB ioctls (EVIOxx...x). |
| 458 | } |
| 459 | |
| 460 | static bool ioctl_initialized = false; |
| 461 | |
| 462 | struct ioctl_desc_compare { |
| 463 | bool operator()(const ioctl_desc& left, const ioctl_desc& right) const { |
| 464 | return left.req < right.req; |
| 465 | } |
| 466 | }; |
| 467 | |
| 468 | static void ioctl_init() { |
| 469 | ioctl_table_fill(); |
| 470 | InternalSort(&ioctl_table, ioctl_table_size, ioctl_desc_compare()); |
| 471 | |
| 472 | for (unsigned i = 0; i < ioctl_table_size - 1; ++i) { |
| 473 | if (ioctl_table[i].req >= ioctl_table[i + 1].req) { |
| 474 | Printf("Duplicate or unsorted ioctl request id %x >= %x\n", |
| 475 | ioctl_table[i].req, ioctl_table[i + 1].req); |
| 476 | Die(); |
| 477 | } |
| 478 | } |
| 479 | |
| 480 | ioctl_initialized = true; |
| 481 | } |
| 482 | |
| 483 | static const ioctl_desc *ioctl_lookup(unsigned req) { |
| 484 | int left = 0; |
| 485 | int right = sizeof(ioctl_table) / sizeof(*ioctl_table); |
| 486 | while (left < right) { |
| 487 | int mid = (left + right) / 2; |
| 488 | if (ioctl_table[mid].req < req) |
| 489 | left = mid + 1; |
| 490 | else |
| 491 | right = mid; |
| 492 | } |
| 493 | if (left == right && ioctl_table[left].req == req) |
| 494 | return ioctl_table + left; |
| 495 | else |
| 496 | return 0; |
| 497 | } |
| 498 | |
| 499 | static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d, |
| 500 | unsigned request, void *arg) { |
| 501 | if (desc->type == ioctl_desc::READ) |
| 502 | COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, desc->size); |
| 503 | if (desc->type != ioctl_desc::CUSTOM) |
| 504 | return; |
| 505 | // FIXME: add some ioctls of "CUSTOM" type and handle them here. |
| 506 | return; |
| 507 | } |
| 508 | |
| 509 | static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d, |
| 510 | unsigned request, void *arg) { |
| 511 | if (desc->type == ioctl_desc::WRITE) { |
| 512 | // FIXME: add verbose output |
| 513 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, desc->size); |
| 514 | } |
| 515 | if (desc->type != ioctl_desc::CUSTOM) |
| 516 | return; |
| 517 | return; // FIXME |
| 518 | } |