[PATCH] fix segmentation fault caused by scsi_sprintf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



1, Test with gcc-5.4/glibc-2.23 and gcc-7.3/libc-2.27, hit segmentation fault
like this:
Program terminated with signal SIGSEGV, Segmentation fault.
 #0  0x00007f58a410ccc0 in _IO_vfprintf_internal (s=s@entry=0x7ffdec98fdc0, format=<optimized out>,
    format@entry=0x432bc8 "d Mode page %d (0x%02x), index: %d\n", ap=ap@entry=0x7ffdec98ff38) at vfprintf.c:1632
 #1  0x00007f58a41d4896 in ___vsnprintf_chk (s=0x7ffdec990010 "", maxlen=<optimized out>, flags=1,
    slen=<optimized out>, format=0x432bc8 "d Mode page %d (0x%02x), index: %d\n", args=args@entry=0x7ffdec98ff38)
    at vsnprintf_chk.c:63
 #2  0x00007f58a41d47f8 in ___snprintf_chk (s=<optimized out>, maxlen=<optimized out>, flags=<optimized out>,
    slen=<optimized out>, format=<optimized out>) at snprintf_chk.c:34
 #3  0x000000000041f6e7 in scsi_sprintf (str=<optimized out>, size=<optimized out>, format=0x432a88 "%-*s",
    format=0x432a88 "%-*s") at util.h:255
 #4  0x000000000042043a in spc_inquiry (host_no=<optimized out>, cmd=0x123ff40) at spc.c:343
 #5  0x000000000041935a in target_cmd_perform (tid=<optimized out>, cmd=0x123ff40) at target.c:1168
 #6  0x000000000040a66b in iscsi_target_cmd_queue (task=0x123fe70) at iscsi/iscsid.c:1387
 #7  iscsi_scsi_cmd_execute (task=task@entry=0x123fe70) at iscsi/iscsid.c:1407
 #8  0x000000000040a93e in iscsi_task_execute (task=task@entry=0x123fe70) at iscsi/iscsid.c:1527
 #9  0x000000000040b817 in iscsi_task_queue (task=0x123fe70) at iscsi/iscsid.c:1614
 #10 iscsi_task_rx_done (conn=0x123b360) at iscsi/iscsid.c:1744
 #11 iscsi_rx_handler (conn=conn@entry=0x123b360) at iscsi/iscsid.c:2222
 #12 0x0000000000411f48 in iscsi_tcp_event_handler (fd=<optimized out>, events=1, data=0x123b360)
    at iscsi/iscsi_tcp.c:278
 #13 0x00000000004152df in event_loop () at tgtd.c:432
 #14 0x0000000000407191 in main (argc=<optimized out>, argv=<optimized out>) at tgtd.c:624

2, Test with gcc-6.3/libc-2.24, tgtd costs about 3s while running spc_inquiry,
and get the perf report like this:
 # Children      Self  Command  Shared Object      Symbol
 # ........  ........  .......  .................  ......................
 #
     50.06%    50.06%  tgtd     libc-2.24.so       [.] _IO_default_xsputn
     46.20%    46.20%  tgtd     libc-2.24.so       [.] _IO_strn_overflow
      3.75%     3.75%  tgtd     libc-2.24.so       [.] _IO_padn

It seems that va_start(va_list ap, last) function can not work well with
format "%-*s". So re-write scsi_sprintf to avoid this case.

And this patch is tested with gcc-5.4, gcc-6.3 and gcc-7.3, all cases
work well.

Signed-off-by: zhenwei pi <pizhenwei@xxxxxxxxxxxxx>
---
 usr/util.h | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/usr/util.h b/usr/util.h
index fe82554..eefce74 100644
--- a/usr/util.h
+++ b/usr/util.h
@@ -240,18 +240,12 @@ static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
 		(((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
 }
 
-static inline int scsi_sprintf(char *str, size_t size, const char *format, ...)
-{
-	va_list args;
-	char buf[size + 1];
-	int n;
-
-	memset(buf, 0, sizeof(buf));
-	va_start(args, format);
-	n = snprintf(buf, sizeof(buf), format, args);
-	va_end(args);
-	memcpy(str, buf, size);
-	return n;
-}
+#define scsi_sprintf(str, size, format, ...) \
+	do { \
+		char buf[size + 1]; \
+		memset(buf, 0, sizeof(buf)); \
+		snprintf(buf, sizeof(buf), format, ## __VA_ARGS__); \
+		memcpy(str, buf, size); \
+	} while (0)
 
 #endif
-- 
2.11.0




[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux