[PATCH 3/6] Use fd_info structure to arbitrate overwrapped IOCTL command assignments between PTS and SND
Masatake YAMATO
yamato at redhat.com
Thu Mar 10 12:01:03 UTC 2022
IOCTL command assignments are overwrapped.
We could observe the overwrapping when running vi under strace:
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 ...
If a fd opens /dev/pts/*, strace with this patch can decode
the same ioctl invocation like:
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 parameter
for passing fd_info that can be used as hint for ioctl command
decoding. Handle the code `T': calling
term_ioctl_decode_command_number().
(SYS_FUNC(ioctl)): Pass fd_info as hint to ioctl_decode_command_number().
* src/term.c(term_ioctl_decode_command_number): decode the command in
this earlier stage if the passed fd opens /dev/pts/*.
Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
src/defs.h | 4 ++++
src/ioctl.c | 7 +++++--
src/term.c | 41 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/src/defs.h b/src/defs.h
index 04c985268..1726e83fa 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -658,6 +658,10 @@ struct fd_info {
unsigned int major, minor;
};
+extern int
+term_ioctl_decode_command_number(int code,
+ struct tcb *tcp, struct fd_info *fd_info);
+
/**
* @return 0 on success, -1 on error.
*/
diff --git a/src/ioctl.c b/src/ioctl.c
index b6dcfff99..72e827d9c 100644
--- a/src/ioctl.c
+++ b/src/ioctl.c
@@ -240,7 +240,7 @@ hiddev_decode_number(const unsigned int code)
}
static int
-ioctl_decode_command_number(struct tcb *tcp)
+ioctl_decode_command_number(struct tcb *tcp, struct fd_info *fd_info)
{
const unsigned int code = tcp->u_arg[1];
@@ -292,6 +292,9 @@ ioctl_decode_command_number(struct tcb *tcp)
return 1;
}
return 0;
+ case 'T':
+ return term_ioctl_decode_command_number(code,
+ tcp, fd_info);
default:
return 0;
}
@@ -442,7 +445,7 @@ SYS_FUNC(ioctl)
if (xlat_verbosity == XLAT_STYLE_VERBOSE)
tprint_comment_begin();
if (xlat_verbosity != XLAT_STYLE_RAW) {
- ret = ioctl_decode_command_number(tcp);
+ ret = ioctl_decode_command_number(tcp, fd_info);
if (!(ret & IOCTL_NUMBER_STOP_LOOKUP)) {
iop = ioctl_lookup(tcp->u_arg[1]);
if (iop) {
diff --git a/src/term.c b/src/term.c
index 73cc7d63c..350cc8158 100644
--- a/src/term.c
+++ b/src/term.c
@@ -273,3 +273,44 @@ term_ioctl(struct tcb *const tcp, const unsigned int code,
return RVAL_IOCTL_DECODED;
}
+
+/* The command numbers for TCSETSF, TCSETSW, and TCSETS
+ * conflict with that for SND:
+ *
+ * 0x00005404
+ * { "SNDCTL_TMR_CONTINUE", 0x00005404 },
+ * { "TCSETSF", 0x00005404 },
+ * 0x00005403
+ * { "SNDCTL_TMR_STOP", 0x00005403 },
+ * { "TCSETSW", 0x00005403 },
+ * 0x00005402
+ * { "SNDCTL_TMR_START", 0x00005402 },
+ * { "TCSETS", 0x00005402 },
+ *
+ * This function tries to solve the command name with the
+ * device information associated with FD.
+ */
+extern int
+term_ioctl_decode_command_number(int code,
+ struct tcb *tcp, struct fd_info *fd_info)
+{
+ /* See Documentation/admin-guide/devices.txt of
+ * Linux kernel source tree about the number 136 ~ 143.
+ */
+ if (fd_info
+ && fd_info->type == fd_info_dev_chr
+ && 136 <= fd_info->major && fd_info->major <= 143) {
+ switch (code) {
+ case TCSETSF:
+ tprints("TCSETSF");
+ return IOCTL_NUMBER_STOP_LOOKUP;
+ case TCSETSW:
+ tprints("TCSETSW");
+ return IOCTL_NUMBER_STOP_LOOKUP;
+ case TCSETS:
+ tprints("TCSETS");
+ return IOCTL_NUMBER_STOP_LOOKUP;
+ }
+ }
+ return 0;
+}
--
2.35.1
More information about the Strace-devel
mailing list