From: Dmitry V. Levin Date: Tue, 12 Jan 2016 01:13:48 +0000 (+0000) Subject: Fix struct sigevent decoding for musl X-Git-Tag: v4.12~652 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e714b87064ca296bcfbc1f8ade9e99773e9dc813;p=strace Fix struct sigevent decoding for musl Do not rely on "struct sigevent.__pad" being located at the same address as "struct sigevent.sigev_notify_thread_id", it's not the case with musl libc. Do not rely on struct sigevent definition at all to access sigev_notify_thread_id. * configure.ac (AC_CHECK_MEMBERS): Remove struct sigevent._sigev_un._pad and struct sigevent.__pad. * sigevent.h: New file. * Makefile.am (strace_SOURCES): Add it. * print_sigevent.c: Include it. * print_sigevent.c (struct_sigevent): Remove. (print_sigevent): Update all struct_sigevent users. * tests/timer_create.c: Include "sigevent.h". (main): Use struct_sigevent instead of struct sigevent, all struct sigevent clients changed. --- diff --git a/Makefile.am b/Makefile.am index b107235f..387856f8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Automake input for strace. # # Copyright (c) 2002-2009 Roland McGrath -# Copyright (c) 2006-2015 Dmitry V. Levin +# Copyright (c) 2006-2016 Dmitry V. Levin # Copyright (c) 2008-2015 Mike Frysinger # Copyright (c) 2015 Elvira Khabirova # All rights reserved. @@ -172,6 +172,7 @@ strace_SOURCES = \ seccomp_fprog.h \ sendfile.c \ sigaltstack.c \ + sigevent.h \ signal.c \ signalfd.c \ sigreturn.c \ diff --git a/configure.ac b/configure.ac index 42a6accd..82573e58 100644 --- a/configure.ac +++ b/configure.ac @@ -378,9 +378,7 @@ AC_CHECK_TYPES([struct pt_all_user_regs, struct ia64_fpreg, struct ptrace_peeksi AC_CHECK_MEMBERS([struct utsname.domainname],,, [#include ]) -AC_CHECK_MEMBERS([struct sigevent._sigev_un._pad, - struct sigevent.__pad, - siginfo_t.si_syscall, +AC_CHECK_MEMBERS([siginfo_t.si_syscall, siginfo_t.si_timerid, siginfo_t.si_overrun],,, [#include ]) diff --git a/print_sigevent.c b/print_sigevent.c index 9ef655ae..f8eb8a0f 100644 --- a/print_sigevent.c +++ b/print_sigevent.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2004 Ulrich Drepper - * Copyright (c) 2005-2015 Dmitry V. Levin + * Copyright (c) 2005-2016 Dmitry V. Levin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,12 +29,10 @@ #include "defs.h" #include DEF_MPERS_TYPE(struct_sigevent) - -#include -typedef struct sigevent struct_sigevent; - +#include "sigevent.h" #include MPERS_DEFS +#include #include "xlat/sigev_value.h" MPERS_PRINTER_DECL(void, print_sigevent)(struct tcb *tcp, const long addr) @@ -66,30 +64,13 @@ MPERS_PRINTER_DECL(void, print_sigevent)(struct tcb *tcp, const long addr) switch (sev.sigev_notify) { case SIGEV_THREAD_ID: -#ifndef sigev_notify_thread_id - /* - * _pad[0] is the _tid field which might not be - * present in the userlevel definition of the struct. - */ -# if defined HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD -# define sigev_notify_thread_id _sigev_un._pad[0] -# elif defined HAVE_STRUCT_SIGEVENT___PAD -# define sigev_notify_thread_id __pad[0] -# endif -#endif - -#ifdef sigev_notify_thread_id - tprintf(", sigev_notify_thread_id=%d", - sev.sigev_notify_thread_id); -#else -# warning unfamiliar struct sigevent => incomplete SIGEV_THREAD_ID decoding -#endif + tprintf(", sigev_notify_thread_id=%d", sev.sigev_un.tid); break; case SIGEV_THREAD: tprints(", sigev_notify_function="); - printaddr((unsigned long) sev.sigev_notify_function); + printaddr(sev.sigev_un.sigev_thread.function); tprints(", sigev_notify_attributes="); - printaddr((unsigned long) sev.sigev_notify_attributes); + printaddr(sev.sigev_un.sigev_thread.attribute); break; } tprints("}"); diff --git a/sigevent.h b/sigevent.h new file mode 100644 index 00000000..6b3bacfb --- /dev/null +++ b/sigevent.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Dmitry V. Levin + * 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. + */ + +#ifndef SIGEVENT_H_ +#define SIGEVENT_H_ + +typedef struct { + union { + int sival_int; + unsigned long sival_ptr; + } sigev_value; + int sigev_signo; + int sigev_notify; + union { + int tid; + struct { + unsigned long function; + unsigned long attribute; + } sigev_thread; + } sigev_un; +} struct_sigevent; + +#endif diff --git a/tests/timer_create.c b/tests/timer_create.c index 651b426e..380c978d 100644 --- a/tests/timer_create.c +++ b/tests/timer_create.c @@ -34,21 +34,21 @@ # include # include # include +# include "sigevent.h" int main(void) { int tid[4] = {}; - struct sigevent sev = { + struct_sigevent sev = { .sigev_notify = SIGEV_NONE, .sigev_signo = 0xfacefeed, - .sigev_value.sival_ptr = - (void *) (unsigned long) 0xdeadbeefbadc0ded + .sigev_value.sival_ptr = (unsigned long) 0xdeadbeefbadc0ded }; if (syscall(__NR_timer_create, CLOCK_REALTIME, &sev, &tid[0])) perror_msg_and_skip("timer_create CLOCK_REALTIME"); - printf("timer_create(CLOCK_REALTIME, {sigev_value={int=%d, ptr=%p}" + printf("timer_create(CLOCK_REALTIME, {sigev_value={int=%d, ptr=%#lx}" ", sigev_signo=%u, sigev_notify=SIGEV_NONE}" ", [%d]) = 0\n", sev.sigev_value.sival_int, @@ -59,54 +59,42 @@ main(void) sev.sigev_signo = SIGALRM; if (syscall(__NR_timer_create, CLOCK_MONOTONIC, &sev, &tid[1])) perror_msg_and_skip("timer_create CLOCK_MONOTONIC"); - printf("timer_create(CLOCK_MONOTONIC, {sigev_value={int=%d, ptr=%p}" + printf("timer_create(CLOCK_MONOTONIC, {sigev_value={int=%d, ptr=%#lx}" ", sigev_signo=SIGALRM, sigev_notify=SIGEV_SIGNAL}" ", [%d]) = 0\n", sev.sigev_value.sival_int, sev.sigev_value.sival_ptr, tid[1]); sev.sigev_notify = SIGEV_THREAD; - sev.sigev_notify_function = - (void *) (unsigned long) 0xdeadbeefbadc0ded; - sev.sigev_notify_attributes = - (void *) (unsigned long) 0xcafef00dfacefeed; + sev.sigev_un.sigev_thread.function = (unsigned long) 0xdeadbeefbadc0ded; + sev.sigev_un.sigev_thread.attribute = (unsigned long) 0xcafef00dfacefeed; if (syscall(__NR_timer_create, CLOCK_REALTIME, &sev, &tid[2])) perror_msg_and_skip("timer_create CLOCK_REALTIME"); - printf("timer_create(CLOCK_REALTIME, {sigev_value={int=%d, ptr=%p}" + printf("timer_create(CLOCK_REALTIME, {sigev_value={int=%d, ptr=%#lx}" ", sigev_signo=SIGALRM, sigev_notify=SIGEV_THREAD" - ", sigev_notify_function=%p, sigev_notify_attributes=%p}" + ", sigev_notify_function=%#lx, sigev_notify_attributes=%#lx}" ", [%d]) = 0\n", sev.sigev_value.sival_int, sev.sigev_value.sival_ptr, - sev.sigev_notify_function, - sev.sigev_notify_attributes, + sev.sigev_un.sigev_thread.function, + sev.sigev_un.sigev_thread.attribute, tid[2]); -#ifndef sigev_notify_thread_id -# if defined HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD -# define sigev_notify_thread_id _sigev_un._pad[0] -# elif defined HAVE_STRUCT_SIGEVENT___PAD -# define sigev_notify_thread_id __pad[0] -# endif -#endif /* !sigev_notify_thread_id */ - -#ifdef sigev_notify_thread_id -# ifndef SIGEV_THREAD_ID -# define SIGEV_THREAD_ID 4 -# endif +#ifndef SIGEV_THREAD_ID +# define SIGEV_THREAD_ID 4 +#endif sev.sigev_notify = SIGEV_THREAD_ID; - sev.sigev_notify_thread_id = getpid(); + sev.sigev_un.tid = getpid(); if (syscall(__NR_timer_create, CLOCK_MONOTONIC, &sev, &tid[3])) perror_msg_and_skip("timer_create CLOCK_MONOTONIC"); - printf("timer_create(CLOCK_MONOTONIC, {sigev_value={int=%d, ptr=%p}" + printf("timer_create(CLOCK_MONOTONIC, {sigev_value={int=%d, ptr=%#lx}" ", sigev_signo=SIGALRM, sigev_notify=SIGEV_THREAD_ID" ", sigev_notify_thread_id=%d}" ", [%d]) = 0\n", sev.sigev_value.sival_int, sev.sigev_value.sival_ptr, - sev.sigev_notify_thread_id, + sev.sigev_un.tid, tid[3]); -#endif /* sigev_notify_thread_id */ puts("+++ exited with 0 +++"); return 0;