2727#include < gmock/gmock.h>
2828#include < gtest/gtest.h>
2929
30+ #include < android-base/logging.h>
3031#include < android-base/properties.h>
3132#include < android-base/result-gmock.h>
3233#include < android-base/result.h>
4243
4344#include < linux/sched.h>
4445#include < sys/epoll.h>
46+ #include < sys/mman.h>
4547#include < sys/prctl.h>
4648#include < sys/socket.h>
4749#include < sys/un.h>
@@ -56,6 +58,7 @@ using namespace std::string_literals;
5658using namespace std ::chrono_literals;
5759using android::base::testing::HasValue;
5860using android::base::testing::Ok;
61+ using android::base::unique_fd;
5962using testing::ExplainMatchResult;
6063using testing::Matcher;
6164using testing::Not;
@@ -104,6 +107,8 @@ enum BinderLibTestTranscationCode {
104107 BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
105108 BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
106109 BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
110+ BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION,
111+ BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION,
107112 BINDER_LIB_TEST_EXIT_TRANSACTION,
108113 BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
109114 BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
@@ -437,6 +442,35 @@ class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestE
437442 };
438443};
439444
445+ ssize_t countFds () {
446+ DIR* dir = opendir (" /proc/self/fd/" );
447+ if (dir == nullptr ) return -1 ;
448+ ssize_t ret = 0 ;
449+ dirent* ent;
450+ while ((ent = readdir (dir)) != nullptr ) ret++;
451+ closedir (dir);
452+ return ret;
453+ }
454+
455+ struct FdLeakDetector {
456+ int startCount;
457+
458+ FdLeakDetector () {
459+ // This log statement is load bearing. We have to log something before
460+ // counting FDs to make sure the logging system is initialized, otherwise
461+ // the sockets it opens will look like a leak.
462+ ALOGW (" FdLeakDetector counting FDs." );
463+ startCount = countFds ();
464+ }
465+ ~FdLeakDetector () {
466+ int endCount = countFds ();
467+ if (startCount != endCount) {
468+ ADD_FAILURE () << " fd count changed (" << startCount << " -> " << endCount
469+ << " ) fd leak?" ;
470+ }
471+ }
472+ };
473+
440474TEST_F (BinderLibTest, CannotUseBinderAfterFork) {
441475 // EXPECT_DEATH works by forking the process
442476 EXPECT_DEATH ({ ProcessState::self (); }, " libbinder ProcessState can not be used after fork" );
@@ -852,6 +886,100 @@ TEST_F(BinderLibTest, PassParcelFileDescriptor) {
852886 EXPECT_EQ (0 , read (read_end.get (), readbuf.data (), datasize));
853887}
854888
889+ TEST_F (BinderLibTest, RecvOwnedFileDescriptors) {
890+ FdLeakDetector fd_leak_detector;
891+
892+ Parcel data;
893+ Parcel reply;
894+ EXPECT_EQ (NO_ERROR,
895+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data,
896+ &reply));
897+ unique_fd a, b;
898+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
899+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
900+ }
901+
902+ // Used to trigger fdsan error (b/239222407).
903+ TEST_F (BinderLibTest, RecvOwnedFileDescriptorsAndWriteInt) {
904+ GTEST_SKIP () << " triggers fdsan false positive: b/370824489" ;
905+
906+ FdLeakDetector fd_leak_detector;
907+
908+ Parcel data;
909+ Parcel reply;
910+ EXPECT_EQ (NO_ERROR,
911+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data,
912+ &reply));
913+ reply.setDataPosition (reply.dataSize ());
914+ reply.writeInt32 (0 );
915+ reply.setDataPosition (0 );
916+ unique_fd a, b;
917+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
918+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
919+ }
920+
921+ // Used to trigger fdsan error (b/239222407).
922+ TEST_F (BinderLibTest, RecvOwnedFileDescriptorsAndTruncate) {
923+ GTEST_SKIP () << " triggers fdsan false positive: b/370824489" ;
924+
925+ FdLeakDetector fd_leak_detector;
926+
927+ Parcel data;
928+ Parcel reply;
929+ EXPECT_EQ (NO_ERROR,
930+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data,
931+ &reply));
932+ reply.setDataSize (reply.dataSize () - sizeof (flat_binder_object));
933+ unique_fd a, b;
934+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
935+ EXPECT_EQ (BAD_TYPE, reply.readUniqueFileDescriptor (&b));
936+ }
937+
938+ TEST_F (BinderLibTest, RecvUnownedFileDescriptors) {
939+ FdLeakDetector fd_leak_detector;
940+
941+ Parcel data;
942+ Parcel reply;
943+ EXPECT_EQ (NO_ERROR,
944+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data,
945+ &reply));
946+ unique_fd a, b;
947+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
948+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
949+ }
950+
951+ // Used to trigger fdsan error (b/239222407).
952+ TEST_F (BinderLibTest, RecvUnownedFileDescriptorsAndWriteInt) {
953+ FdLeakDetector fd_leak_detector;
954+
955+ Parcel data;
956+ Parcel reply;
957+ EXPECT_EQ (NO_ERROR,
958+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data,
959+ &reply));
960+ reply.setDataPosition (reply.dataSize ());
961+ reply.writeInt32 (0 );
962+ reply.setDataPosition (0 );
963+ unique_fd a, b;
964+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
965+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
966+ }
967+
968+ // Used to trigger fdsan error (b/239222407).
969+ TEST_F (BinderLibTest, RecvUnownedFileDescriptorsAndTruncate) {
970+ FdLeakDetector fd_leak_detector;
971+
972+ Parcel data;
973+ Parcel reply;
974+ EXPECT_EQ (NO_ERROR,
975+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data,
976+ &reply));
977+ reply.setDataSize (reply.dataSize () - sizeof (flat_binder_object));
978+ unique_fd a, b;
979+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
980+ EXPECT_EQ (BAD_TYPE, reply.readUniqueFileDescriptor (&b));
981+ }
982+
855983TEST_F (BinderLibTest, PromoteLocal) {
856984 sp<IBinder> strong = new BBinder ();
857985 wp<IBinder> weak = strong;
@@ -1600,6 +1728,40 @@ class BinderLibTestService : public BBinder {
16001728 if (ret != size) return UNKNOWN_ERROR;
16011729 return NO_ERROR;
16021730 }
1731+ case BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION: {
1732+ unique_fd fd1 (memfd_create (" memfd1" , MFD_CLOEXEC));
1733+ if (!fd1.ok ()) {
1734+ PLOG (ERROR) << " memfd_create failed" ;
1735+ return UNKNOWN_ERROR;
1736+ }
1737+ unique_fd fd2 (memfd_create (" memfd2" , MFD_CLOEXEC));
1738+ if (!fd2.ok ()) {
1739+ PLOG (ERROR) << " memfd_create failed" ;
1740+ return UNKNOWN_ERROR;
1741+ }
1742+ status_t ret;
1743+ ret = reply->writeFileDescriptor (fd1.release (), true );
1744+ if (ret != NO_ERROR) {
1745+ return ret;
1746+ }
1747+ ret = reply->writeFileDescriptor (fd2.release (), true );
1748+ if (ret != NO_ERROR) {
1749+ return ret;
1750+ }
1751+ return NO_ERROR;
1752+ }
1753+ case BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION: {
1754+ status_t ret;
1755+ ret = reply->writeFileDescriptor (STDOUT_FILENO, false );
1756+ if (ret != NO_ERROR) {
1757+ return ret;
1758+ }
1759+ ret = reply->writeFileDescriptor (STDERR_FILENO, false );
1760+ if (ret != NO_ERROR) {
1761+ return ret;
1762+ }
1763+ return NO_ERROR;
1764+ }
16031765 case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
16041766 alarm (10 );
16051767 return NO_ERROR;
0 commit comments