]> granicus.if.org Git - strace/blob - ioctl.c
print_array: enhance printing of unfetchable object addresses
[strace] / ioctl.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-2001 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 1999-2018 The strace developers.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "defs.h"
33 #include <linux/ioctl.h>
34 #include "xlat/ioctl_dirs.h"
35
36 #include "xlat/evdev_ev.h"
37
38 static int
39 compare(const void *a, const void *b)
40 {
41         const unsigned int code1 = (const uintptr_t) a;
42         const unsigned int code2 = ((struct_ioctlent *) b)->code;
43         return (code1 > code2) ? 1 : (code1 < code2) ? -1 : 0;
44 }
45
46 static const struct_ioctlent *
47 ioctl_lookup(const unsigned int code)
48 {
49         struct_ioctlent *iop;
50
51         iop = bsearch((const void *) (const uintptr_t) code, ioctlent,
52                         nioctlents, sizeof(ioctlent[0]), compare);
53         while (iop > ioctlent) {
54                 iop--;
55                 if (iop->code != code) {
56                         iop++;
57                         break;
58                 }
59         }
60         return iop;
61 }
62
63 static const struct_ioctlent *
64 ioctl_next_match(const struct_ioctlent *iop)
65 {
66         const unsigned int code = iop->code;
67         iop++;
68         if (iop < ioctlent + nioctlents && iop->code == code)
69                 return iop;
70         return NULL;
71 }
72
73 static void
74 ioctl_print_code(const unsigned int code)
75 {
76         tprints("_IOC(");
77         printflags(ioctl_dirs, _IOC_DIR(code), "_IOC_???");
78         tprintf(", %#x, %#x, %#x)",
79                 _IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code));
80 }
81
82 static int
83 evdev_decode_number(const unsigned int code)
84 {
85         const unsigned int nr = _IOC_NR(code);
86
87         if (_IOC_DIR(code) == _IOC_WRITE) {
88                 if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
89                         tprints("EVIOCSABS(");
90                         printxval_indexn(evdev_abs, evdev_abs_size, nr - 0xc0,
91                                          "ABS_???");
92                         tprints(")");
93                         return 1;
94                 }
95         }
96
97         if (_IOC_DIR(code) != _IOC_READ)
98                 return 0;
99
100         if (nr >= 0x20 && nr <= 0x20 + 0x1f) {
101                 tprints("EVIOCGBIT(");
102                 printxval(evdev_ev, nr - 0x20, "EV_???");
103                 tprintf(", %u)", _IOC_SIZE(code));
104                 return 1;
105         } else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
106                 tprints("EVIOCGABS(");
107                 printxval_indexn(evdev_abs, evdev_abs_size, nr - 0x40,
108                                  "ABS_???");
109                 tprints(")");
110                 return 1;
111         }
112
113         switch (_IOC_NR(nr)) {
114                 case 0x06:
115                         tprintf("EVIOCGNAME(%u)", _IOC_SIZE(code));
116                         return 1;
117                 case 0x07:
118                         tprintf("EVIOCGPHYS(%u)", _IOC_SIZE(code));
119                         return 1;
120                 case 0x08:
121                         tprintf("EVIOCGUNIQ(%u)", _IOC_SIZE(code));
122                         return 1;
123                 case 0x09:
124                         tprintf("EVIOCGPROP(%u)", _IOC_SIZE(code));
125                         return 1;
126                 case 0x0a:
127                         tprintf("EVIOCGMTSLOTS(%u)", _IOC_SIZE(code));
128                         return 1;
129                 case 0x18:
130                         tprintf("EVIOCGKEY(%u)", _IOC_SIZE(code));
131                         return 1;
132                 case 0x19:
133                         tprintf("EVIOCGLED(%u)", _IOC_SIZE(code));
134                         return 1;
135                 case 0x1a:
136                         tprintf("EVIOCGSND(%u)", _IOC_SIZE(code));
137                         return 1;
138                 case 0x1b:
139                         tprintf("EVIOCGSW(%u)", _IOC_SIZE(code));
140                         return 1;
141                 default:
142                         return 0;
143         }
144 }
145
146 static int
147 hiddev_decode_number(const unsigned int code)
148 {
149         if (_IOC_DIR(code) == _IOC_READ) {
150                 switch (_IOC_NR(code)) {
151                         case 0x04:
152                                 tprintf("HIDIOCGRAWNAME(%u)", _IOC_SIZE(code));
153                                 return 1;
154                         case 0x05:
155                                 tprintf("HIDIOCGRAWPHYS(%u)", _IOC_SIZE(code));
156                                 return 1;
157                         case 0x06:
158                                 tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
159                                 return 1;
160                         case 0x12:
161                                 tprintf("HIDIOCGPHYS(%u)", _IOC_SIZE(code));
162                                 return 1;
163                         default:
164                                 return 0;
165                 }
166         } else if (_IOC_DIR(code) == (_IOC_READ | _IOC_WRITE)) {
167                 switch (_IOC_NR(code)) {
168                         case 0x06:
169                                 tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
170                                 return 1;
171                         case 0x07:
172                                 tprintf("HIDIOCGFEATURE(%u)", _IOC_SIZE(code));
173                                 return 1;
174                         default:
175                                 return 0;
176                 }
177         }
178
179         return 0;
180 }
181
182 static int
183 ioctl_decode_command_number(struct tcb *tcp)
184 {
185         const unsigned int code = tcp->u_arg[1];
186
187         switch (_IOC_TYPE(code)) {
188                 case 'E':
189                         return evdev_decode_number(code);
190                 case 'H':
191                         return hiddev_decode_number(code);
192                 case 'M':
193                         if (_IOC_DIR(code) == _IOC_WRITE) {
194                                 tprintf("MIXER_WRITE(%u)", _IOC_NR(code));
195                                 return 1;
196                         } else if (_IOC_DIR(code) == _IOC_READ) {
197                                 tprintf("MIXER_READ(%u)", _IOC_NR(code));
198                                 return 1;
199                         }
200                         return 0;
201                 case 'U':
202                         if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x2c) {
203                                 tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(code));
204                                 return 1;
205                         }
206                         return 0;
207                 case 'j':
208                         if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x13) {
209                                 tprintf("JSIOCGNAME(%u)", _IOC_SIZE(code));
210                                 return 1;
211                         }
212                         return 0;
213                 case 'k':
214                         if (_IOC_DIR(code) == _IOC_WRITE && _IOC_NR(code) == 0) {
215                                 tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(code));
216                                 return 1;
217                         }
218                         return 0;
219                 default:
220                         return 0;
221         }
222 }
223
224 /**
225  * Decode arg parameter of the ioctl call.
226  *
227  * @return There are two flags of the return value important for the purposes of
228  *         processing by SYS_FUNC(ioctl):
229  *          - RVAL_IOCTL_DECODED: indicates that ioctl decoder code
230  *                                has printed arg parameter;
231  *          - RVAL_DECODED: indicates that decoding is done.
232  *         As a result, the following behaviour is expected:
233  *          - on entering:
234  *            - 0: decoding should be continued on exiting;
235  *            - RVAL_IOCTL_DECODED: decoding on exiting is not needed
236  *                                  and decoder has printed arg value;
237  *            - RVAL_DECODED: decoding on exiting is not needed
238  *                            and generic handler should print arg value.
239  *          - on exiting:
240  *            - 0: generic handler should print arg value;
241  *            - RVAL_IOCTL_DECODED: decoder has printed arg value.
242  *
243  *         Note that it makes no sense to return just RVAL_DECODED on exiting,
244  *         but, of course, it is not prohibited (for example, it may be useful
245  *         in cases where the return path is common on entering and on exiting
246  *         the syscall).
247  *
248  *         SYS_FUNC(ioctl) converts RVAL_IOCTL_DECODED flag to RVAL_DECODED,
249  *         and passes all other bits of ioctl_decode return value unchanged.
250  */
251 static int
252 ioctl_decode(struct tcb *tcp)
253 {
254         const unsigned int code = tcp->u_arg[1];
255         const kernel_ulong_t arg = tcp->u_arg[2];
256
257         switch (_IOC_TYPE(code)) {
258         case '$':
259                 return perf_ioctl(tcp, code, arg);
260 #if defined(ALPHA) || defined(POWERPC)
261         case 'f': {
262                 int ret = file_ioctl(tcp, code, arg);
263                 if (ret != RVAL_DECODED)
264                         return ret;
265                 ATTRIBUTE_FALLTHROUGH;
266         }
267         case 't':
268         case 'T':
269                 return term_ioctl(tcp, code, arg);
270 #else /* !ALPHA */
271         case 'f':
272                 return file_ioctl(tcp, code, arg);
273         case 0x54:
274 #endif /* !ALPHA */
275                 return term_ioctl(tcp, code, arg);
276         case 0x89:
277                 return sock_ioctl(tcp, code, arg);
278         case 'p':
279                 return rtc_ioctl(tcp, code, arg);
280         case 0x03:
281                 return hdio_ioctl(tcp, code, arg);
282         case 0x12:
283                 return block_ioctl(tcp, code, arg);
284         case 'X':
285                 return fs_x_ioctl(tcp, code, arg);
286         case 0x22:
287                 return scsi_ioctl(tcp, code, arg);
288         case 'L':
289                 return loop_ioctl(tcp, code, arg);
290 #ifdef HAVE_STRUCT_MTD_WRITE_REQ
291         case 'M':
292                 return mtd_ioctl(tcp, code, arg);
293 #endif
294 #ifdef HAVE_STRUCT_UBI_ATTACH_REQ_MAX_BEB_PER1024
295         case 'o':
296         case 'O':
297                 return ubi_ioctl(tcp, code, arg);
298 #endif
299         case 'V':
300                 return v4l2_ioctl(tcp, code, arg);
301 #ifdef HAVE_STRUCT_PTP_SYS_OFFSET
302         case '=':
303                 return ptp_ioctl(tcp, code, arg);
304 #endif
305 #ifdef HAVE_LINUX_INPUT_H
306         case 'E':
307                 return evdev_ioctl(tcp, code, arg);
308 #endif
309 #ifdef HAVE_LINUX_USERFAULTFD_H
310         case 0xaa:
311                 return uffdio_ioctl(tcp, code, arg);
312 #endif
313 #ifdef HAVE_LINUX_BTRFS_H
314         case 0x94:
315                 return btrfs_ioctl(tcp, code, arg);
316 #endif
317         case 0xb7:
318                 return nsfs_ioctl(tcp, code, arg);
319 #ifdef HAVE_LINUX_DM_IOCTL_H
320         case 0xfd:
321                 return dm_ioctl(tcp, code, arg);
322 #endif
323 #ifdef HAVE_LINUX_KVM_H
324         case 0xae:
325                 return kvm_ioctl(tcp, code, arg);
326 #endif
327         case 'I':
328                 return inotify_ioctl(tcp, code, arg);
329         default:
330                 break;
331         }
332         return 0;
333 }
334
335 SYS_FUNC(ioctl)
336 {
337         const struct_ioctlent *iop;
338         int ret;
339
340         if (entering(tcp)) {
341                 printfd(tcp, tcp->u_arg[0]);
342                 tprints(", ");
343
344                 if (xlat_verbosity != XLAT_STYLE_ABBREV)
345                         tprintf("%#x", (unsigned int) tcp->u_arg[1]);
346                 if (xlat_verbosity == XLAT_STYLE_VERBOSE)
347                         tprints(" /* ");
348                 if (xlat_verbosity != XLAT_STYLE_RAW) {
349                         ret = ioctl_decode_command_number(tcp);
350                         if (!(ret & IOCTL_NUMBER_STOP_LOOKUP)) {
351                                 iop = ioctl_lookup(tcp->u_arg[1]);
352                                 if (iop) {
353                                         if (ret)
354                                                 tprints(" or ");
355                                         tprints(iop->symbol);
356                                         while ((iop = ioctl_next_match(iop)))
357                                                 tprintf(" or %s", iop->symbol);
358                                 } else if (!ret) {
359                                         ioctl_print_code(tcp->u_arg[1]);
360                                 }
361                         }
362                 }
363                 if (xlat_verbosity == XLAT_STYLE_VERBOSE)
364                         tprints(" */");
365
366                 ret = ioctl_decode(tcp);
367         } else {
368                 ret = ioctl_decode(tcp) | RVAL_DECODED;
369         }
370
371         if (ret & RVAL_IOCTL_DECODED) {
372                 ret &= ~RVAL_IOCTL_DECODED;
373                 ret |= RVAL_DECODED;
374         } else if (ret & RVAL_DECODED) {
375                 tprintf(", %#" PRI_klx, tcp->u_arg[2]);
376         }
377
378         return ret;
379 }