From fd3cdc04d89fde9792db823e3ded17071bcd045b Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 13 Jul 2015 20:10:20 +0000 Subject: [PATCH] term.c: enhance tty ioctl parser Decode as much data on entering syscall as possible. * term.c (decode_termios, decode_termio, decode_winsize, decode_ttysize, decode_modem_flags): New functions. (term_ioctl): Use them. Update for RVAL_DECODED. --- term.c | 375 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 190 insertions(+), 185 deletions(-) diff --git a/term.c b/term.c index fbcd4a7c..c913a468 100644 --- a/term.c +++ b/term.c @@ -32,269 +32,274 @@ */ #include -#ifdef TCXONC -# include "xlat/tcxonc_options.h" -#endif - -#ifdef TCFLSH -# include "xlat/tcflsh_options.h" -#endif - +#include "xlat/tcxonc_options.h" +#include "xlat/tcflsh_options.h" #include "xlat/baud_options.h" #include "xlat/modem_flags.h" -int -term_ioctl(struct tcb *tcp, const unsigned int code, long arg) +static void +decode_termios(struct tcb *tcp, const long addr) { struct termios tios; + int i; + + if (!verbose(tcp)) + return; + + tprints(", "); + if (umove_or_printaddr(tcp, addr, &tios)) + return; + if (abbrev(tcp)) { + tprints("{"); + printxval(baud_options, tios.c_cflag & CBAUD, "B???"); + tprintf(" %sopost %sisig %sicanon %secho ...}", + (tios.c_oflag & OPOST) ? "" : "-", + (tios.c_lflag & ISIG) ? "" : "-", + (tios.c_lflag & ICANON) ? "" : "-", + (tios.c_lflag & ECHO) ? "" : "-"); + return; + } + tprintf("{c_iflags=%#lx, c_oflags=%#lx, ", + (long) tios.c_iflag, (long) tios.c_oflag); + tprintf("c_cflags=%#lx, c_lflags=%#lx, ", + (long) tios.c_cflag, (long) tios.c_lflag); + tprintf("c_line=%u, ", tios.c_line); + if (!(tios.c_lflag & ICANON)) + tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", + tios.c_cc[VMIN], tios.c_cc[VTIME]); + tprintf("c_cc=\""); + for (i = 0; i < NCCS; i++) + tprintf("\\x%02x", tios.c_cc[i]); + tprintf("\"}"); +} + +static void +decode_termio(struct tcb *tcp, const long addr) +{ struct termio tio; + int i; + + if (!verbose(tcp)) + return; + + tprints(", "); + if (umove_or_printaddr(tcp, addr, &tio)) + return; + if (abbrev(tcp)) { + tprints("{"); + printxval(baud_options, tio.c_cflag & CBAUD, "B???"); + tprintf(" %sopost %sisig %sicanon %secho ...}", + (tio.c_oflag & OPOST) ? "" : "-", + (tio.c_lflag & ISIG) ? "" : "-", + (tio.c_lflag & ICANON) ? "" : "-", + (tio.c_lflag & ECHO) ? "" : "-"); + return; + } + tprintf("{c_iflags=%#lx, c_oflags=%#lx, ", + (long) tio.c_iflag, (long) tio.c_oflag); + tprintf("c_cflags=%#lx, c_lflags=%#lx, ", + (long) tio.c_cflag, (long) tio.c_lflag); + tprintf("c_line=%u, ", tio.c_line); +#ifdef _VMIN + if (!(tio.c_lflag & ICANON)) + tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ", + tio.c_cc[_VMIN], tio.c_cc[_VTIME]); +#else /* !_VMIN */ + if (!(tio.c_lflag & ICANON)) + tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", + tio.c_cc[VMIN], tio.c_cc[VTIME]); +#endif /* !_VMIN */ + tprintf("c_cc=\""); + for (i = 0; i < NCC; i++) + tprintf("\\x%02x", tio.c_cc[i]); + tprintf("\"}"); +} + +static void +decode_winsize(struct tcb *tcp, const long addr) +{ struct winsize ws; + + if (!verbose(tcp)) + return; + + tprints(", "); + if (umove_or_printaddr(tcp, addr, &ws)) + return; + tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}", + ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel); +} + #ifdef TIOCGSIZE - struct ttysize ts; +static void +decode_ttysize(struct tcb *tcp, const long addr) +{ + struct ttysize ts; + + if (!verbose(tcp)) + return; + + tprints(", "); + if (umove_or_printaddr(tcp, addr, &ts)) + return; + tprintf("{ts_lines=%d, ts_cols=%d}", + ts.ts_lines, ts.ts_cols); +} #endif - int i; - if (entering(tcp)) - return 0; +static void +decode_modem_flags(struct tcb *tcp, const long addr) +{ + int i; - switch (code) { + if (!verbose(tcp)) + return; - /* ioctls with termios or termio args */ + tprints(", "); + if (umove_or_printaddr(tcp, addr, &i)) + return; + tprints("["); + printflags(modem_flags, i, "TIOCM_???"); + tprints("]"); +} -#ifdef TCGETS +int +term_ioctl(struct tcb *tcp, const unsigned int code, const long arg) +{ + switch (code) { + /* struct termios */ case TCGETS: - if (syserror(tcp)) +#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: - if (!verbose(tcp) || umove(tcp, arg, &tios) < 0) - return 0; - if (abbrev(tcp)) { - tprints(", {"); - printxval(baud_options, tios.c_cflag & CBAUD, "B???"); - tprintf(" %sopost %sisig %sicanon %secho ...}", - (tios.c_oflag & OPOST) ? "" : "-", - (tios.c_lflag & ISIG) ? "" : "-", - (tios.c_lflag & ICANON) ? "" : "-", - (tios.c_lflag & ECHO) ? "" : "-"); - return 1; - } - tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ", - (long) tios.c_iflag, (long) tios.c_oflag); - tprintf("c_cflags=%#lx, c_lflags=%#lx, ", - (long) tios.c_cflag, (long) tios.c_lflag); - tprintf("c_line=%u, ", tios.c_line); - if (!(tios.c_lflag & ICANON)) - tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", - tios.c_cc[VMIN], tios.c_cc[VTIME]); - tprintf("c_cc=\""); - for (i = 0; i < NCCS; i++) - tprintf("\\x%02x", tios.c_cc[i]); - tprintf("\"}"); - return 1; -#endif /* TCGETS */ +#ifdef TCSETSF2 + case TCSETSF2: +#endif + case TIOCSLCKTRMIOS: + decode_termios(tcp, arg); + break; -#ifdef TCGETA + /* struct termio */ case TCGETA: - if (syserror(tcp)) + if (entering(tcp)) return 0; case TCSETA: case TCSETAW: case TCSETAF: - if (!verbose(tcp) || umove(tcp, arg, &tio) < 0) - return 0; - if (abbrev(tcp)) { - tprints(", {"); - printxval(baud_options, tio.c_cflag & CBAUD, "B???"); - tprintf(" %sopost %sisig %sicanon %secho ...}", - (tio.c_oflag & OPOST) ? "" : "-", - (tio.c_lflag & ISIG) ? "" : "-", - (tio.c_lflag & ICANON) ? "" : "-", - (tio.c_lflag & ECHO) ? "" : "-"); - return 1; - } - tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ", - (long) tio.c_iflag, (long) tio.c_oflag); - tprintf("c_cflags=%#lx, c_lflags=%#lx, ", - (long) tio.c_cflag, (long) tio.c_lflag); - tprintf("c_line=%u, ", tio.c_line); -#ifdef _VMIN - if (!(tio.c_lflag & ICANON)) - tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ", - tio.c_cc[_VMIN], tio.c_cc[_VTIME]); -#else /* !_VMIN */ - if (!(tio.c_lflag & ICANON)) - tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", - tio.c_cc[VMIN], tio.c_cc[VTIME]); -#endif /* !_VMIN */ - tprintf("c_cc=\""); - for (i = 0; i < NCC; i++) - tprintf("\\x%02x", tio.c_cc[i]); - tprintf("\"}"); - return 1; -#endif /* TCGETA */ - - /* ioctls with winsize or ttysize args */ + decode_termio(tcp, arg); + break; -#ifdef TIOCGWINSZ + /* struct winsize */ case TIOCGWINSZ: - if (syserror(tcp)) + if (entering(tcp)) return 0; case TIOCSWINSZ: - if (!verbose(tcp) || umove(tcp, arg, &ws) < 0) - return 0; - tprintf(", {ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}", - ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel); - return 1; -#endif /* TIOCGWINSZ */ + decode_winsize(tcp, arg); + break; + /* struct ttysize */ #ifdef TIOCGSIZE case TIOCGSIZE: - if (syserror(tcp)) + if (entering(tcp)) return 0; case TIOCSSIZE: - if (!verbose(tcp) || umove(tcp, arg, &ts) < 0) - return 0; - tprintf(", {ts_lines=%d, ts_cols=%d}", - ts.ts_lines, ts.ts_cols); - return 1; + decode_ttysize(tcp, arg); + break; #endif /* ioctls with a direct decodable arg */ -#ifdef TCXONC case TCXONC: tprints(", "); printxval(tcxonc_options, arg, "TC???"); - return 1; -#endif -#ifdef TCFLSH + break; case TCFLSH: tprints(", "); printxval(tcflsh_options, arg, "TC???"); - return 1; -#endif -#ifdef TIOCSCTTY + break; + case TCSBRK: + case TCSBRKP: case TIOCSCTTY: - tprintf(", %ld", arg); - return 1; -#endif + tprintf(", %d", (int) arg); + break; /* ioctls with an indirect parameter displayed as modem flags */ - -#ifdef TIOCMGET case TIOCMGET: + if (entering(tcp)) + return 0; case TIOCMBIS: case TIOCMBIC: case TIOCMSET: - if (umove(tcp, arg, &i) < 0) - return 0; - tprints(", ["); - printflags(modem_flags, i, "TIOCM_???"); - tprints("]"); - return 1; -#endif /* TIOCMGET */ + decode_modem_flags(tcp, arg); + break; /* ioctls with an indirect parameter displayed in decimal */ - - case TIOCSPGRP: case TIOCGPGRP: -#ifdef TIOCGETPGRP - case TIOCGETPGRP: -#endif -#ifdef TIOCSETPGRP - case TIOCSETPGRP: -#endif -#ifdef FIONREAD + case TIOCGSID: + case TIOCGETD: + case TIOCGSOFTCAR: + case TIOCGPTN: case FIONREAD: -#endif case TIOCOUTQ: -#ifdef FIONBIO - case FIONBIO: -#endif -#ifdef FIOASYNC - case FIOASYNC: -#endif -#ifdef FIOGETOWN - case FIOGETOWN: -#endif -#ifdef FIOSETOWN - case FIOSETOWN: +#ifdef TIOCGEXCL + case TIOCGEXCL: #endif -#ifdef TIOCGETD - case TIOCGETD: +#ifdef TIOCGDEV + case TIOCGDEV: #endif -#ifdef TIOCSETD + if (entering(tcp)) + return 0; + case TIOCSPGRP: case TIOCSETD: -#endif -#ifdef TIOCPKT + case FIONBIO: + case FIOASYNC: case TIOCPKT: -#endif -#ifdef TIOCREMOTE - case TIOCREMOTE: -#endif -#ifdef TIOCUCNTL - case TIOCUCNTL: -#endif -#ifdef TIOCTCNTL - case TIOCTCNTL: -#endif -#ifdef TIOCSIGNAL - case TIOCSIGNAL: -#endif -#ifdef TIOCSSOFTCAR case TIOCSSOFTCAR: -#endif -#ifdef TIOCGSOFTCAR - case TIOCGSOFTCAR: -#endif -#ifdef TIOCISPACE - case TIOCISPACE: -#endif -#ifdef TIOCISIZE - case TIOCISIZE: -#endif -#ifdef TIOCSINTR - case TIOCSINTR: -#endif -#ifdef TIOCSPTLCK case TIOCSPTLCK: -#endif -#ifdef TIOCGPTN - case TIOCGPTN: -#endif tprints(", "); printnum_int(tcp, arg, "%d"); - return 1; + break; /* ioctls with an indirect parameter displayed as a char */ - -#ifdef TIOCSTI case TIOCSTI: -#endif tprints(", "); printstr(tcp, arg, 1); - return 1; + break; /* ioctls with no parameters */ -#ifdef TIOCNOTTY + case TIOCSBRK: + case TIOCCBRK: + case TIOCCONS: case TIOCNOTTY: -#endif -#ifdef FIOCLEX + case TIOCEXCL: + case TIOCNXCL: case FIOCLEX: -#endif -#ifdef FIONCLEX case FIONCLEX: +#ifdef TIOCVHANGUP + case TIOCVHANGUP: #endif -#ifdef TIOCCONS - case TIOCCONS: +#ifdef TIOCSSERIAL + case TIOCSSERIAL: #endif - return 1; + break; /* ioctls which are unknown */ default: - return 0; + return RVAL_DECODED; } + + return RVAL_DECODED | 1; } -- 2.40.0