Skip to content

Commit

Permalink
No public description
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 693505976
  • Loading branch information
MediaPipe Team authored and copybara-github committed Nov 6, 2024
1 parent 0f27e9d commit 0529235
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 93 deletions.
1 change: 1 addition & 0 deletions mediapipe/framework/formats/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ cc_test(

cc_library(
name = "unique_fd",
srcs = ["unique_fd.cc"],
hdrs = ["unique_fd.h"],
deps = [
"//mediapipe/framework/port:ret_check",
Expand Down
118 changes: 118 additions & 0 deletions mediapipe/framework/formats/unique_fd.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include "mediapipe/framework/formats/unique_fd.h"

#include <unistd.h>

#include "absl/base/attributes.h"
#include "absl/log/absl_log.h"
#include "absl/status/statusor.h"
#include "mediapipe/framework/port/ret_check.h"

#if (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG)
#define MEDIAPIPE_UNIQUE_FD_USE_FDSAN 1

#include <android/fdsan.h>

#include <cstdint>

#endif // (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG)

namespace mediapipe {

namespace {

#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN)
// Address of the object is used as tag.
uint64_t Tag(UniqueFd* fd) { return reinterpret_cast<uint64_t>(fd); }

// These functions are marked with __attribute__((weak)), so that their
// availability can be determined at runtime. These wrappers will use them
// if available, and fall back to no-ops or regular close on devices older
// than API level 29 or non-bionic or non-production builds.
void FdsanExchangeTag(int fd, uint64_t old_tag, uint64_t new_tag) {
if (android_fdsan_exchange_owner_tag) {
android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
}
}

void FdsanClose(int fd, uint64_t tag) {
if (android_fdsan_close_with_tag) {
if (android_fdsan_close_with_tag(fd, tag) != 0) {
ABSL_LOG(ERROR) << "Failed to close fd: " << fd;
}
return;
}
if (::close(fd) != 0) {
ABSL_LOG(ERROR) << "Failed to close fd: " << fd;
}
}
#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN

} // namespace

UniqueFd& UniqueFd::operator=(UniqueFd&& move) {
if (this == &move) {
return *this;
}

Reset();

if (move.fd_ != -1) {
fd_ = move.fd_;
move.fd_ = -1;
#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN)
// Acquire ownership from the moved-from object.
FdsanExchangeTag(fd_, Tag(&move), Tag(this));
#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN
}

return *this;
}

absl::StatusOr<UniqueFd> UniqueFd::Dup() const {
RET_CHECK(IsValid());
int dup_fd = dup(Get());
return UniqueFd(dup_fd);
}

// Releases ownership of the file descriptor and returns it.
ABSL_MUST_USE_RESULT int UniqueFd::Release() {
if (!IsValid()) {
return -1;
}

int fd = fd_;
fd_ = -1;
#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN)
// Release ownership.
FdsanExchangeTag(fd, Tag(this), 0);
#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN
return fd;
}

// Closes a wrapped file descriptor and resets the wrapper.
void UniqueFd::Reset(int new_fd) {
if (IsValid()) {
#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN)
FdsanClose(fd_, Tag(this));
#else
if (::close(fd_) != 0) {
ABSL_LOG(ERROR) << "Failed to close fd: " << fd_;
}
#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN
fd_ = -1;
}

if (new_fd != -1) {
fd_ = new_fd;
#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN)
// Acquire ownership of the presumably unowned fd.
FdsanExchangeTag(fd_, 0, Tag(this));
#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN
}
}

} // namespace mediapipe

#ifdef MEDIAPIPE_UNIQUE_FD_USE_FDSAN
#undef MEDIAPIPE_UNIQUE_FD_USE_FDSAN
#endif
97 changes: 4 additions & 93 deletions mediapipe/framework/formats/unique_fd.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
#ifndef MEDIAPIPE_FRAMEWORK_FORMATS_ANDROID_UNIQUE_FD_H_
#define MEDIAPIPE_FRAMEWORK_FORMATS_ANDROID_UNIQUE_FD_H_

#include <unistd.h>

#include <utility>

#include "absl/base/attributes.h"
#include "absl/log/absl_log.h"
#include "absl/status/statusor.h"
#include "mediapipe/framework/port/ret_check.h"

#if (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG)
#define MEDIAPIPE_USE_FDSAN 1
#include <android/fdsan.h>
#endif // (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG)

namespace mediapipe {

Expand All @@ -38,103 +29,23 @@ class UniqueFd {
~UniqueFd() { Reset(); }

UniqueFd& operator=(const UniqueFd& copy) = delete;
UniqueFd& operator=(UniqueFd&& move) {
if (this == &move) {
return *this;
}

Reset();

if (move.fd_ != -1) {
fd_ = move.fd_;
move.fd_ = -1;
#if defined(MEDIAPIPE_USE_FDSAN)
// Acquire ownership from the moved-from object.
FdsanExchangeTag(fd_, move.Tag(), Tag());
#endif // MEDIAPIPE_USE_FDSAN
}

return *this;
}

UniqueFd& operator=(UniqueFd&& move);
// Returns a non-owned file descriptor.
int Get() const { return fd_; }

// Checks if a valid file descriptor is wrapped.
bool IsValid() const { return fd_ >= 0; }

absl::StatusOr<UniqueFd> Dup() const {
RET_CHECK(IsValid());
int dup_fd = dup(Get());
return UniqueFd(dup_fd);
}
absl::StatusOr<UniqueFd> Dup() const;

// Releases ownership of the file descriptor and returns it.
ABSL_MUST_USE_RESULT int Release() {
if (!IsValid()) {
return -1;
}

int fd = fd_;
fd_ = -1;
#if defined(MEDIAPIPE_USE_FDSAN)
// Release ownership.
FdsanExchangeTag(fd, Tag(), 0);
#endif // MEDIAPIPE_USE_FDSAN
return fd;
}
ABSL_MUST_USE_RESULT int Release();

// Closes a wrapped file descriptor and resets the wrapper.
void Reset(int new_fd = -1) {
if (IsValid()) {
#if defined(MEDIAPIPE_USE_FDSAN)
FdsanClose(fd_, Tag());
#else
if (::close(fd_) != 0) {
ABSL_LOG(ERROR) << "Failed to close fd: " << fd_;
}
#endif // MEDIAPIPE_USE_FDSAN
fd_ = -1;
}

if (new_fd != -1) {
fd_ = new_fd;
#if defined(MEDIAPIPE_USE_FDSAN)
// Acquire ownership of the presumably unowned fd.
FdsanExchangeTag(fd_, 0, Tag());
#endif // MEDIAPIPE_USE_FDSAN
}
}
void Reset(int new_fd = -1);

private:
int fd_ = -1;

#if defined(MEDIAPIPE_USE_FDSAN)
// Address of the object is used as tag.
uint64_t Tag() { return reinterpret_cast<uint64_t>(this); }

// These functions are marked with __attribute__((weak)), so that their
// availability can be determined at runtime. These wrappers will use them
// if available, and fall back to no-ops or regular close on devices older
// than API level 29 or non-bionic or non-production builds.
static void FdsanExchangeTag(int fd, uint64_t old_tag, uint64_t new_tag) {
if (android_fdsan_exchange_owner_tag) {
android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
}
}

static void FdsanClose(int fd, uint64_t tag) {
if (android_fdsan_close_with_tag) {
if (android_fdsan_close_with_tag(fd, tag) != 0) {
ABSL_LOG(ERROR) << "Failed to close fd: " << fd;
}
return;
}
if (::close(fd) != 0) {
ABSL_LOG(ERROR) << "Failed to close fd: " << fd;
}
}
#endif // MEDIAPIPE_USE_FDSAN
};

} // namespace mediapipe
Expand Down

0 comments on commit 0529235

Please sign in to comment.