From 2268bd05318f7170ecc2da60271eeb8f63d214dc Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Mon, 22 Nov 2021 17:51:54 +0900 Subject: ioctl: use finfo as hints for resolving overlapping ioctl commands Such an overlapping can be observed, e.g. when running vi under strace: ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 ... After this change, when the file descriptor corresponds to a terminal device, strace would be able to resolve the collision between ioctl commands from different subsystems: ioctl(0, TCSETS, {B38400 ... * src/defs.h (term_ioctl_decode_command_number): New function declaration. * src/ioctl.c (ioctl_decode_command_number): Add a new argument for passing finfo that can be used as hints for decoding ioctl commands. Handle the code `T'. (SYS_FUNC(ioctl)): Pass finfo as hints to ioctl_decode_command_number. * src/term.c: Include "xlat/term_cmds_overlapping.h". (term_ioctl_decode_command_number): Decode the command in this earlier stage if the corresponding file descriptor corresponds to a terminal device. * src/xlat/term_cmds_overlapping.in: New file listing overlapping tty ioctl commands. * tests/ioctl_termios.c (main): Extend cmds[] in checks[]. (main::checks::cmds): Add new member "pass_invalid_fd". Omit " or ..." substring in case of TCSETS, TCSETSW, and TCSETSF for a valid tty descriptor. Add test commands for invalid descriptors. Signed-off-by: Masatake YAMATO Signed-off-by: Dmitry V. Levin --- tests/ioctl_termios.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/ioctl_termios.c b/tests/ioctl_termios.c index 9b0c94274..eaea4e96b 100644 --- a/tests/ioctl_termios.c +++ b/tests/ioctl_termios.c @@ -860,7 +860,8 @@ main(void) const char *cmd_str; bool write; bool can_fail; - } cmds[6]; + bool pass_invalid_fd; + } cmds[9]; struct { kernel_ulong_t data; const char *data_str; @@ -889,22 +890,33 @@ main(void) #endif { { - /* XXX */ + /* + * If the fd is valid and points to a tty, + * the potential ioctl command collision is resolved. + */ + { ARG_STR(TCSETS), true }, + { ARG_STR(TCSETSW), true }, + { ARG_STR(TCSETSF), true }, + + /* + * If the fd is invalid, it is impossible + * to distinguish the overlapping ioctl commands. + */ { TCSETS, #if IOCTL_CLASHED "SNDCTL_TMR_START or " #endif - "TCSETS", true }, + "TCSETS", true, true, true }, { TCSETSW, #if IOCTL_CLASHED "SNDCTL_TMR_STOP or " #endif - "TCSETSW", true }, + "TCSETSW", true, true, true }, { TCSETSF, #if IOCTL_CLASHED "SNDCTL_TMR_CONTINUE or " #endif - "TCSETSF", true }, + "TCSETSF", true, true, true }, { ARG_STR(TCGETS), false }, { ARG_STR(TIOCSLCKTRMIOS), true, true }, @@ -963,7 +975,7 @@ main(void) do_ioctl(checks[i].cmds[j].cmd, checks[i].cmds[j].cmd_str, - ret, + checks[i].cmds[j].pass_invalid_fd? -1: ret, checks[i].printer, checks[i].args[k].data, checks[i].args[k].valid, -- cgit v1.2.1