fune/security/sandbox/linux/SandboxOpenedFiles.cpp
Jed Davis 4552fc73a3 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
2022-07-27 19:41:05 +00:00

77 lines
1.9 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SandboxOpenedFiles.h"
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <utility>
#include "SandboxLogging.h"
namespace mozilla {
// The default move constructor almost works, but Atomic isn't
// move-constructable and the fd needs some special handling.
SandboxOpenedFile::SandboxOpenedFile(SandboxOpenedFile&& aMoved)
: mPath(std::move(aMoved.mPath)),
mMaybeFd(aMoved.TakeDesc()),
mDup(aMoved.mDup),
mExpectError(aMoved.mExpectError) {}
SandboxOpenedFile::SandboxOpenedFile(const char* aPath, Dup aDup)
: mPath(aPath), mDup(aDup == Dup::YES), mExpectError(false) {
MOZ_ASSERT(aPath[0] == '/', "path should be absolute");
int fd = open(aPath, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
mExpectError = true;
}
mMaybeFd = fd;
}
SandboxOpenedFile::SandboxOpenedFile(const char* aPath, Error)
: mPath(aPath), mMaybeFd(-1), mDup(false), mExpectError(true) {}
int SandboxOpenedFile::GetDesc() const {
int fd;
if (mDup) {
fd = mMaybeFd;
if (fd >= 0) {
fd = dup(fd);
if (fd < 0) {
SANDBOX_LOG_ERRNO("dup");
}
}
} else {
fd = TakeDesc();
}
if (fd < 0 && !mExpectError) {
SANDBOX_LOG("unexpected multiple open of file %s", Path());
}
return fd;
}
SandboxOpenedFile::~SandboxOpenedFile() {
int fd = TakeDesc();
if (fd >= 0) {
close(fd);
}
}
int SandboxOpenedFiles::GetDesc(const char* aPath) const {
for (const auto& file : mFiles) {
if (strcmp(file.Path(), aPath) == 0) {
return file.GetDesc();
}
}
SANDBOX_LOG("attempt to open unexpected file %s", aPath);
return -1;
}
} // namespace mozilla