From: Eugene Syromyatnikov Date: Mon, 26 Mar 2018 06:15:26 +0000 (+0200) Subject: strace: handle possible NULL from localtime() call X-Git-Tag: v4.22~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a02a583b3fca3f9e4fe6d0d68114eb3cc20f3810;p=strace strace: handle possible NULL from localtime() call * 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 Closes: https://github.com/strace/strace/issues/42 --- diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 6b411e6e..8ce5df34 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -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() diff --git a/strace.c b/strace.c index c421446f..314fe0be 100644 --- 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); diff --git a/tests/.gitignore b/tests/.gitignore index d55ee490..9cfa7d54 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -173,6 +173,7 @@ link linkat list_sigaction_signum llseek +localtime lookup_dcookie lseek lstat diff --git a/tests/Makefile.am b/tests/Makefile.am index e24efe4e..d88a09bc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 00000000..bae54867 --- /dev/null +++ b/tests/localtime.c @@ -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 +#include +#include +#include + +#include + +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 index 00000000..d025b77f --- /dev/null +++ b/tests/localtime.test @@ -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