Loading libs/binder/Parcel.cpp +6 −3 Original line number Diff line number Diff line Loading @@ -614,11 +614,14 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) { if (status_t status = readInt32(&fdIndex); status != OK) { return status; } const auto& oldFd = otherRpcFields->mFds->at(fdIndex); int oldFd = toRawFd(otherRpcFields->mFds->at(fdIndex)); // To match kernel binder behavior, we always dup, even if the // FD was unowned in the source parcel. rpcFields->mFds->emplace_back( base::unique_fd(fcntl(toRawFd(oldFd), F_DUPFD_CLOEXEC, 0))); int newFd = -1; if (status_t status = dupFileDescriptor(oldFd, &newFd); status != OK) { ALOGW("Failed to duplicate file descriptor %d: %s", oldFd, strerror(-status)); } rpcFields->mFds->emplace_back(base::unique_fd(newFd)); // Fixup the index in the data. mDataPos = newDataPos + 4; if (status_t status = writeInt32(rpcFields->mFds->size() - 1); status != OK) { Loading libs/binder/tests/binderRpcTest.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -913,6 +913,33 @@ TEST_P(BinderRpc, SendTooManyFiles) { EXPECT_EQ(status.transactionError(), BAD_VALUE) << status; } TEST_P(BinderRpc, AppendInvalidFd) { auto proc = createRpcTestSocketServerProcess({ .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX, .serverSupportedFileDescriptorTransportModes = {RpcSession::FileDescriptorTransportMode::UNIX}, }); int badFd = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 0); ASSERT_NE(badFd, -1); // Close the file descriptor so it becomes invalid for dup close(badFd); Parcel p1; p1.markForBinder(proc.rootBinder); p1.writeInt32(3); EXPECT_EQ(OK, p1.writeFileDescriptor(badFd, false)); Parcel pRaw; pRaw.markForBinder(proc.rootBinder); EXPECT_EQ(OK, pRaw.appendFrom(&p1, 0, p1.dataSize())); pRaw.setDataPosition(0); EXPECT_EQ(3, pRaw.readInt32()); ASSERT_EQ(-1, pRaw.readFileDescriptor()); } TEST_P(BinderRpc, WorksWithLibbinderNdkPing) { if constexpr (!kEnableSharedLibs) { GTEST_SKIP() << "Test disabled because Binder was built as a static library"; Loading Loading
libs/binder/Parcel.cpp +6 −3 Original line number Diff line number Diff line Loading @@ -614,11 +614,14 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) { if (status_t status = readInt32(&fdIndex); status != OK) { return status; } const auto& oldFd = otherRpcFields->mFds->at(fdIndex); int oldFd = toRawFd(otherRpcFields->mFds->at(fdIndex)); // To match kernel binder behavior, we always dup, even if the // FD was unowned in the source parcel. rpcFields->mFds->emplace_back( base::unique_fd(fcntl(toRawFd(oldFd), F_DUPFD_CLOEXEC, 0))); int newFd = -1; if (status_t status = dupFileDescriptor(oldFd, &newFd); status != OK) { ALOGW("Failed to duplicate file descriptor %d: %s", oldFd, strerror(-status)); } rpcFields->mFds->emplace_back(base::unique_fd(newFd)); // Fixup the index in the data. mDataPos = newDataPos + 4; if (status_t status = writeInt32(rpcFields->mFds->size() - 1); status != OK) { Loading
libs/binder/tests/binderRpcTest.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -913,6 +913,33 @@ TEST_P(BinderRpc, SendTooManyFiles) { EXPECT_EQ(status.transactionError(), BAD_VALUE) << status; } TEST_P(BinderRpc, AppendInvalidFd) { auto proc = createRpcTestSocketServerProcess({ .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX, .serverSupportedFileDescriptorTransportModes = {RpcSession::FileDescriptorTransportMode::UNIX}, }); int badFd = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 0); ASSERT_NE(badFd, -1); // Close the file descriptor so it becomes invalid for dup close(badFd); Parcel p1; p1.markForBinder(proc.rootBinder); p1.writeInt32(3); EXPECT_EQ(OK, p1.writeFileDescriptor(badFd, false)); Parcel pRaw; pRaw.markForBinder(proc.rootBinder); EXPECT_EQ(OK, pRaw.appendFrom(&p1, 0, p1.dataSize())); pRaw.setDataPosition(0); EXPECT_EQ(3, pRaw.readInt32()); ASSERT_EQ(-1, pRaw.readFileDescriptor()); } TEST_P(BinderRpc, WorksWithLibbinderNdkPing) { if constexpr (!kEnableSharedLibs) { GTEST_SKIP() << "Test disabled because Binder was built as a static library"; Loading