Fix fd leak

Support swapping and move assignment in FDCloser

PiperOrigin-RevId: 351119550
Change-Id: I9865d2fcad029a440cab60328b8731f8e1dc340f
This commit is contained in:
Wiktor Garbacz 2021-01-11 03:33:03 -08:00 committed by Copybara-Service
parent e94ba3a16b
commit 451c24c1c4
4 changed files with 18 additions and 6 deletions

View File

@ -33,6 +33,7 @@ cc_binary(
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2:util",
"//sandboxed_api/sandbox2/util:bpf_helper",
"//sandboxed_api/sandbox2/util:fileops",
"//sandboxed_api/util:flags",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/strings",

View File

@ -43,6 +43,7 @@
#include "sandboxed_api/sandbox2/sandbox2.h"
#include "sandboxed_api/sandbox2/util.h"
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
#include "sandboxed_api/sandbox2/util/fileops.h"
using std::string;
@ -117,10 +118,11 @@ int main(int argc, char** argv) {
}
auto executor = absl::make_unique<sandbox2::Executor>(argv[1], args, envp);
int recv_fd1 = -1;
sandbox2::file_util::fileops::FDCloser recv_fd1;
if (absl::GetFlag(FLAGS_sandbox2tool_redirect_fd1)) {
// Make the sandboxed process' fd be available as fd in the current process.
recv_fd1 = executor->ipc()->ReceiveFd(STDOUT_FILENO);
recv_fd1 = sandbox2::file_util::fileops::FDCloser(
executor->ipc()->ReceiveFd(STDOUT_FILENO));
}
executor
@ -206,7 +208,7 @@ int main(int argc, char** argv) {
sleep(1);
s2.DumpStackTrace();
} else if (absl::GetFlag(FLAGS_sandbox2tool_redirect_fd1)) {
OutputFD(recv_fd1);
OutputFD(recv_fd1.get());
// We couldn't receive more data from the sandboxee's STDOUT_FILENO, but
// the process could still be running. Kill it unconditionally. A correct
// final status code will be reported instead of Result::EXTERNAL_KILL.

View File

@ -34,7 +34,7 @@ FDCloser::~FDCloser() { Close(); }
bool FDCloser::Close() {
int fd = Release();
if (fd == -1) {
if (fd == kCanonicalInvalidFd) {
return false;
}
return close(fd) == 0 || errno == EINTR;
@ -42,7 +42,7 @@ bool FDCloser::Close() {
int FDCloser::Release() {
int ret = fd_;
fd_ = -1;
fd_ = kCanonicalInvalidFd;
return ret;
}

View File

@ -16,6 +16,7 @@
#define SANDBOXED_API_SANDBOX2_UTIL_FILEOPS_H_
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
@ -28,17 +29,25 @@ namespace fileops {
// RAII helper class to automatically close file descriptors.
class FDCloser {
public:
explicit FDCloser(int fd) : fd_{fd} {}
explicit FDCloser(int fd = kCanonicalInvalidFd) : fd_{fd} {}
FDCloser(const FDCloser&) = delete;
FDCloser& operator=(const FDCloser&) = delete;
FDCloser(FDCloser&& other) : fd_(other.Release()) {}
FDCloser& operator=(FDCloser&& other) {
Swap(other);
other.Close();
return *this;
}
~FDCloser();
int get() const { return fd_; }
bool Close();
void Swap(FDCloser& other) { std::swap(fd_, other.fd_); }
int Release();
private:
static constexpr int kCanonicalInvalidFd = -1;
int fd_;
};