]> granicus.if.org Git - strace/commitdiff
strace: handle possible NULL from localtime() call
authorEugene Syromyatnikov <evgsyr@gmail.com>
Mon, 26 Mar 2018 06:15:26 +0000 (08:15 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 4 Apr 2018 20:32:42 +0000 (20:32 +0000)
* strace.c (printleader): Print raw tv_sec value if localtime() returned
NULL.
* tests/localtime.c: New file.
* tests/localtime.test: New test.
* tests/Makefile.am (check_PROGRAMS): Add localtime.
(MISC_TESTS): Add localtime.test.
(localtime_LDADD): New variable.
* tests/.gitignore: Add localtime.
* ci/install-dependencies.sh (common_packages): Add faketime.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
Closes: https://github.com/strace/strace/issues/42
ci/install-dependencies.sh
strace.c
tests/.gitignore
tests/Makefile.am
tests/localtime.c [new file with mode: 0644]
tests/localtime.test [new file with mode: 0755]

index 6b411e6e1438d0114029792f8f4d46deccad05d9..8ce5df341e98d857a2be5f517ec63f1b45ff5b34 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh -ex
 
 type sudo >/dev/null 2>&1 && sudo=sudo || sudo=
-common_packages='autoconf automake file gawk gcc-multilib git gzip libunwind8-dev make xz-utils'
+common_packages='autoconf automake faketime file gawk gcc-multilib git gzip libunwind8-dev make xz-utils'
 
 updated=
 apt_get_install()
index c421446f43a2ca4477737d3b64aca94bff2f1c35..314fe0bea6513bcc56170877466b605af9fd2e05 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -664,9 +664,13 @@ printleader(struct tcb *tcp)
                                (long long) ts.tv_sec, (long) ts.tv_nsec / 1000);
                } else {
                        time_t local = ts.tv_sec;
-                       char str[sizeof("HH:MM:SS")];
+                       char str[MAX(sizeof("HH:MM:SS"), sizeof(ts.tv_sec) * 3)];
+                       struct tm *tm = localtime(&local);
 
-                       strftime(str, sizeof(str), "%T", localtime(&local));
+                       if (tm)
+                               strftime(str, sizeof(str), "%T", tm);
+                       else
+                               xsprintf(str, "%lld", (long long) local);
                        if (tflag > 1)
                                tprintf("%s.%06ld ",
                                        str, (long) ts.tv_nsec / 1000);
index d55ee490a707cc06db938f13941e3cf3c97eed0d..9cfa7d54da9659e4c48d0802a05d5b2a0a9ee559 100644 (file)
@@ -173,6 +173,7 @@ link
 linkat
 list_sigaction_signum
 llseek
+localtime
 lookup_dcookie
 lseek
 lstat
index e24efe4e94d41df53ed65f934366cbce608c9c47..d88a09bc28a19f9c7b9e01e73301b55ef302b1f3 100644 (file)
@@ -119,6 +119,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
        is_linux_mips_n64 \
        ksysent \
        list_sigaction_signum \
+       localtime \
        mmsg-silent \
        mmsg_name-v \
        msg_control-v \
@@ -175,6 +176,7 @@ filter_unavailable_LDADD = -lpthread $(LDADD)
 fstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 fstatat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 ftruncate64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
+localtime_LDADD = $(clock_LIBS) $(LDADD)
 lstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 mmap64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 mq_LDADD = $(mq_LIBS) $(LDADD)
@@ -289,6 +291,7 @@ MISC_TESTS = \
        inject-nf.test \
        interactive_block.test \
        ksysent.test \
+       localtime.test \
        opipe.test \
        options-syntax.test \
        pc.test \
diff --git a/tests/localtime.c b/tests/localtime.c
new file mode 100644 (file)
index 0000000..bae5486
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Check handling of localtime() returning NULL in printleader().
+ *
+ * Copyright (c) 2018 The strace developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <asm/unistd.h>
+
+int
+main(void)
+{
+       struct timespec ts;
+       int pid;
+
+       assert(!clock_gettime(CLOCK_REALTIME, &ts));
+
+       pid = syscall(__NR_gettid);
+
+       /* We expect localtime to fail here */
+       printf("%lld.%06ld gettid() = %d\n",
+              (long long) ts.tv_sec, (long) (ts.tv_nsec / 1000), pid);
+
+       printf("%lld.%06ld +++ exited with 0 +++\n",
+              (long long) ts.tv_sec, (long) (ts.tv_nsec / 1000));
+
+       return 0;
+}
diff --git a/tests/localtime.test b/tests/localtime.test
new file mode 100755 (executable)
index 0000000..d025b77
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Check handling of localtime() failure in printleader().
+#
+# Copyright (c) 2018 The strace developers.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+. "${srcdir=.}/init.sh"
+
+check_prog faketime
+faketime -f +1000000000000000000x0 ../$NAME | grep -q '^100000000' \
+       || framework_skip_ 'faketime failed to fake time'
+
+STRACE="faketime -f +1000000000000000000x0 $STRACE"
+
+run_strace_match_diff -tt -a10 -e trace=gettid