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>
4344
4445#include < linux/sched.h>
4546#include < sys/epoll.h>
47+ #include < sys/mman.h>
4648#include < sys/prctl.h>
4749#include < sys/socket.h>
4850#include < sys/un.h>
@@ -57,6 +59,7 @@ using namespace std::string_literals;
5759using namespace std ::chrono_literals;
5860using android::base::testing::HasValue;
5961using android::base::testing::Ok;
62+ using android::base::unique_fd;
6063using testing::ExplainMatchResult;
6164using testing::Matcher;
6265using testing::Not;
@@ -106,6 +109,8 @@ enum BinderLibTestTranscationCode {
106109 BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
107110 BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
108111 BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
112+ BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION,
113+ BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION,
109114 BINDER_LIB_TEST_EXIT_TRANSACTION,
110115 BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
111116 BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
@@ -445,6 +450,35 @@ class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestE
445450 };
446451};
447452
453+ ssize_t countFds () {
454+ DIR* dir = opendir (" /proc/self/fd/" );
455+ if (dir == nullptr ) return -1 ;
456+ ssize_t ret = 0 ;
457+ dirent* ent;
458+ while ((ent = readdir (dir)) != nullptr ) ret++;
459+ closedir (dir);
460+ return ret;
461+ }
462+
463+ struct FdLeakDetector {
464+ int startCount;
465+
466+ FdLeakDetector () {
467+ // This log statement is load bearing. We have to log something before
468+ // counting FDs to make sure the logging system is initialized, otherwise
469+ // the sockets it opens will look like a leak.
470+ ALOGW (" FdLeakDetector counting FDs." );
471+ startCount = countFds ();
472+ }
473+ ~FdLeakDetector () {
474+ int endCount = countFds ();
475+ if (startCount != endCount) {
476+ ADD_FAILURE () << " fd count changed (" << startCount << " -> " << endCount
477+ << " ) fd leak?" ;
478+ }
479+ }
480+ };
481+
448482TEST_F (BinderLibTest, CannotUseBinderAfterFork) {
449483 // EXPECT_DEATH works by forking the process
450484 EXPECT_DEATH ({ ProcessState::self (); }, " libbinder ProcessState can not be used after fork" );
@@ -872,6 +906,100 @@ TEST_F(BinderLibTest, PassParcelFileDescriptor) {
872906 EXPECT_EQ (0 , read (read_end.get (), readbuf.data (), datasize));
873907}
874908
909+ TEST_F (BinderLibTest, RecvOwnedFileDescriptors) {
910+ FdLeakDetector fd_leak_detector;
911+
912+ Parcel data;
913+ Parcel reply;
914+ EXPECT_EQ (NO_ERROR,
915+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data,
916+ &reply));
917+ unique_fd a, b;
918+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
919+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
920+ }
921+
922+ // Used to trigger fdsan error (b/239222407).
923+ TEST_F (BinderLibTest, RecvOwnedFileDescriptorsAndWriteInt) {
924+ GTEST_SKIP () << " triggers fdsan false positive: b/370824489" ;
925+
926+ FdLeakDetector fd_leak_detector;
927+
928+ Parcel data;
929+ Parcel reply;
930+ EXPECT_EQ (NO_ERROR,
931+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data,
932+ &reply));
933+ reply.setDataPosition (reply.dataSize ());
934+ reply.writeInt32 (0 );
935+ reply.setDataPosition (0 );
936+ unique_fd a, b;
937+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
938+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
939+ }
940+
941+ // Used to trigger fdsan error (b/239222407).
942+ TEST_F (BinderLibTest, RecvOwnedFileDescriptorsAndTruncate) {
943+ GTEST_SKIP () << " triggers fdsan false positive: b/370824489" ;
944+
945+ FdLeakDetector fd_leak_detector;
946+
947+ Parcel data;
948+ Parcel reply;
949+ EXPECT_EQ (NO_ERROR,
950+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data,
951+ &reply));
952+ reply.setDataSize (reply.dataSize () - sizeof (flat_binder_object));
953+ unique_fd a, b;
954+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
955+ EXPECT_EQ (BAD_TYPE, reply.readUniqueFileDescriptor (&b));
956+ }
957+
958+ TEST_F (BinderLibTest, RecvUnownedFileDescriptors) {
959+ FdLeakDetector fd_leak_detector;
960+
961+ Parcel data;
962+ Parcel reply;
963+ EXPECT_EQ (NO_ERROR,
964+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data,
965+ &reply));
966+ unique_fd a, b;
967+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
968+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
969+ }
970+
971+ // Used to trigger fdsan error (b/239222407).
972+ TEST_F (BinderLibTest, RecvUnownedFileDescriptorsAndWriteInt) {
973+ FdLeakDetector fd_leak_detector;
974+
975+ Parcel data;
976+ Parcel reply;
977+ EXPECT_EQ (NO_ERROR,
978+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data,
979+ &reply));
980+ reply.setDataPosition (reply.dataSize ());
981+ reply.writeInt32 (0 );
982+ reply.setDataPosition (0 );
983+ unique_fd a, b;
984+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
985+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&b));
986+ }
987+
988+ // Used to trigger fdsan error (b/239222407).
989+ TEST_F (BinderLibTest, RecvUnownedFileDescriptorsAndTruncate) {
990+ FdLeakDetector fd_leak_detector;
991+
992+ Parcel data;
993+ Parcel reply;
994+ EXPECT_EQ (NO_ERROR,
995+ m_server->transact (BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data,
996+ &reply));
997+ reply.setDataSize (reply.dataSize () - sizeof (flat_binder_object));
998+ unique_fd a, b;
999+ EXPECT_EQ (OK, reply.readUniqueFileDescriptor (&a));
1000+ EXPECT_EQ (BAD_TYPE, reply.readUniqueFileDescriptor (&b));
1001+ }
1002+
8751003TEST_F (BinderLibTest, PromoteLocal) {
8761004 sp<IBinder> strong = new BBinder ();
8771005 wp<IBinder> weak = strong;
@@ -1800,6 +1928,40 @@ class BinderLibTestService : public BBinder {
18001928 if (ret != size) return UNKNOWN_ERROR;
18011929 return NO_ERROR;
18021930 }
1931+ case BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION: {
1932+ unique_fd fd1 (memfd_create (" memfd1" , MFD_CLOEXEC));
1933+ if (!fd1.ok ()) {
1934+ PLOG (ERROR) << " memfd_create failed" ;
1935+ return UNKNOWN_ERROR;
1936+ }
1937+ unique_fd fd2 (memfd_create (" memfd2" , MFD_CLOEXEC));
1938+ if (!fd2.ok ()) {
1939+ PLOG (ERROR) << " memfd_create failed" ;
1940+ return UNKNOWN_ERROR;
1941+ }
1942+ status_t ret;
1943+ ret = reply->writeFileDescriptor (fd1.release (), true );
1944+ if (ret != NO_ERROR) {
1945+ return ret;
1946+ }
1947+ ret = reply->writeFileDescriptor (fd2.release (), true );
1948+ if (ret != NO_ERROR) {
1949+ return ret;
1950+ }
1951+ return NO_ERROR;
1952+ }
1953+ case BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION: {
1954+ status_t ret;
1955+ ret = reply->writeFileDescriptor (STDOUT_FILENO, false );
1956+ if (ret != NO_ERROR) {
1957+ return ret;
1958+ }
1959+ ret = reply->writeFileDescriptor (STDERR_FILENO, false );
1960+ if (ret != NO_ERROR) {
1961+ return ret;
1962+ }
1963+ return NO_ERROR;
1964+ }
18031965 case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
18041966 alarm (10 );
18051967 return NO_ERROR;
0 commit comments