[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