[compiler-rt] r312576 - [msan] Check sigset_t and sigaction arguments.
Richard Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 5 17:21:36 PDT 2017
On 5 September 2017 at 14:08, Evgeniy Stepanov via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: eugenis
> Date: Tue Sep 5 14:08:56 2017
> New Revision: 312576
>
> URL: http://llvm.org/viewvc/llvm-project?rev=312576&view=rev
> Log:
> [msan] Check sigset_t and sigaction arguments.
>
> Summary:
> Check sigset_t arguments in ppoll, sig*wait*, sigprocmask
> interceptors, and the entire "struct sigaction" in sigaction. This
> can be done because sigemptyset/sigfullset are intercepted and
> signal masks should be correctly marked as initialized.
>
> Reviewers: vitalybuka
>
> Subscribers: kubamracek, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D37367
>
> Added:
> compiler-rt/trunk/test/msan/Linux/poll.cc
> compiler-rt/trunk/test/msan/sigaction.cc
> Modified:
> compiler-rt/trunk/lib/msan/msan_interceptors.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_
> common_interceptors.inc
> compiler-rt/trunk/test/msan/sigwait.cc
>
> Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> msan/msan_interceptors.cc?rev=312576&r1=312575&r2=312576&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Sep 5 14:08:56
> 2017
> @@ -983,11 +983,21 @@ static void SignalAction(int signo, void
> cb(signo, si, uc);
> }
>
> +static void read_sigaction(const __sanitizer_sigaction *act) {
> + CHECK_UNPOISONED(&act->sa_flags, sizeof(act->sa_flags));
> + if (act->sa_flags & __sanitizer::sa_siginfo)
> + CHECK_UNPOISONED(&act->sigaction, sizeof(act->sigaction));
> + else
> + CHECK_UNPOISONED(&act->handler, sizeof(act->handler));
> + CHECK_UNPOISONED(&act->sa_mask, sizeof(act->sa_mask));
> +}
> +
> INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
> __sanitizer_sigaction *oldact) {
> ENSURE_MSAN_INITED();
> // FIXME: check that *act is unpoisoned.
>
Can this FIXME be removed now?
> // That requires intercepting all of sigemptyset, sigfillset, etc.
> + if (act) read_sigaction(act);
> int res;
> if (flags()->wrap_signals) {
> SpinMutexLock lock(&sigactions_mu);
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_
> common_interceptors.inc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> sanitizer_common/sanitizer_common_interceptors.inc?rev=
> 312576&r1=312575&r2=312576&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> Tue Sep 5 14:08:56 2017
> @@ -3589,7 +3589,7 @@ INTERCEPTOR(int, ppoll, __sanitizer_poll
> if (fds && nfds) read_pollfd(ctx, fds, nfds);
> if (timeout_ts)
> COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
> - // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
> + if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask,
> sizeof(*sigmask));
> int res =
> COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts,
> sigmask);
> if (fds && nfds) write_pollfd(ctx, fds, nfds);
> @@ -3630,7 +3630,7 @@ INTERCEPTOR(int, wordexp, char *s, __san
> INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
> void *ctx;
> COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
> - // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
> + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
> // FIXME: under ASan the call below may write to freed memory and
> corrupt
> // its metadata. See
> // https://github.com/google/sanitizers/issues/321.
> @@ -3647,7 +3647,7 @@ INTERCEPTOR(int, sigwait, __sanitizer_si
> INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
> void *ctx;
> COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
> - // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
> + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
> // FIXME: under ASan the call below may write to freed memory and
> corrupt
> // its metadata. See
> // https://github.com/google/sanitizers/issues/321.
> @@ -3666,7 +3666,7 @@ INTERCEPTOR(int, sigtimedwait, __sanitiz
> void *ctx;
> COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
> if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout,
> struct_timespec_sz);
> - // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
> + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
> // FIXME: under ASan the call below may write to freed memory and
> corrupt
> // its metadata. See
> // https://github.com/google/sanitizers/issues/321.
> @@ -3729,7 +3729,7 @@ INTERCEPTOR(int, sigprocmask, int how, _
> __sanitizer_sigset_t *oldset) {
> void *ctx;
> COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
> - // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
> + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
> // FIXME: under ASan the call below may write to freed memory and
> corrupt
> // its metadata. See
> // https://github.com/google/sanitizers/issues/321.
>
> Added: compiler-rt/trunk/test/msan/Linux/poll.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/
> test/msan/Linux/poll.cc?rev=312576&view=auto
> ============================================================
> ==================
> --- compiler-rt/trunk/test/msan/Linux/poll.cc (added)
> +++ compiler-rt/trunk/test/msan/Linux/poll.cc Tue Sep 5 14:08:56 2017
> @@ -0,0 +1,42 @@
> +// RUN: %clangxx_msan -O0 -std=c++11 -g %s -o %t
> +// RUN: %run %t _ 2>&1 | FileCheck %s --check-prefix=CLEAN
> +// RUN: not %run %t A 2>&1 | FileCheck %s --check-prefix=A
> +// RUN: not %run %t B 2>&1 | FileCheck %s --check-prefix=B
> +
> +#include <assert.h>
> +#include <poll.h>
> +#include <signal.h>
> +#include <stdio.h>
> +
> +#include <sanitizer/msan_interface.h>
> +
> +int main(int argc, char **argv) {
> + char T = argv[1][0];
> +
> + struct timespec ts;
> + ts.tv_sec = 0;
> + ts.tv_nsec = 1000;
> + int res = ppoll(nullptr, 0, &ts, nullptr);
> + assert(res == 0);
> +
> + if (T == 'A') {
> + __msan_poison(&ts.tv_sec, sizeof(ts.tv_sec));
> + ppoll(nullptr, 0, &ts, nullptr);
> + // A: use-of-uninitialized-value
> + }
> +
> + // A-NOT: ==1
> + // B: ==1
> + fprintf(stderr, "==1\n");
> +
> + sigset_t sig;
> + if (T != 'B')
> + sigemptyset(&sig);
> + ppoll(nullptr, 0, &ts, &sig);
> + // B: use-of-uninitialized-value
> +
> + // B-NOT: ==2
> + // CLEAN: ==2
> + fprintf(stderr, "==2\n");
> + return 0;
> +}
>
> Added: compiler-rt/trunk/test/msan/sigaction.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/
> test/msan/sigaction.cc?rev=312576&view=auto
> ============================================================
> ==================
> --- compiler-rt/trunk/test/msan/sigaction.cc (added)
> +++ compiler-rt/trunk/test/msan/sigaction.cc Tue Sep 5 14:08:56 2017
> @@ -0,0 +1,47 @@
> +// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t
> +// RUN: %run %t __
> +// RUN: not %run %t A_ 2>&1 | FileCheck %s
> +// RUN: not %run %t AH 2>&1 | FileCheck %s
> +// RUN: not %run %t B_ 2>&1 | FileCheck %s
> +// RUN: not %run %t BH 2>&1 | FileCheck %s
> +// RUN: not %run %t C_ 2>&1 | FileCheck %s
> +// RUN: not %run %t CH 2>&1 | FileCheck %s
> +
> +#include <assert.h>
> +#include <signal.h>
> +#include <string.h>
> +#include <sys/time.h>
> +#include <unistd.h>
> +
> +#include <sanitizer/msan_interface.h>
> +
> +void handler(int) {}
> +void action(int, siginfo_t *, void *) {}
> +
> +int main(int argc, char **argv) {
> + char T = argv[1][0];
> + char H = argv[1][1];
> + struct sigaction sa;
> + memset(&sa, 0, sizeof(sa));
> + if (H == 'H') {
> + sa.sa_handler = handler;
> + } else {
> + sa.sa_sigaction = action;
> + sa.sa_flags = SA_SIGINFO;
> + }
> +
> + if (T == 'A') {
> + if (H == 'H')
> + __msan_poison(&sa.sa_handler, sizeof(sa.sa_handler));
> + else
> + __msan_poison(&sa.sa_sigaction, sizeof(sa.sa_sigaction));
> + }
> + if (T == 'B')
> + __msan_poison(&sa.sa_flags, sizeof(sa.sa_flags));
> + if (T == 'C')
> + __msan_poison(&sa.sa_mask, sizeof(sa.sa_mask));
> + // CHECK: use-of-uninitialized-value
> + int res = sigaction(SIGUSR1, &sa, nullptr);
> + assert(res == 0);
> + return 0;
> +}
>
> Modified: compiler-rt/trunk/test/msan/sigwait.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/
> test/msan/sigwait.cc?rev=312576&r1=312575&r2=312576&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/test/msan/sigwait.cc (original)
> +++ compiler-rt/trunk/test/msan/sigwait.cc Tue Sep 5 14:08:56 2017
> @@ -1,16 +1,21 @@
> // RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && %run %t
> +// RUN: %clangxx_msan -DPOSITIVE -std=c++11 -O0 -g %s -o %t && not %run
> %t 2>&1 | FileCheck %s
>
> #include <assert.h>
> -#include <sanitizer/msan_interface.h>
> #include <signal.h>
> #include <sys/time.h>
> #include <unistd.h>
>
> +#include <sanitizer/msan_interface.h>
> +
> void test_sigwait() {
> sigset_t s;
> +#ifndef POSITIVE
> sigemptyset(&s);
> sigaddset(&s, SIGUSR1);
> +#endif
> sigprocmask(SIG_BLOCK, &s, 0);
> + // CHECK: MemorySanitizer: use-of-uninitialized-value
>
> if (pid_t pid = fork()) {
> kill(pid, SIGUSR1);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170905/2b37d9b3/attachment.html>
More information about the llvm-commits
mailing list