blob: 1de59e723920d2d0504c070412c91127f844338c [file] [log] [blame]
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +00001//===-- 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
15struct 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
27const unsigned ioctl_table_max = 500;
28static ioctl_desc ioctl_table[ioctl_table_max];
29static 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.
34static 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 Stepanov4ce6f792013-06-07 14:56:54 +000088
89#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_MAC
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +000090 _(0x000089E0, WRITE, struct_sioc_vif_req_sz); // SIOCGETVIFCNT
91 _(0x000089E1, WRITE, struct_sioc_sg_req_sz); // SIOCGETSGCNT
Evgeniy Stepanov4ce6f792013-06-07 14:56:54 +000092#endif
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +000093
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
460static bool ioctl_initialized = false;
461
462struct ioctl_desc_compare {
463 bool operator()(const ioctl_desc& left, const ioctl_desc& right) const {
464 return left.req < right.req;
465 }
466};
467
468static 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
483static 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
499static 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
509static 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}