Bug report and patch for strace's -s option

Zhaolei zhaolei at cn.fujitsu.com
Fri Jul 6 09:53:47 UTC 2007


Hi, everyone

I found a bug of strace when I was using strace with -s option.

# strace-4.5.15/strace -s0 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, ""..., 11) = 11
# strace-4.5.15/strace -s1 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0"..., 11) = 11
# strace-4.5.15/strace -s2 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0"..., 11) = 11
# strace-4.5.15/strace -s3 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0"..., 11) = 11
# strace-4.5.15/strace -s4 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0"..., 11) = 11
# strace-4.5.15/strace -s5 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0"..., 11) = 11
# strace-4.5.15/strace -s6 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "01"..., 11) = 11
# strace-4.5.15/strace -s7 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0123"..., 11) = 11
# strace-4.5.15/strace -s8 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "012345"..., 11) = 11
# strace-4.5.15/strace -s9 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "01234567"..., 11) = 11
#
# # with -xx
# strace-4.5.15/strace -xx -s0 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, ""..., 11) = 11
# strace-4.5.15/strace -xx -s1 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s2 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s3 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s4 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s5 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s6 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s7 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s8 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31"..., 11) = 11
# strace-4.5.15/strace -xx -s9 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31"..., 11) = 11
#
# strace-4.5.15/strace -V
strace -- version 4.5.15

The printed string's length is somehow different with the value
specified by -s option.
I checked the code and found that there's something wrong in the util.c.
( Invalid access to memory location will also happen if the value is set
to less than 6 )
The bug can be fixed with the following patch:

Signed-off-by: "Zhaolei" zhaolei at cn.fujitsu.com

--- util.c	2007-07-06 17:40:26.000000000 +0800
+++ util.c.new	2007-07-06 17:40:26.000000000 +0800
@@ -449,13 +449,16 @@ int len;
 	}
 	if (!str) {
 		if ((str = malloc(max_strlen)) == NULL
-		    || (outstr = malloc(2*max_strlen)) == NULL) {
+			|| (outstr = malloc(max_strlen + 9)) == NULL) {
+			/* Max additional length of outstr is 2 of ["],
+			plus 3 of [.], plus 1 of [\0], and additional
+			3 chars for sprintf(s, "\\x%02x", c). */
 			fprintf(stderr, "out of memory\n");
 			tprintf("%#lx", addr);
 			return;
 		}
 	}
-	outend = outstr + max_strlen * 2 - 10;
+	outend = outstr + max_strlen;
 	if (len < 0) {
 		n = max_strlen;
 		if (umovestr(tcp, addr, n, (char *) str) < 0) {

The following is result outputted by the patched strace:

# strace-4.5.15/strace -s0 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, ""..., 11) = 11
# strace-4.5.15/strace -s1 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0"..., 11) = 11
# strace-4.5.15/strace -s2 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "01"..., 11) = 11
# strace-4.5.15/strace -s3 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "012"..., 11) = 11
# strace-4.5.15/strace -s4 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0123"..., 11) = 11
# strace-4.5.15/strace -s5 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "01234"..., 11) = 11
# strace-4.5.15/strace -s6 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "012345"..., 11) = 11
# strace-4.5.15/strace -s7 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "0123456"..., 11) = 11
# strace-4.5.15/strace -s8 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "01234567"..., 11) = 11
# strace-4.5.15/strace -s9 echo 0123456789 2>&1 1>/dev/null | grep "write("
write(1, "012345678"..., 11) = 11
#
# # with -xx
# strace-4.5.15/strace -xx -s0 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, ""..., 11) = 11
# strace-4.5.15/strace -xx -s1 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s2 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s3 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s4 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30"..., 11) = 11
# strace-4.5.15/strace -xx -s5 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31"..., 11) = 11
# strace-4.5.15/strace -xx -s6 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31"..., 11) = 11
# strace-4.5.15/strace -xx -s7 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31"..., 11) = 11
# strace-4.5.15/strace -xx -s8 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31"..., 11) = 11
# strace-4.5.15/strace -xx -s9 echo 0123456789 2>&1 1>/dev/null | grep
"write("
write(1, "\x30\x31\x32"..., 11) = 11

Regards
Zhaolei







More information about the Strace-devel mailing list