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; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 17 | // FIXME: support read+write arguments. Currently READWRITE and WRITE do the |
| 18 | // same thing. |
| 19 | // XXX: The declarations below may use WRITE instead of READWRITE, unless |
| 20 | // explicitly noted. |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 21 | enum { |
| 22 | NONE, |
| 23 | READ, |
| 24 | WRITE, |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 25 | READWRITE, |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 26 | CUSTOM |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 27 | } type : 3; |
| 28 | unsigned size : 29; |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 29 | const char* name; |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 30 | }; |
| 31 | |
| 32 | const unsigned ioctl_table_max = 500; |
| 33 | static ioctl_desc ioctl_table[ioctl_table_max]; |
| 34 | static unsigned ioctl_table_size = 0; |
| 35 | |
| 36 | // This can not be declared as a global, because references to struct_*_sz |
| 37 | // require a global initializer. And this table must be available before global |
| 38 | // initializers are run. |
| 39 | static void ioctl_table_fill() { |
Evgeniy Stepanov | bb273d5 | 2013-06-21 10:54:57 +0000 | [diff] [blame] | 40 | #define _(rq, tp, sz) \ |
| 41 | if (IOCTL_##rq != IOCTL_NOT_PRESENT) { \ |
| 42 | CHECK(ioctl_table_size < ioctl_table_max); \ |
| 43 | ioctl_table[ioctl_table_size].req = IOCTL_##rq; \ |
| 44 | ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \ |
| 45 | ioctl_table[ioctl_table_size].size = sz; \ |
| 46 | ioctl_table[ioctl_table_size].name = #rq; \ |
| 47 | ++ioctl_table_size; \ |
| 48 | } |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 49 | |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 50 | _(FIOASYNC, READ, sizeof(int)); |
| 51 | _(FIOCLEX, NONE, 0); |
| 52 | _(FIOGETOWN, WRITE, sizeof(int)); |
| 53 | _(FIONBIO, READ, sizeof(int)); |
| 54 | _(FIONCLEX, NONE, 0); |
| 55 | _(FIOSETOWN, READ, sizeof(int)); |
| 56 | _(SIOCADDMULTI, READ, struct_ifreq_sz); |
| 57 | _(SIOCATMARK, WRITE, sizeof(int)); |
| 58 | _(SIOCDELMULTI, READ, struct_ifreq_sz); |
| 59 | _(SIOCGIFADDR, WRITE, struct_ifreq_sz); |
| 60 | _(SIOCGIFBRDADDR, WRITE, struct_ifreq_sz); |
| 61 | _(SIOCGIFCONF, CUSTOM, 0); |
| 62 | _(SIOCGIFDSTADDR, WRITE, struct_ifreq_sz); |
| 63 | _(SIOCGIFFLAGS, WRITE, struct_ifreq_sz); |
| 64 | _(SIOCGIFMETRIC, WRITE, struct_ifreq_sz); |
| 65 | _(SIOCGIFMTU, WRITE, struct_ifreq_sz); |
| 66 | _(SIOCGIFNETMASK, WRITE, struct_ifreq_sz); |
| 67 | _(SIOCGPGRP, WRITE, sizeof(int)); |
| 68 | _(SIOCSIFADDR, READ, struct_ifreq_sz); |
| 69 | _(SIOCSIFBRDADDR, READ, struct_ifreq_sz); |
| 70 | _(SIOCSIFDSTADDR, READ, struct_ifreq_sz); |
| 71 | _(SIOCSIFFLAGS, READ, struct_ifreq_sz); |
| 72 | _(SIOCSIFMETRIC, READ, struct_ifreq_sz); |
| 73 | _(SIOCSIFMTU, READ, struct_ifreq_sz); |
| 74 | _(SIOCSIFNETMASK, READ, struct_ifreq_sz); |
| 75 | _(SIOCSPGRP, READ, sizeof(int)); |
| 76 | _(TIOCCONS, NONE, 0); |
| 77 | _(TIOCEXCL, NONE, 0); |
| 78 | _(TIOCGETD, WRITE, sizeof(int)); |
| 79 | _(TIOCGPGRP, WRITE, pid_t_sz); |
| 80 | _(TIOCGWINSZ, WRITE, struct_winsize_sz); |
| 81 | _(TIOCMBIC, READ, sizeof(int)); |
| 82 | _(TIOCMBIS, READ, sizeof(int)); |
| 83 | _(TIOCMGET, WRITE, sizeof(int)); |
| 84 | _(TIOCMSET, READ, sizeof(int)); |
| 85 | _(TIOCNOTTY, NONE, 0); |
| 86 | _(TIOCNXCL, NONE, 0); |
| 87 | _(TIOCOUTQ, WRITE, sizeof(int)); |
| 88 | _(TIOCPKT, READ, sizeof(int)); |
| 89 | _(TIOCSCTTY, NONE, 0); |
| 90 | _(TIOCSETD, READ, sizeof(int)); |
| 91 | _(TIOCSPGRP, READ, pid_t_sz); |
| 92 | _(TIOCSTI, READ, sizeof(char)); |
| 93 | _(TIOCSWINSZ, READ, struct_winsize_sz); |
Evgeniy Stepanov | 4ce6f79 | 2013-06-07 14:56:54 +0000 | [diff] [blame] | 94 | |
Bob Wilson | efb0226 | 2013-11-15 19:13:08 +0000 | [diff] [blame] | 95 | #if (SANITIZER_LINUX && !SANITIZER_ANDROID) |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 96 | _(SIOCGETSGCNT, WRITE, struct_sioc_sg_req_sz); |
| 97 | _(SIOCGETVIFCNT, WRITE, struct_sioc_vif_req_sz); |
Evgeniy Stepanov | 4ce6f79 | 2013-06-07 14:56:54 +0000 | [diff] [blame] | 98 | #endif |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 99 | |
| 100 | #if SANITIZER_LINUX |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 101 | // Conflicting request ids. |
| 102 | // _(CDROMAUDIOBUFSIZ, NONE, 0); |
| 103 | // _(SNDCTL_TMR_CONTINUE, NONE, 0); |
| 104 | // _(SNDCTL_TMR_START, NONE, 0); |
| 105 | // _(SNDCTL_TMR_STOP, NONE, 0); |
| 106 | // _(SOUND_MIXER_READ_LOUD, WRITE, sizeof(int)); // same as ...READ_ENHANCE |
| 107 | // _(SOUND_MIXER_READ_MUTE, WRITE, sizeof(int)); // same as ...READ_ENHANCE |
| 108 | // _(SOUND_MIXER_WRITE_LOUD, WRITE, sizeof(int)); // same as ...WRITE_ENHANCE |
| 109 | // _(SOUND_MIXER_WRITE_MUTE, WRITE, sizeof(int)); // same as ...WRITE_ENHANCE |
| 110 | _(BLKFLSBUF, NONE, 0); |
| 111 | _(BLKGETSIZE, WRITE, sizeof(uptr)); |
| 112 | _(BLKRAGET, WRITE, sizeof(int)); |
| 113 | _(BLKRASET, NONE, 0); |
| 114 | _(BLKROGET, WRITE, sizeof(int)); |
| 115 | _(BLKROSET, READ, sizeof(int)); |
| 116 | _(BLKRRPART, NONE, 0); |
| 117 | _(CDROMEJECT, NONE, 0); |
| 118 | _(CDROMEJECT_SW, NONE, 0); |
| 119 | _(CDROMMULTISESSION, WRITE, struct_cdrom_multisession_sz); |
| 120 | _(CDROMPAUSE, NONE, 0); |
| 121 | _(CDROMPLAYMSF, READ, struct_cdrom_msf_sz); |
| 122 | _(CDROMPLAYTRKIND, READ, struct_cdrom_ti_sz); |
| 123 | _(CDROMREADAUDIO, READ, struct_cdrom_read_audio_sz); |
| 124 | _(CDROMREADCOOKED, READ, struct_cdrom_msf_sz); |
| 125 | _(CDROMREADMODE1, READ, struct_cdrom_msf_sz); |
| 126 | _(CDROMREADMODE2, READ, struct_cdrom_msf_sz); |
| 127 | _(CDROMREADRAW, READ, struct_cdrom_msf_sz); |
| 128 | _(CDROMREADTOCENTRY, WRITE, struct_cdrom_tocentry_sz); |
| 129 | _(CDROMREADTOCHDR, WRITE, struct_cdrom_tochdr_sz); |
| 130 | _(CDROMRESET, NONE, 0); |
| 131 | _(CDROMRESUME, NONE, 0); |
| 132 | _(CDROMSEEK, READ, struct_cdrom_msf_sz); |
| 133 | _(CDROMSTART, NONE, 0); |
| 134 | _(CDROMSTOP, NONE, 0); |
| 135 | _(CDROMSUBCHNL, WRITE, struct_cdrom_subchnl_sz); |
| 136 | _(CDROMVOLCTRL, READ, struct_cdrom_volctrl_sz); |
| 137 | _(CDROMVOLREAD, WRITE, struct_cdrom_volctrl_sz); |
| 138 | _(CDROM_GET_UPC, WRITE, 8); |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 139 | _(EVIOCGABS, WRITE, struct_input_absinfo_sz); // fixup |
| 140 | _(EVIOCGBIT, WRITE, struct_input_id_sz); // fixup |
| 141 | _(EVIOCGEFFECTS, WRITE, sizeof(int)); |
| 142 | _(EVIOCGID, WRITE, struct_input_id_sz); |
| 143 | _(EVIOCGKEY, WRITE, 0); |
| 144 | _(EVIOCGKEYCODE, WRITE, sizeof(int) * 2); |
| 145 | _(EVIOCGLED, WRITE, 0); |
| 146 | _(EVIOCGNAME, WRITE, 0); |
| 147 | _(EVIOCGPHYS, WRITE, 0); |
| 148 | _(EVIOCGRAB, READ, sizeof(int)); |
| 149 | _(EVIOCGREP, WRITE, sizeof(int) * 2); |
| 150 | _(EVIOCGSND, WRITE, 0); |
| 151 | _(EVIOCGSW, WRITE, 0); |
| 152 | _(EVIOCGUNIQ, WRITE, 0); |
| 153 | _(EVIOCGVERSION, WRITE, sizeof(int)); |
| 154 | _(EVIOCRMFF, READ, sizeof(int)); |
| 155 | _(EVIOCSABS, READ, struct_input_absinfo_sz); // fixup |
| 156 | _(EVIOCSFF, READ, struct_ff_effect_sz); |
| 157 | _(EVIOCSKEYCODE, READ, sizeof(int) * 2); |
| 158 | _(EVIOCSREP, READ, sizeof(int) * 2); |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 159 | _(FDCLRPRM, NONE, 0); |
| 160 | _(FDDEFPRM, READ, struct_floppy_struct_sz); |
| 161 | _(FDFLUSH, NONE, 0); |
| 162 | _(FDFMTBEG, NONE, 0); |
| 163 | _(FDFMTEND, NONE, 0); |
| 164 | _(FDFMTTRK, READ, struct_format_descr_sz); |
| 165 | _(FDGETDRVPRM, WRITE, struct_floppy_drive_params_sz); |
| 166 | _(FDGETDRVSTAT, WRITE, struct_floppy_drive_struct_sz); |
| 167 | _(FDGETDRVTYP, WRITE, 16); |
| 168 | _(FDGETFDCSTAT, WRITE, struct_floppy_fdc_state_sz); |
| 169 | _(FDGETMAXERRS, WRITE, struct_floppy_max_errors_sz); |
| 170 | _(FDGETPRM, WRITE, struct_floppy_struct_sz); |
| 171 | _(FDMSGOFF, NONE, 0); |
| 172 | _(FDMSGON, NONE, 0); |
| 173 | _(FDPOLLDRVSTAT, WRITE, struct_floppy_drive_struct_sz); |
| 174 | _(FDRAWCMD, WRITE, struct_floppy_raw_cmd_sz); |
| 175 | _(FDRESET, NONE, 0); |
| 176 | _(FDSETDRVPRM, READ, struct_floppy_drive_params_sz); |
| 177 | _(FDSETEMSGTRESH, NONE, 0); |
| 178 | _(FDSETMAXERRS, READ, struct_floppy_max_errors_sz); |
| 179 | _(FDSETPRM, READ, struct_floppy_struct_sz); |
| 180 | _(FDTWADDLE, NONE, 0); |
| 181 | _(FDWERRORCLR, NONE, 0); |
| 182 | _(FDWERRORGET, WRITE, struct_floppy_write_errors_sz); |
| 183 | _(HDIO_DRIVE_CMD, WRITE, sizeof(int)); |
| 184 | _(HDIO_GETGEO, WRITE, struct_hd_geometry_sz); |
| 185 | _(HDIO_GET_32BIT, WRITE, sizeof(int)); |
| 186 | _(HDIO_GET_DMA, WRITE, sizeof(int)); |
| 187 | _(HDIO_GET_IDENTITY, WRITE, struct_hd_driveid_sz); |
| 188 | _(HDIO_GET_KEEPSETTINGS, WRITE, sizeof(int)); |
| 189 | _(HDIO_GET_MULTCOUNT, WRITE, sizeof(int)); |
| 190 | _(HDIO_GET_NOWERR, WRITE, sizeof(int)); |
| 191 | _(HDIO_GET_UNMASKINTR, WRITE, sizeof(int)); |
| 192 | _(HDIO_SET_32BIT, NONE, 0); |
| 193 | _(HDIO_SET_DMA, NONE, 0); |
| 194 | _(HDIO_SET_KEEPSETTINGS, NONE, 0); |
| 195 | _(HDIO_SET_MULTCOUNT, NONE, 0); |
| 196 | _(HDIO_SET_NOWERR, NONE, 0); |
| 197 | _(HDIO_SET_UNMASKINTR, NONE, 0); |
| 198 | _(MTIOCGET, WRITE, struct_mtget_sz); |
| 199 | _(MTIOCPOS, WRITE, struct_mtpos_sz); |
| 200 | _(MTIOCTOP, READ, struct_mtop_sz); |
| 201 | _(PPPIOCGASYNCMAP, WRITE, sizeof(int)); |
| 202 | _(PPPIOCGDEBUG, WRITE, sizeof(int)); |
| 203 | _(PPPIOCGFLAGS, WRITE, sizeof(int)); |
| 204 | _(PPPIOCGUNIT, WRITE, sizeof(int)); |
| 205 | _(PPPIOCGXASYNCMAP, WRITE, sizeof(int) * 8); |
| 206 | _(PPPIOCSASYNCMAP, READ, sizeof(int)); |
| 207 | _(PPPIOCSDEBUG, READ, sizeof(int)); |
| 208 | _(PPPIOCSFLAGS, READ, sizeof(int)); |
| 209 | _(PPPIOCSMAXCID, READ, sizeof(int)); |
| 210 | _(PPPIOCSMRU, READ, sizeof(int)); |
| 211 | _(PPPIOCSXASYNCMAP, READ, sizeof(int) * 8); |
| 212 | _(SIOCADDRT, READ, struct_rtentry_sz); |
| 213 | _(SIOCDARP, READ, struct_arpreq_sz); |
| 214 | _(SIOCDELRT, READ, struct_rtentry_sz); |
| 215 | _(SIOCDRARP, READ, struct_arpreq_sz); |
| 216 | _(SIOCGARP, WRITE, struct_arpreq_sz); |
| 217 | _(SIOCGIFENCAP, WRITE, sizeof(int)); |
| 218 | _(SIOCGIFHWADDR, WRITE, struct_ifreq_sz); |
| 219 | _(SIOCGIFMAP, WRITE, struct_ifreq_sz); |
| 220 | _(SIOCGIFMEM, WRITE, struct_ifreq_sz); |
| 221 | _(SIOCGIFNAME, NONE, 0); |
| 222 | _(SIOCGIFSLAVE, NONE, 0); |
| 223 | _(SIOCGRARP, WRITE, struct_arpreq_sz); |
| 224 | _(SIOCGSTAMP, WRITE, timeval_sz); |
| 225 | _(SIOCSARP, READ, struct_arpreq_sz); |
| 226 | _(SIOCSIFENCAP, READ, sizeof(int)); |
| 227 | _(SIOCSIFHWADDR, READ, struct_ifreq_sz); |
| 228 | _(SIOCSIFLINK, NONE, 0); |
| 229 | _(SIOCSIFMAP, READ, struct_ifreq_sz); |
| 230 | _(SIOCSIFMEM, READ, struct_ifreq_sz); |
| 231 | _(SIOCSIFSLAVE, NONE, 0); |
| 232 | _(SIOCSRARP, READ, struct_arpreq_sz); |
| 233 | _(SNDCTL_COPR_HALT, WRITE, struct_copr_debug_buf_sz); |
| 234 | _(SNDCTL_COPR_LOAD, READ, struct_copr_buffer_sz); |
| 235 | _(SNDCTL_COPR_RCODE, WRITE, struct_copr_debug_buf_sz); |
| 236 | _(SNDCTL_COPR_RCVMSG, WRITE, struct_copr_msg_sz); |
| 237 | _(SNDCTL_COPR_RDATA, WRITE, struct_copr_debug_buf_sz); |
| 238 | _(SNDCTL_COPR_RESET, NONE, 0); |
| 239 | _(SNDCTL_COPR_RUN, WRITE, struct_copr_debug_buf_sz); |
| 240 | _(SNDCTL_COPR_SENDMSG, READ, struct_copr_msg_sz); |
| 241 | _(SNDCTL_COPR_WCODE, READ, struct_copr_debug_buf_sz); |
| 242 | _(SNDCTL_COPR_WDATA, READ, struct_copr_debug_buf_sz); |
| 243 | _(SNDCTL_DSP_GETBLKSIZE, WRITE, sizeof(int)); |
| 244 | _(SNDCTL_DSP_GETFMTS, WRITE, sizeof(int)); |
| 245 | _(SNDCTL_DSP_NONBLOCK, NONE, 0); |
| 246 | _(SNDCTL_DSP_POST, NONE, 0); |
| 247 | _(SNDCTL_DSP_RESET, NONE, 0); |
| 248 | _(SNDCTL_DSP_SETFMT, WRITE, sizeof(int)); |
| 249 | _(SNDCTL_DSP_SETFRAGMENT, WRITE, sizeof(int)); |
| 250 | _(SNDCTL_DSP_SPEED, WRITE, sizeof(int)); |
| 251 | _(SNDCTL_DSP_STEREO, WRITE, sizeof(int)); |
| 252 | _(SNDCTL_DSP_SUBDIVIDE, WRITE, sizeof(int)); |
| 253 | _(SNDCTL_DSP_SYNC, NONE, 0); |
| 254 | _(SNDCTL_FM_4OP_ENABLE, READ, sizeof(int)); |
| 255 | _(SNDCTL_FM_LOAD_INSTR, READ, struct_sbi_instrument_sz); |
| 256 | _(SNDCTL_MIDI_INFO, WRITE, struct_midi_info_sz); |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 257 | _(SNDCTL_MIDI_PRETIME, WRITE, sizeof(int)); |
| 258 | _(SNDCTL_SEQ_CTRLRATE, WRITE, sizeof(int)); |
| 259 | _(SNDCTL_SEQ_GETINCOUNT, WRITE, sizeof(int)); |
| 260 | _(SNDCTL_SEQ_GETOUTCOUNT, WRITE, sizeof(int)); |
| 261 | _(SNDCTL_SEQ_NRMIDIS, WRITE, sizeof(int)); |
| 262 | _(SNDCTL_SEQ_NRSYNTHS, WRITE, sizeof(int)); |
| 263 | _(SNDCTL_SEQ_OUTOFBAND, READ, struct_seq_event_rec_sz); |
| 264 | _(SNDCTL_SEQ_PANIC, NONE, 0); |
| 265 | _(SNDCTL_SEQ_PERCMODE, NONE, 0); |
| 266 | _(SNDCTL_SEQ_RESET, NONE, 0); |
| 267 | _(SNDCTL_SEQ_RESETSAMPLES, READ, sizeof(int)); |
| 268 | _(SNDCTL_SEQ_SYNC, NONE, 0); |
| 269 | _(SNDCTL_SEQ_TESTMIDI, READ, sizeof(int)); |
| 270 | _(SNDCTL_SEQ_THRESHOLD, READ, sizeof(int)); |
| 271 | _(SNDCTL_SYNTH_INFO, WRITE, struct_synth_info_sz); |
| 272 | _(SNDCTL_SYNTH_MEMAVL, WRITE, sizeof(int)); |
| 273 | _(SNDCTL_TMR_METRONOME, READ, sizeof(int)); |
| 274 | _(SNDCTL_TMR_SELECT, WRITE, sizeof(int)); |
| 275 | _(SNDCTL_TMR_SOURCE, WRITE, sizeof(int)); |
| 276 | _(SNDCTL_TMR_TEMPO, WRITE, sizeof(int)); |
| 277 | _(SNDCTL_TMR_TIMEBASE, WRITE, sizeof(int)); |
| 278 | _(SOUND_MIXER_READ_ALTPCM, WRITE, sizeof(int)); |
| 279 | _(SOUND_MIXER_READ_BASS, WRITE, sizeof(int)); |
| 280 | _(SOUND_MIXER_READ_CAPS, WRITE, sizeof(int)); |
| 281 | _(SOUND_MIXER_READ_CD, WRITE, sizeof(int)); |
| 282 | _(SOUND_MIXER_READ_DEVMASK, WRITE, sizeof(int)); |
| 283 | _(SOUND_MIXER_READ_ENHANCE, WRITE, sizeof(int)); |
| 284 | _(SOUND_MIXER_READ_IGAIN, WRITE, sizeof(int)); |
| 285 | _(SOUND_MIXER_READ_IMIX, WRITE, sizeof(int)); |
| 286 | _(SOUND_MIXER_READ_LINE, WRITE, sizeof(int)); |
| 287 | _(SOUND_MIXER_READ_LINE1, WRITE, sizeof(int)); |
| 288 | _(SOUND_MIXER_READ_LINE2, WRITE, sizeof(int)); |
| 289 | _(SOUND_MIXER_READ_LINE3, WRITE, sizeof(int)); |
| 290 | _(SOUND_MIXER_READ_MIC, WRITE, sizeof(int)); |
| 291 | _(SOUND_MIXER_READ_OGAIN, WRITE, sizeof(int)); |
| 292 | _(SOUND_MIXER_READ_PCM, WRITE, sizeof(int)); |
| 293 | _(SOUND_MIXER_READ_RECLEV, WRITE, sizeof(int)); |
| 294 | _(SOUND_MIXER_READ_RECMASK, WRITE, sizeof(int)); |
| 295 | _(SOUND_MIXER_READ_RECSRC, WRITE, sizeof(int)); |
| 296 | _(SOUND_MIXER_READ_SPEAKER, WRITE, sizeof(int)); |
| 297 | _(SOUND_MIXER_READ_STEREODEVS, WRITE, sizeof(int)); |
| 298 | _(SOUND_MIXER_READ_SYNTH, WRITE, sizeof(int)); |
| 299 | _(SOUND_MIXER_READ_TREBLE, WRITE, sizeof(int)); |
| 300 | _(SOUND_MIXER_READ_VOLUME, WRITE, sizeof(int)); |
| 301 | _(SOUND_MIXER_WRITE_ALTPCM, WRITE, sizeof(int)); |
| 302 | _(SOUND_MIXER_WRITE_BASS, WRITE, sizeof(int)); |
| 303 | _(SOUND_MIXER_WRITE_CD, WRITE, sizeof(int)); |
| 304 | _(SOUND_MIXER_WRITE_ENHANCE, WRITE, sizeof(int)); |
| 305 | _(SOUND_MIXER_WRITE_IGAIN, WRITE, sizeof(int)); |
| 306 | _(SOUND_MIXER_WRITE_IMIX, WRITE, sizeof(int)); |
| 307 | _(SOUND_MIXER_WRITE_LINE, WRITE, sizeof(int)); |
| 308 | _(SOUND_MIXER_WRITE_LINE1, WRITE, sizeof(int)); |
| 309 | _(SOUND_MIXER_WRITE_LINE2, WRITE, sizeof(int)); |
| 310 | _(SOUND_MIXER_WRITE_LINE3, WRITE, sizeof(int)); |
| 311 | _(SOUND_MIXER_WRITE_MIC, WRITE, sizeof(int)); |
| 312 | _(SOUND_MIXER_WRITE_OGAIN, WRITE, sizeof(int)); |
| 313 | _(SOUND_MIXER_WRITE_PCM, WRITE, sizeof(int)); |
| 314 | _(SOUND_MIXER_WRITE_RECLEV, WRITE, sizeof(int)); |
| 315 | _(SOUND_MIXER_WRITE_RECSRC, WRITE, sizeof(int)); |
| 316 | _(SOUND_MIXER_WRITE_SPEAKER, WRITE, sizeof(int)); |
| 317 | _(SOUND_MIXER_WRITE_SYNTH, WRITE, sizeof(int)); |
| 318 | _(SOUND_MIXER_WRITE_TREBLE, WRITE, sizeof(int)); |
| 319 | _(SOUND_MIXER_WRITE_VOLUME, WRITE, sizeof(int)); |
| 320 | _(SOUND_PCM_READ_BITS, WRITE, sizeof(int)); |
| 321 | _(SOUND_PCM_READ_CHANNELS, WRITE, sizeof(int)); |
| 322 | _(SOUND_PCM_READ_FILTER, WRITE, sizeof(int)); |
| 323 | _(SOUND_PCM_READ_RATE, WRITE, sizeof(int)); |
| 324 | _(SOUND_PCM_WRITE_CHANNELS, WRITE, sizeof(int)); |
| 325 | _(SOUND_PCM_WRITE_FILTER, WRITE, sizeof(int)); |
| 326 | _(TCFLSH, NONE, 0); |
| 327 | _(TCGETA, WRITE, struct_termio_sz); |
| 328 | _(TCGETS, WRITE, struct_termios_sz); |
| 329 | _(TCSBRK, NONE, 0); |
| 330 | _(TCSBRKP, NONE, 0); |
| 331 | _(TCSETA, READ, struct_termio_sz); |
| 332 | _(TCSETAF, READ, struct_termio_sz); |
| 333 | _(TCSETAW, READ, struct_termio_sz); |
| 334 | _(TCSETS, READ, struct_termios_sz); |
| 335 | _(TCSETSF, READ, struct_termios_sz); |
| 336 | _(TCSETSW, READ, struct_termios_sz); |
| 337 | _(TCXONC, NONE, 0); |
| 338 | _(TIOCGLCKTRMIOS, WRITE, struct_termios_sz); |
| 339 | _(TIOCGSOFTCAR, WRITE, sizeof(int)); |
| 340 | _(TIOCINQ, WRITE, sizeof(int)); |
| 341 | _(TIOCLINUX, READ, sizeof(char)); |
| 342 | _(TIOCSERCONFIG, NONE, 0); |
| 343 | _(TIOCSERGETLSR, WRITE, sizeof(int)); |
| 344 | _(TIOCSERGWILD, WRITE, sizeof(int)); |
| 345 | _(TIOCSERSWILD, READ, sizeof(int)); |
| 346 | _(TIOCSLCKTRMIOS, READ, struct_termios_sz); |
| 347 | _(TIOCSSOFTCAR, READ, sizeof(int)); |
| 348 | _(VT_ACTIVATE, NONE, 0); |
| 349 | _(VT_DISALLOCATE, NONE, 0); |
| 350 | _(VT_GETMODE, WRITE, struct_vt_mode_sz); |
| 351 | _(VT_GETSTATE, WRITE, struct_vt_stat_sz); |
| 352 | _(VT_OPENQRY, WRITE, sizeof(int)); |
| 353 | _(VT_RELDISP, NONE, 0); |
| 354 | _(VT_RESIZE, READ, struct_vt_sizes_sz); |
| 355 | _(VT_RESIZEX, READ, struct_vt_consize_sz); |
| 356 | _(VT_SENDSIG, NONE, 0); |
| 357 | _(VT_SETMODE, READ, struct_vt_mode_sz); |
| 358 | _(VT_WAITACTIVE, NONE, 0); |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 359 | #endif |
| 360 | |
| 361 | #if SANITIZER_LINUX && !SANITIZER_ANDROID |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 362 | // _(SIOCDEVPLIP, WRITE, struct_ifreq_sz); // the same as EQL_ENSLAVE |
| 363 | _(CYGETDEFTHRESH, WRITE, sizeof(int)); |
| 364 | _(CYGETDEFTIMEOUT, WRITE, sizeof(int)); |
| 365 | _(CYGETMON, WRITE, struct_cyclades_monitor_sz); |
| 366 | _(CYGETTHRESH, WRITE, sizeof(int)); |
| 367 | _(CYGETTIMEOUT, WRITE, sizeof(int)); |
| 368 | _(CYSETDEFTHRESH, NONE, 0); |
| 369 | _(CYSETDEFTIMEOUT, NONE, 0); |
| 370 | _(CYSETTHRESH, NONE, 0); |
| 371 | _(CYSETTIMEOUT, NONE, 0); |
| 372 | _(EQL_EMANCIPATE, WRITE, struct_ifreq_sz); |
| 373 | _(EQL_ENSLAVE, WRITE, struct_ifreq_sz); |
| 374 | _(EQL_GETMASTRCFG, WRITE, struct_ifreq_sz); |
| 375 | _(EQL_GETSLAVECFG, WRITE, struct_ifreq_sz); |
| 376 | _(EQL_SETMASTRCFG, WRITE, struct_ifreq_sz); |
| 377 | _(EQL_SETSLAVECFG, WRITE, struct_ifreq_sz); |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 378 | _(EVIOCGKEYCODE_V2, WRITE, struct_input_keymap_entry_sz); |
| 379 | _(EVIOCGPROP, WRITE, 0); |
| 380 | _(EVIOCSKEYCODE_V2, READ, struct_input_keymap_entry_sz); |
Evgeniy Stepanov | 7028c1e | 2013-06-18 13:56:12 +0000 | [diff] [blame] | 381 | _(FS_IOC_GETFLAGS, WRITE, sizeof(int)); |
| 382 | _(FS_IOC_GETVERSION, WRITE, sizeof(int)); |
| 383 | _(FS_IOC_SETFLAGS, READ, sizeof(int)); |
| 384 | _(FS_IOC_SETVERSION, READ, sizeof(int)); |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 385 | _(GIO_CMAP, WRITE, 48); |
| 386 | _(GIO_FONT, WRITE, 8192); |
| 387 | _(GIO_SCRNMAP, WRITE, e_tabsz); |
| 388 | _(GIO_UNIMAP, WRITE, struct_unimapdesc_sz); |
| 389 | _(GIO_UNISCRNMAP, WRITE, sizeof(short) * e_tabsz); |
| 390 | _(KDADDIO, NONE, 0); |
| 391 | _(KDDELIO, NONE, 0); |
| 392 | _(KDDISABIO, NONE, 0); |
| 393 | _(KDENABIO, NONE, 0); |
| 394 | _(KDGETKEYCODE, WRITE, struct_kbkeycode_sz); |
| 395 | _(KDGETLED, WRITE, 1); |
| 396 | _(KDGETMODE, WRITE, sizeof(int)); |
| 397 | _(KDGKBDIACR, WRITE, struct_kbdiacrs_sz); |
| 398 | _(KDGKBENT, WRITE, struct_kbentry_sz); |
| 399 | _(KDGKBLED, WRITE, sizeof(int)); |
| 400 | _(KDGKBMETA, WRITE, sizeof(int)); |
| 401 | _(KDGKBMODE, WRITE, sizeof(int)); |
| 402 | _(KDGKBSENT, WRITE, struct_kbsentry_sz); |
| 403 | _(KDGKBTYPE, WRITE, 1); |
| 404 | _(KDMAPDISP, NONE, 0); |
| 405 | _(KDMKTONE, NONE, 0); |
| 406 | _(KDSETKEYCODE, READ, struct_kbkeycode_sz); |
| 407 | _(KDSETLED, NONE, 0); |
| 408 | _(KDSETMODE, NONE, 0); |
| 409 | _(KDSIGACCEPT, NONE, 0); |
| 410 | _(KDSKBDIACR, READ, struct_kbdiacrs_sz); |
| 411 | _(KDSKBENT, READ, struct_kbentry_sz); |
| 412 | _(KDSKBLED, NONE, 0); |
| 413 | _(KDSKBMETA, NONE, 0); |
| 414 | _(KDSKBMODE, NONE, 0); |
| 415 | _(KDSKBSENT, READ, struct_kbsentry_sz); |
| 416 | _(KDUNMAPDISP, NONE, 0); |
| 417 | _(KIOCSOUND, NONE, 0); |
| 418 | _(LPABORT, NONE, 0); |
| 419 | _(LPABORTOPEN, NONE, 0); |
| 420 | _(LPCAREFUL, NONE, 0); |
| 421 | _(LPCHAR, NONE, 0); |
| 422 | _(LPGETIRQ, WRITE, sizeof(int)); |
| 423 | _(LPGETSTATUS, WRITE, sizeof(int)); |
| 424 | _(LPRESET, NONE, 0); |
| 425 | _(LPSETIRQ, NONE, 0); |
| 426 | _(LPTIME, NONE, 0); |
| 427 | _(LPWAIT, NONE, 0); |
Chandler Carruth | 8766b81 | 2013-08-18 08:47:06 +0000 | [diff] [blame] | 428 | _(MTIOCGETCONFIG, WRITE, struct_mtconfiginfo_sz); |
| 429 | _(MTIOCSETCONFIG, READ, struct_mtconfiginfo_sz); |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 430 | _(PIO_CMAP, NONE, 0); |
| 431 | _(PIO_FONT, READ, 8192); |
| 432 | _(PIO_SCRNMAP, READ, e_tabsz); |
| 433 | _(PIO_UNIMAP, READ, struct_unimapdesc_sz); |
| 434 | _(PIO_UNIMAPCLR, READ, struct_unimapinit_sz); |
| 435 | _(PIO_UNISCRNMAP, READ, sizeof(short) * e_tabsz); |
| 436 | _(SCSI_IOCTL_PROBE_HOST, READ, sizeof(int)); |
| 437 | _(SCSI_IOCTL_TAGGED_DISABLE, NONE, 0); |
| 438 | _(SCSI_IOCTL_TAGGED_ENABLE, NONE, 0); |
| 439 | _(SNDCTL_DSP_GETISPACE, WRITE, struct_audio_buf_info_sz); |
| 440 | _(SNDCTL_DSP_GETOSPACE, WRITE, struct_audio_buf_info_sz); |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 441 | _(TIOCGSERIAL, WRITE, struct_serial_struct_sz); |
| 442 | _(TIOCSERGETMULTI, WRITE, struct_serial_multiport_struct_sz); |
| 443 | _(TIOCSERSETMULTI, READ, struct_serial_multiport_struct_sz); |
| 444 | _(TIOCSSERIAL, READ, struct_serial_struct_sz); |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 445 | |
| 446 | // The following ioctl requests are shared between AX25, IPX, netrom and |
| 447 | // mrouted. |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 448 | // _(SIOCAIPXITFCRT, READ, sizeof(char)); |
| 449 | // _(SIOCAX25GETUID, READ, struct_sockaddr_ax25_sz); |
| 450 | // _(SIOCNRGETPARMS, WRITE, struct_nr_parms_struct_sz); |
| 451 | // _(SIOCAIPXPRISLT, READ, sizeof(char)); |
| 452 | // _(SIOCNRSETPARMS, READ, struct_nr_parms_struct_sz); |
| 453 | // _(SIOCAX25ADDUID, READ, struct_sockaddr_ax25_sz); |
| 454 | // _(SIOCNRDECOBS, NONE, 0); |
| 455 | // _(SIOCAX25DELUID, READ, struct_sockaddr_ax25_sz); |
| 456 | // _(SIOCIPXCFGDATA, WRITE, struct_ipx_config_data_sz); |
| 457 | // _(SIOCAX25NOUID, READ, sizeof(int)); |
| 458 | // _(SIOCNRRTCTL, READ, sizeof(int)); |
| 459 | // _(SIOCAX25DIGCTL, READ, sizeof(int)); |
| 460 | // _(SIOCAX25GETPARMS, WRITE, struct_ax25_parms_struct_sz); |
| 461 | // _(SIOCAX25SETPARMS, READ, struct_ax25_parms_struct_sz); |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 462 | #endif |
| 463 | #undef _ |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 464 | } |
| 465 | |
| 466 | static bool ioctl_initialized = false; |
| 467 | |
| 468 | struct ioctl_desc_compare { |
| 469 | bool operator()(const ioctl_desc& left, const ioctl_desc& right) const { |
| 470 | return left.req < right.req; |
| 471 | } |
| 472 | }; |
| 473 | |
| 474 | static void ioctl_init() { |
| 475 | ioctl_table_fill(); |
| 476 | InternalSort(&ioctl_table, ioctl_table_size, ioctl_desc_compare()); |
| 477 | |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 478 | bool bad = false; |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 479 | for (unsigned i = 0; i < ioctl_table_size - 1; ++i) { |
| 480 | if (ioctl_table[i].req >= ioctl_table[i + 1].req) { |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 481 | Printf("Duplicate or unsorted ioctl request id %x >= %x (%s vs %s)\n", |
| 482 | ioctl_table[i].req, ioctl_table[i + 1].req, ioctl_table[i].name, |
| 483 | ioctl_table[i + 1].name); |
| 484 | bad = true; |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 485 | } |
| 486 | } |
| 487 | |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 488 | if (bad) Die(); |
| 489 | |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 490 | ioctl_initialized = true; |
| 491 | } |
| 492 | |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 493 | // Handle the most evil ioctls that encode argument value as part of request id. |
| 494 | static unsigned ioctl_request_fixup(unsigned req) { |
Evgeniy Stepanov | 132d51c | 2013-06-20 09:39:34 +0000 | [diff] [blame] | 495 | #if SANITIZER_LINUX |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 496 | // Strip size and event number. |
| 497 | const unsigned kEviocgbitMask = |
| 498 | (IOC_SIZEMASK << IOC_SIZESHIFT) | EVIOC_EV_MAX; |
| 499 | if ((req & ~kEviocgbitMask) == IOCTL_EVIOCGBIT) |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 500 | return IOCTL_EVIOCGBIT; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 501 | // Strip absolute axis number. |
| 502 | if ((req & ~EVIOC_ABS_MAX) == IOCTL_EVIOCGABS) |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 503 | return IOCTL_EVIOCGABS; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 504 | if ((req & ~EVIOC_ABS_MAX) == IOCTL_EVIOCSABS) |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 505 | return IOCTL_EVIOCSABS; |
Evgeniy Stepanov | 132d51c | 2013-06-20 09:39:34 +0000 | [diff] [blame] | 506 | #endif |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 507 | return req; |
| 508 | } |
| 509 | |
| 510 | static const ioctl_desc *ioctl_table_lookup(unsigned req) { |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 511 | int left = 0; |
Evgeniy Stepanov | 2557a1b | 2013-06-18 09:22:24 +0000 | [diff] [blame] | 512 | int right = ioctl_table_size; |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 513 | while (left < right) { |
| 514 | int mid = (left + right) / 2; |
| 515 | if (ioctl_table[mid].req < req) |
| 516 | left = mid + 1; |
| 517 | else |
| 518 | right = mid; |
| 519 | } |
| 520 | if (left == right && ioctl_table[left].req == req) |
| 521 | return ioctl_table + left; |
| 522 | else |
Pirama Arumuga Nainar | 799172d | 2016-03-03 15:50:30 -0800 | [diff] [blame^] | 523 | return nullptr; |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 524 | } |
| 525 | |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 526 | static bool ioctl_decode(unsigned req, ioctl_desc *desc) { |
| 527 | CHECK(desc); |
| 528 | desc->req = req; |
| 529 | desc->name = "<DECODED_IOCTL>"; |
| 530 | desc->size = IOC_SIZE(req); |
| 531 | // Sanity check. |
Stephen Hines | 6a211c5 | 2014-07-21 00:49:56 -0700 | [diff] [blame] | 532 | if (desc->size > 0xFFFF) return false; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 533 | unsigned dir = IOC_DIR(req); |
| 534 | switch (dir) { |
| 535 | case IOC_NONE: |
| 536 | desc->type = ioctl_desc::NONE; |
| 537 | break; |
| 538 | case IOC_READ | IOC_WRITE: |
| 539 | desc->type = ioctl_desc::READWRITE; |
| 540 | break; |
| 541 | case IOC_READ: |
| 542 | desc->type = ioctl_desc::WRITE; |
| 543 | break; |
| 544 | case IOC_WRITE: |
| 545 | desc->type = ioctl_desc::READ; |
| 546 | break; |
| 547 | default: |
| 548 | return false; |
| 549 | } |
Stephen Hines | 6a211c5 | 2014-07-21 00:49:56 -0700 | [diff] [blame] | 550 | // Size can be 0 iff type is NONE. |
| 551 | if ((desc->type == IOC_NONE) != (desc->size == 0)) return false; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 552 | // Sanity check. |
Stephen Hines | 6a211c5 | 2014-07-21 00:49:56 -0700 | [diff] [blame] | 553 | if (IOC_TYPE(req) == 0) return false; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 554 | return true; |
| 555 | } |
| 556 | |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 557 | static const ioctl_desc *ioctl_lookup(unsigned req) { |
| 558 | req = ioctl_request_fixup(req); |
| 559 | const ioctl_desc *desc = ioctl_table_lookup(req); |
| 560 | if (desc) return desc; |
| 561 | |
| 562 | // Try stripping access size from the request id. |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 563 | desc = ioctl_table_lookup(req & ~(IOC_SIZEMASK << IOC_SIZESHIFT)); |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 564 | // Sanity check: requests that encode access size are either read or write and |
| 565 | // have size of 0 in the table. |
| 566 | if (desc && desc->size == 0 && |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 567 | (desc->type == ioctl_desc::READWRITE || desc->type == ioctl_desc::WRITE || |
| 568 | desc->type == ioctl_desc::READ)) |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 569 | return desc; |
Pirama Arumuga Nainar | 799172d | 2016-03-03 15:50:30 -0800 | [diff] [blame^] | 570 | return nullptr; |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 571 | } |
| 572 | |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 573 | static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d, |
| 574 | unsigned request, void *arg) { |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 575 | if (desc->type == ioctl_desc::READ || desc->type == ioctl_desc::READWRITE) { |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 576 | unsigned size = desc->size ? desc->size : IOC_SIZE(request); |
| 577 | COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, size); |
| 578 | } |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 579 | if (desc->type != ioctl_desc::CUSTOM) |
| 580 | return; |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 581 | if (request == IOCTL_SIOCGIFCONF) { |
| 582 | struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg; |
| 583 | COMMON_INTERCEPTOR_READ_RANGE(ctx, &ifc->ifc_len, sizeof(ifc->ifc_len)); |
Evgeniy Stepanov | 4757c47 | 2013-06-07 15:49:38 +0000 | [diff] [blame] | 584 | } |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 585 | } |
| 586 | |
| 587 | static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d, |
| 588 | unsigned request, void *arg) { |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 589 | if (desc->type == ioctl_desc::WRITE || desc->type == ioctl_desc::READWRITE) { |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 590 | // FIXME: add verbose output |
Evgeniy Stepanov | 4612aba | 2013-06-20 09:19:28 +0000 | [diff] [blame] | 591 | unsigned size = desc->size ? desc->size : IOC_SIZE(request); |
| 592 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, size); |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 593 | } |
| 594 | if (desc->type != ioctl_desc::CUSTOM) |
| 595 | return; |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 596 | if (request == IOCTL_SIOCGIFCONF) { |
| 597 | struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg; |
| 598 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len); |
Evgeniy Stepanov | 4757c47 | 2013-06-07 15:49:38 +0000 | [diff] [blame] | 599 | } |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 600 | } |