mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Fix fd leak
Support swapping and move assignment in FDCloser PiperOrigin-RevId: 351119550 Change-Id: I9865d2fcad029a440cab60328b8731f8e1dc340f
This commit is contained in:
parent
e94ba3a16b
commit
451c24c1c4
@ -33,6 +33,7 @@ cc_binary(
|
|||||||
"//sandboxed_api/sandbox2",
|
"//sandboxed_api/sandbox2",
|
||||||
"//sandboxed_api/sandbox2:util",
|
"//sandboxed_api/sandbox2:util",
|
||||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||||
|
"//sandboxed_api/sandbox2/util:fileops",
|
||||||
"//sandboxed_api/util:flags",
|
"//sandboxed_api/util:flags",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "sandboxed_api/sandbox2/sandbox2.h"
|
#include "sandboxed_api/sandbox2/sandbox2.h"
|
||||||
#include "sandboxed_api/sandbox2/util.h"
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||||
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
@ -117,10 +118,11 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
auto executor = absl::make_unique<sandbox2::Executor>(argv[1], args, envp);
|
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)) {
|
if (absl::GetFlag(FLAGS_sandbox2tool_redirect_fd1)) {
|
||||||
// Make the sandboxed process' fd be available as fd in the current process.
|
// 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
|
executor
|
||||||
@ -206,7 +208,7 @@ int main(int argc, char** argv) {
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
s2.DumpStackTrace();
|
s2.DumpStackTrace();
|
||||||
} else if (absl::GetFlag(FLAGS_sandbox2tool_redirect_fd1)) {
|
} 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
|
// We couldn't receive more data from the sandboxee's STDOUT_FILENO, but
|
||||||
// the process could still be running. Kill it unconditionally. A correct
|
// the process could still be running. Kill it unconditionally. A correct
|
||||||
// final status code will be reported instead of Result::EXTERNAL_KILL.
|
// final status code will be reported instead of Result::EXTERNAL_KILL.
|
||||||
|
@ -34,7 +34,7 @@ FDCloser::~FDCloser() { Close(); }
|
|||||||
|
|
||||||
bool FDCloser::Close() {
|
bool FDCloser::Close() {
|
||||||
int fd = Release();
|
int fd = Release();
|
||||||
if (fd == -1) {
|
if (fd == kCanonicalInvalidFd) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return close(fd) == 0 || errno == EINTR;
|
return close(fd) == 0 || errno == EINTR;
|
||||||
@ -42,7 +42,7 @@ bool FDCloser::Close() {
|
|||||||
|
|
||||||
int FDCloser::Release() {
|
int FDCloser::Release() {
|
||||||
int ret = fd_;
|
int ret = fd_;
|
||||||
fd_ = -1;
|
fd_ = kCanonicalInvalidFd;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define SANDBOXED_API_SANDBOX2_UTIL_FILEOPS_H_
|
#define SANDBOXED_API_SANDBOX2_UTIL_FILEOPS_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
@ -28,17 +29,25 @@ namespace fileops {
|
|||||||
// RAII helper class to automatically close file descriptors.
|
// RAII helper class to automatically close file descriptors.
|
||||||
class FDCloser {
|
class FDCloser {
|
||||||
public:
|
public:
|
||||||
explicit FDCloser(int fd) : fd_{fd} {}
|
explicit FDCloser(int fd = kCanonicalInvalidFd) : fd_{fd} {}
|
||||||
FDCloser(const FDCloser&) = delete;
|
FDCloser(const FDCloser&) = delete;
|
||||||
FDCloser& operator=(const FDCloser&) = delete;
|
FDCloser& operator=(const FDCloser&) = delete;
|
||||||
FDCloser(FDCloser&& other) : fd_(other.Release()) {}
|
FDCloser(FDCloser&& other) : fd_(other.Release()) {}
|
||||||
|
FDCloser& operator=(FDCloser&& other) {
|
||||||
|
Swap(other);
|
||||||
|
other.Close();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
~FDCloser();
|
~FDCloser();
|
||||||
|
|
||||||
int get() const { return fd_; }
|
int get() const { return fd_; }
|
||||||
bool Close();
|
bool Close();
|
||||||
|
void Swap(FDCloser& other) { std::swap(fd_, other.fd_); }
|
||||||
int Release();
|
int Release();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr int kCanonicalInvalidFd = -1;
|
||||||
|
|
||||||
int fd_;
|
int fd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user