From 0bf3f6915282dc8df2f02e6da30814951e52d179 Mon Sep 17 00:00:00 2001
From: zhenwei pi <pizhenwei@bytedance.com>
Date: Sun, 17 Mar 2019 11:44:00 +0800
Subject: [PATCH] fix segmentation fault caused by scsi_sprintf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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@bytedance.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
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.20.1