libbinder: detach ParcelFileDescriptor comm
Now that ParcelFileDescriptors are being exposed in the NDK, we need
to provide the correct behavior when these are expected to be used
with comms.
- ideally, this code would be refactored to be inside of
ParcelFileDescriptor.(cpp|h), however many places in the codebase
call this function directly, so I'm leaving it in Parcel.cpp for now
- BIG_ENDIAN path can't be tested, but it's being added to be
consistent with writeInplace.
Change-Id: I93b9cede757c4423c49bc117c4d96c5a501de6f4
Fixes: 115607973
Test: android.binder.cts
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index b3ae09b..07d5c4b 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -2239,8 +2239,30 @@
int32_t hasComm = readInt32();
int fd = readFileDescriptor();
if (hasComm != 0) {
- // skip
- readFileDescriptor();
+ // detach (owned by the binder driver)
+ int comm = readFileDescriptor();
+
+ // warning: this must be kept in sync with:
+ // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+ enum ParcelFileDescriptorStatus {
+ DETACHED = 2,
+ };
+
+#if BYTE_ORDER == BIG_ENDIAN
+ const int32_t message = ParcelFileDescriptorStatus::DETACHED;
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+ const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
+#endif
+
+ ssize_t written = TEMP_FAILURE_RETRY(
+ ::write(comm, &message, sizeof(message)));
+
+ if (written == -1 || written != sizeof(message)) {
+ ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
+ written, strerror(errno));
+ return BAD_TYPE;
+ }
}
return fd;
}