1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Assertions.h"
8 #include "mozilla/Atomics.h"
9 #include "mozilla/Types.h"
16 #include <sys/inotify.h>
18 # include <X11/Xlib.h>
21 // Signal number used to enable seccomp on each thread.
22 extern mozilla::Atomic
<int> gSeccompTsyncBroadcastSignum
;
24 static bool SigSetNeedsFixup(const sigset_t
* aSet
) {
25 int tsyncSignum
= gSeccompTsyncBroadcastSignum
;
27 return aSet
!= nullptr &&
28 (sigismember(aSet
, SIGSYS
) ||
29 (tsyncSignum
!= 0 && sigismember(aSet
, tsyncSignum
)));
32 static void SigSetFixup(sigset_t
* aSet
) {
33 int tsyncSignum
= gSeccompTsyncBroadcastSignum
;
34 int rv
= sigdelset(aSet
, SIGSYS
);
35 MOZ_RELEASE_ASSERT(rv
== 0);
36 if (tsyncSignum
!= 0) {
37 rv
= sigdelset(aSet
, tsyncSignum
);
38 MOZ_RELEASE_ASSERT(rv
== 0);
42 // This file defines a hook for sigprocmask() and pthread_sigmask().
43 // Bug 1176099: some threads block SIGSYS signal which breaks our seccomp-bpf
44 // sandbox. To avoid this, we intercept the call and remove SIGSYS.
46 // ENOSYS indicates an error within the hook function itself.
47 static int HandleSigset(int (*aRealFunc
)(int, const sigset_t
*, sigset_t
*),
48 int aHow
, const sigset_t
* aSet
, sigset_t
* aOldSet
,
59 // Avoid unnecessary work
60 if (aHow
== SIG_UNBLOCK
|| !SigSetNeedsFixup(aSet
)) {
61 return aRealFunc(aHow
, aSet
, aOldSet
);
64 sigset_t newSet
= *aSet
;
66 return aRealFunc(aHow
, &newSet
, aOldSet
);
69 extern "C" MOZ_EXPORT
int sigprocmask(int how
, const sigset_t
* set
,
71 static auto sRealFunc
=
72 (int (*)(int, const sigset_t
*, sigset_t
*))dlsym(RTLD_NEXT
, "sigprocmask");
74 return HandleSigset(sRealFunc
, how
, set
, oldset
, true);
77 extern "C" MOZ_EXPORT
int pthread_sigmask(int how
, const sigset_t
* set
,
79 static auto sRealFunc
= (int (*)(int, const sigset_t
*, sigset_t
*))dlsym(
80 RTLD_NEXT
, "pthread_sigmask");
82 return HandleSigset(sRealFunc
, how
, set
, oldset
, false);
85 extern "C" MOZ_EXPORT
int sigaction(int signum
, const struct sigaction
* act
,
86 struct sigaction
* oldact
) {
87 static auto sRealFunc
=
88 (int (*)(int, const struct sigaction
*, struct sigaction
*))dlsym(
89 RTLD_NEXT
, "sigaction");
96 if (act
== nullptr || !SigSetNeedsFixup(&act
->sa_mask
)) {
97 return sRealFunc(signum
, act
, oldact
);
100 struct sigaction newact
= *act
;
101 SigSetFixup(&newact
.sa_mask
);
102 return sRealFunc(signum
, &newact
, oldact
);
105 extern "C" MOZ_EXPORT
int inotify_init(void) { return inotify_init1(0); }
107 extern "C" MOZ_EXPORT
int inotify_init1(int flags
) {