static bool print_iovec(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data) { const kernel_ulong_t *iov; kernel_ulong_t iov_buf[2], len; struct print_iovec_config *c = data; if (elem_size < sizeof(iov_buf)) { iov_buf[0] = ((unsigned int *) elem_buf)[0]; iov_buf[1] = ((unsigned int *) elem_buf)[1]; iov = iov_buf; } else { iov = elem_buf; } tprints("{iov_base="); len = iov[1]; switch (c->decode_iov) { case IOV_DECODE_STR: if (len > c->data_size) len = c->data_size; if (c->data_size != (kernel_ulong_t) -1) c->data_size -= len; printstrn(tcp, iov[0], len); break; case IOV_DECODE_NETLINK: if (len > c->data_size) len = c->data_size; if (c->data_size != (kernel_ulong_t) -1) c->data_size -= len; /* assume that the descriptor is 1st syscall argument */ decode_netlink(tcp, tcp->u_arg[0], iov[0], len); break; default: printaddr(iov[0]); break; } tprintf(", iov_len=%" PRI_klu "}", iov[1]); return true; }
int term_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { switch (code) { /* struct termios */ case TCGETS: #ifdef TCGETS2 case TCGETS2: #endif case TIOCGLCKTRMIOS: if (entering(tcp)) return 0; case TCSETS: #ifdef TCSETS2 case TCSETS2: #endif case TCSETSW: #ifdef TCSETSW2 case TCSETSW2: #endif case TCSETSF: #ifdef TCSETSF2 case TCSETSF2: #endif case TIOCSLCKTRMIOS: decode_termios(tcp, arg); break; /* struct termio */ case TCGETA: if (entering(tcp)) return 0; case TCSETA: case TCSETAW: case TCSETAF: decode_termio(tcp, arg); break; /* struct winsize */ case TIOCGWINSZ: if (entering(tcp)) return 0; case TIOCSWINSZ: decode_winsize(tcp, arg); break; /* struct ttysize */ #ifdef TIOCGSIZE case TIOCGSIZE: if (entering(tcp)) return 0; case TIOCSSIZE: decode_ttysize(tcp, arg); break; #endif /* ioctls with a direct decodable arg */ case TCXONC: tprints(", "); printxval64(tcxonc_options, arg, "TC???"); break; case TCFLSH: tprints(", "); printxval64(tcflsh_options, arg, "TC???"); break; case TCSBRK: case TCSBRKP: case TIOCSCTTY: tprintf(", %d", (int) arg); break; /* ioctls with an indirect parameter displayed as modem flags */ case TIOCMGET: if (entering(tcp)) return 0; case TIOCMBIS: case TIOCMBIC: case TIOCMSET: decode_modem_flags(tcp, arg); break; /* ioctls with an indirect parameter displayed in decimal */ case TIOCGPGRP: case TIOCGSID: case TIOCGETD: case TIOCGSOFTCAR: case TIOCGPTN: case FIONREAD: case TIOCOUTQ: #ifdef TIOCGEXCL case TIOCGEXCL: #endif #ifdef TIOCGDEV case TIOCGDEV: #endif if (entering(tcp)) return 0; case TIOCSPGRP: case TIOCSETD: case FIONBIO: case FIOASYNC: case TIOCPKT: case TIOCSSOFTCAR: case TIOCSPTLCK: tprints(", "); printnum_int(tcp, arg, "%d"); break; /* ioctls with an indirect parameter displayed as a char */ case TIOCSTI: tprints(", "); printstrn(tcp, arg, 1); break; /* ioctls with no parameters */ case TIOCSBRK: case TIOCCBRK: case TIOCCONS: case TIOCNOTTY: case TIOCEXCL: case TIOCNXCL: case FIOCLEX: case FIONCLEX: #ifdef TIOCVHANGUP case TIOCVHANGUP: #endif #ifdef TIOCSSERIAL case TIOCSSERIAL: #endif break; /* ioctls which are unknown */ default: return RVAL_DECODED; } return RVAL_IOCTL_DECODED; }
static int evdev_read_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { /* fixed-number fixed-length commands */ switch (code) { case EVIOCGVERSION: tprints(", "); printnum_int(tcp, arg, "%#x"); return 1; case EVIOCGEFFECTS: tprints(", "); printnum_int(tcp, arg, "%u"); return 1; case EVIOCGID: return getid_ioctl(tcp, arg); # ifdef EVIOCGREP case EVIOCGREP: return repeat_ioctl(tcp, arg); # endif case EVIOCGKEYCODE: return keycode_ioctl(tcp, arg); # ifdef EVIOCGKEYCODE_V2 case EVIOCGKEYCODE_V2: return keycode_V2_ioctl(tcp, arg); # endif } /* fixed-number variable-length commands */ switch (_IOC_NR(code)) { # ifdef EVIOCGMTSLOTS case _IOC_NR(EVIOCGMTSLOTS(0)): return mtslots_ioctl(tcp, code, arg); # endif case _IOC_NR(EVIOCGNAME(0)): case _IOC_NR(EVIOCGPHYS(0)): case _IOC_NR(EVIOCGUNIQ(0)): tprints(", "); if (syserror(tcp)) printaddr(arg); else printstrn(tcp, arg, tcp->u_rval); return 1; # ifdef EVIOCGPROP case _IOC_NR(EVIOCGPROP(0)): return decode_bitset(tcp, arg, evdev_prop, INPUT_PROP_MAX, "PROP_???"); # endif case _IOC_NR(EVIOCGSND(0)): return decode_bitset(tcp, arg, evdev_snd, SND_MAX, "SND_???"); # ifdef EVIOCGSW case _IOC_NR(EVIOCGSW(0)): return decode_bitset(tcp, arg, evdev_switch, SW_MAX, "SW_???"); # endif case _IOC_NR(EVIOCGKEY(0)): return decode_bitset(tcp, arg, evdev_keycode, KEY_MAX, "KEY_???"); case _IOC_NR(EVIOCGLED(0)): return decode_bitset(tcp, arg, evdev_leds, LED_MAX, "LED_???"); } /* multi-number fixed-length commands */ if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) return abs_ioctl(tcp, arg); /* multi-number variable-length commands */ if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg); return 0; }