Bug 1779312 - Replace uses of strerror in Linux sandbox code. r=glandium

`strerror` is async signal unsafe, and we're using it in contexts where
that's a problem: in particular in the child process after `clone()`ing,
where it can deadlock if it takes locks the parents' other threads had
held (or cause other undefined behavior), but also in the SIGSYS handler
if it's nested inside an async signal.  It's also thread-unsafe.

This is mostly a mechanical replacement with the new `SANDBOX_LOG_ERRNO`
or `SANDBOX_LOG_WITH_ERROR`; two messages had the error string in the
middle and have been adjusted.

Differential Revision: https://phabricator.services.mozilla.com/D152099
This commit is contained in:
Jed Davis 2022-07-27 19:41:05 +00:00
parent 05621d57dc
commit 4552fc73a3
6 changed files with 27 additions and 32 deletions

View File

@ -222,21 +222,20 @@ static void InstallSigSysHandler(void) {
if (!aUseTSync && errno == ETXTBSY) {
return false;
}
SANDBOX_LOG("prctl(PR_SET_NO_NEW_PRIVS) failed: %s", strerror(errno));
SANDBOX_LOG_ERRNO("prctl(PR_SET_NO_NEW_PRIVS) failed");
MOZ_CRASH("prctl(PR_SET_NO_NEW_PRIVS)");
}
if (aUseTSync) {
if (syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER,
SECCOMP_FILTER_FLAG_TSYNC, aProg) != 0) {
SANDBOX_LOG("thread-synchronized seccomp failed: %s", strerror(errno));
SANDBOX_LOG_ERRNO("thread-synchronized seccomp failed");
MOZ_CRASH("seccomp+tsync failed, but kernel supports tsync");
}
} else {
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, (unsigned long)aProg, 0,
0)) {
SANDBOX_LOG("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed: %s",
strerror(errno));
SANDBOX_LOG_ERRNO("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed");
MOZ_CRASH("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)");
}
}
@ -316,7 +315,7 @@ static void BroadcastSetThreadSandbox(const sock_fprog* aFilter) {
myTid = syscall(__NR_gettid);
taskdp = opendir("/proc/self/task");
if (taskdp == nullptr) {
SANDBOX_LOG("opendir /proc/self/task: %s\n", strerror(errno));
SANDBOX_LOG_ERRNO("opendir /proc/self/task");
MOZ_CRASH("failed while trying to open directory /proc/self/task");
}
@ -352,7 +351,7 @@ static void BroadcastSetThreadSandbox(const sock_fprog* aFilter) {
sandboxProgress = true;
continue;
}
SANDBOX_LOG("tgkill(%d,%d): %s\n", pid, tid, strerror(errno));
SANDBOX_LOG_ERRNO("tgkill(%d,%d)", pid, tid);
MOZ_CRASH("failed while trying to send a signal to a thread");
}
// It's unlikely, but if the thread somehow manages to exit
@ -380,7 +379,7 @@ static void BroadcastSetThreadSandbox(const sock_fprog* aFilter) {
if (syscall(__NR_futex, reinterpret_cast<int*>(&gSetSandboxDone),
FUTEX_WAIT, 0, &futexTimeout) != 0) {
if (errno != EWOULDBLOCK && errno != ETIMEDOUT && errno != EINTR) {
SANDBOX_LOG("FUTEX_WAIT: %s\n", strerror(errno));
SANDBOX_LOG_ERRNO("FUTEX_WAIT");
MOZ_CRASH("failed during FUTEX_WAIT");
}
}
@ -664,8 +663,7 @@ void SetMediaPluginSandbox(const char* aFilePath) {
SandboxOpenedFile plugin(aFilePath);
if (!plugin.IsOpen()) {
SANDBOX_LOG("failed to open plugin file %s: %s", aFilePath,
strerror(errno));
SANDBOX_LOG_ERRNO("failed to open plugin file %s", aFilePath);
MOZ_CRASH("failed while trying to open the plugin file ");
}

View File

@ -45,7 +45,7 @@ int SandboxOpenedFile::GetDesc() const {
if (fd >= 0) {
fd = dup(fd);
if (fd < 0) {
SANDBOX_LOG("dup: %s", strerror(errno));
SANDBOX_LOG_ERRNO("dup");
}
}
} else {

View File

@ -81,7 +81,7 @@ void SandboxReporterClient::SendReport(const SandboxReport& aReport) {
if (sent != sizeof(SandboxReport)) {
MOZ_DIAGNOSTIC_ASSERT(sent == -1);
SANDBOX_LOG("Failed to report rejected syscall: %s", strerror(errno));
SANDBOX_LOG_ERRNO("Failed to report rejected syscall");
}
}

View File

@ -47,7 +47,7 @@ SandboxBroker::SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
: mChildPid(aChildPid), mPolicy(std::move(aPolicy)) {
int fds[2];
if (0 != socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, fds)) {
SANDBOX_LOG("SandboxBroker: socketpair failed: %s", strerror(errno));
SANDBOX_LOG_ERRNO("SandboxBroker: socketpair failed");
mFileDesc = -1;
aClientFd = -1;
return;
@ -56,7 +56,7 @@ SandboxBroker::SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
aClientFd = fds[1];
if (!PlatformThread::Create(0, this, &mThread)) {
SANDBOX_LOG("SandboxBroker: thread creation failed: %s", strerror(errno));
SANDBOX_LOG_ERRNO("SandboxBroker: thread creation failed");
close(mFileDesc);
close(aClientFd);
mFileDesc = -1;
@ -728,7 +728,7 @@ void SandboxBroker::ThreadMain(void) {
// at least in some cases, but protocol violation indicates a
// hostile client, so terminate the broker instead.
if (recvd < 0) {
SANDBOX_LOG("bad read from pid %d: %s", mChildPid, strerror(errno));
SANDBOX_LOG_ERRNO("bad read from pid %d", mChildPid);
shutdown(mFileDesc, SHUT_RD);
break;
}
@ -1027,8 +1027,7 @@ void SandboxBroker::ThreadMain(void) {
const size_t numIO = ios[1].iov_len > 0 ? 2 : 1;
const ssize_t sent = SendWithFd(respfd, ios, numIO, openedFd);
if (sent < 0) {
SANDBOX_LOG("failed to send broker response to pid %d: %s", mChildPid,
strerror(errno));
SANDBOX_LOG_ERRNO("failed to send broker response to pid %d", mChildPid);
} else {
MOZ_ASSERT(static_cast<size_t>(sent) == ios[0].iov_len + ios[1].iov_len);
}
@ -1071,12 +1070,10 @@ void SandboxBroker::AuditPermissive(int aOp, int aFlags, int aPerms,
errno = 0;
}
SANDBOX_LOG(
SANDBOX_LOG_ERRNO(
"SandboxBroker: would have denied op=%s rflags=%o perms=%d path=%s for "
"pid=%d"
" permissive=1 error=\"%s\"",
OperationDescription[aOp], aFlags, aPerms, aPath, mChildPid,
strerror(errno));
"pid=%d permissive=1; real status",
OperationDescription[aOp], aFlags, aPerms, aPath, mChildPid);
}
void SandboxBroker::AuditDenial(int aOp, int aFlags, int aPerms,

View File

@ -130,10 +130,10 @@ static bool IsGraphicsOkWithoutNetwork() {
accessFlags = R_OK | W_OK;
}
if (access(socketPath.get(), accessFlags) != 0) {
SANDBOX_LOG(
"%s is inaccessible (%s); can't isolate network namespace in"
SANDBOX_LOG_ERRNO(
"%s is inaccessible; can't isolate network namespace in"
" content processes",
socketPath.get(), strerror(errno));
socketPath.get());
return false;
}
}
@ -417,7 +417,7 @@ SandboxFork::SandboxFork(int aFlags, bool aChroot, int aServerFd, int aClientFd)
int fds[2];
int rv = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
if (rv != 0) {
SANDBOX_LOG("socketpair: %s", strerror(errno));
SANDBOX_LOG_ERRNO("socketpair");
MOZ_CRASH("socketpair failed");
}
mChrootClient = fds[0];
@ -452,7 +452,7 @@ static void BlockAllSignals(sigset_t* aOldSigs) {
MOZ_RELEASE_ASSERT(rv == 0);
rv = pthread_sigmask(SIG_BLOCK, &allSigs, aOldSigs);
if (rv != 0) {
SANDBOX_LOG("pthread_sigmask (block all): %s", strerror(rv));
SANDBOX_LOG_WITH_ERROR(rv, "pthread_sigmask (block all)");
MOZ_CRASH("pthread_sigmask");
}
}
@ -463,7 +463,7 @@ static void RestoreSignals(const sigset_t* aOldSigs) {
// state right now:
int rv = pthread_sigmask(SIG_SETMASK, aOldSigs, nullptr);
if (rv != 0) {
SANDBOX_LOG("pthread_sigmask (restore): %s", strerror(rv));
SANDBOX_LOG_WITH_ERROR(rv, "pthread_sigmask (restore)");
MOZ_CRASH("pthread_sigmask");
}
}
@ -592,7 +592,7 @@ static void ConfigureUserNamespace(uid_t uid, gid_t gid) {
static void DropAllCaps() {
if (!LinuxCapabilities().SetCurrent()) {
SANDBOX_LOG("capset (drop all): %s", strerror(errno));
SANDBOX_LOG_ERRNO("capset (drop all)");
}
}
@ -656,7 +656,7 @@ void SandboxFork::StartChrootServer() {
LinuxCapabilities caps;
caps.Effective(CAP_SYS_CHROOT) = true;
if (!caps.SetCurrent()) {
SANDBOX_LOG("capset (chroot helper): %s", strerror(errno));
SANDBOX_LOG_ERRNO("capset (chroot helper)");
MOZ_DIAGNOSTIC_ASSERT(false);
}

View File

@ -50,14 +50,14 @@ bool SandboxReporter::Init() {
int fds[2];
if (0 != socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, fds)) {
SANDBOX_LOG("SandboxReporter: socketpair failed: %s", strerror(errno));
SANDBOX_LOG_ERRNO("SandboxReporter: socketpair failed");
return false;
}
mClientFd = fds[0];
mServerFd = fds[1];
if (!PlatformThread::Create(0, this, &mThread)) {
SANDBOX_LOG("SandboxReporter: thread creation failed: %s", strerror(errno));
SANDBOX_LOG_ERRNO("SandboxReporter: thread creation failed");
close(mClientFd);
close(mServerFd);
mClientFd = mServerFd = -1;
@ -259,7 +259,7 @@ void SandboxReporter::ThreadMain(void) {
if (errno == EINTR) {
continue;
}
SANDBOX_LOG("SandboxReporter: recvmsg: %s", strerror(errno));
SANDBOX_LOG_ERRNO("SandboxReporter: recvmsg");
}
if (recvd <= 0) {
break;