|
26 | 26 | #include <gmock/gmock.h> |
27 | 27 | #include <gtest/gtest.h> |
28 | 28 |
|
| 29 | +#include <android-base/logging.h> |
| 30 | +#include <android-base/unique_fd.h> |
29 | 31 | #include <binder/Binder.h> |
30 | 32 | #include <binder/IBinder.h> |
31 | 33 | #include <binder/IPCThreadState.h> |
32 | 34 | #include <binder/IServiceManager.h> |
33 | 35 |
|
34 | 36 | #include <linux/sched.h> |
35 | 37 | #include <sys/epoll.h> |
| 38 | +#include <sys/mman.h> |
36 | 39 | #include <sys/prctl.h> |
37 | 40 |
|
38 | 41 | #include "../binder_module.h" |
|
41 | 44 | #define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) |
42 | 45 |
|
43 | 46 | using namespace android; |
| 47 | +using android::base::unique_fd; |
44 | 48 | using testing::Not; |
45 | 49 |
|
46 | 50 | // e.g. EXPECT_THAT(expr, StatusEq(OK)) << "additional message"; |
@@ -85,6 +89,8 @@ enum BinderLibTestTranscationCode { |
85 | 89 | BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, |
86 | 90 | BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, |
87 | 91 | BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION, |
| 92 | + BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, |
| 93 | + BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, |
88 | 94 | BINDER_LIB_TEST_EXIT_TRANSACTION, |
89 | 95 | BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION, |
90 | 96 | BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, |
@@ -404,6 +410,35 @@ class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestE |
404 | 410 | }; |
405 | 411 | }; |
406 | 412 |
|
| 413 | +ssize_t countFds() { |
| 414 | + DIR* dir = opendir("/proc/self/fd/"); |
| 415 | + if (dir == nullptr) return -1; |
| 416 | + ssize_t ret = 0; |
| 417 | + dirent* ent; |
| 418 | + while ((ent = readdir(dir)) != nullptr) ret++; |
| 419 | + closedir(dir); |
| 420 | + return ret; |
| 421 | +} |
| 422 | + |
| 423 | +struct FdLeakDetector { |
| 424 | + int startCount; |
| 425 | + |
| 426 | + FdLeakDetector() { |
| 427 | + // This log statement is load bearing. We have to log something before |
| 428 | + // counting FDs to make sure the logging system is initialized, otherwise |
| 429 | + // the sockets it opens will look like a leak. |
| 430 | + ALOGW("FdLeakDetector counting FDs."); |
| 431 | + startCount = countFds(); |
| 432 | + } |
| 433 | + ~FdLeakDetector() { |
| 434 | + int endCount = countFds(); |
| 435 | + if (startCount != endCount) { |
| 436 | + ADD_FAILURE() << "fd count changed (" << startCount << " -> " << endCount |
| 437 | + << ") fd leak?"; |
| 438 | + } |
| 439 | + } |
| 440 | +}; |
| 441 | + |
407 | 442 | TEST_F(BinderLibTest, NopTransaction) { |
408 | 443 | Parcel data, reply; |
409 | 444 | EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply), |
@@ -812,6 +847,100 @@ TEST_F(BinderLibTest, PassParcelFileDescriptor) { |
812 | 847 | EXPECT_EQ(0, read(read_end.get(), readbuf.data(), datasize)); |
813 | 848 | } |
814 | 849 |
|
| 850 | +TEST_F(BinderLibTest, RecvOwnedFileDescriptors) { |
| 851 | + FdLeakDetector fd_leak_detector; |
| 852 | + |
| 853 | + Parcel data; |
| 854 | + Parcel reply; |
| 855 | + EXPECT_EQ(NO_ERROR, |
| 856 | + m_server->transact(BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data, |
| 857 | + &reply)); |
| 858 | + unique_fd a, b; |
| 859 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&a)); |
| 860 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&b)); |
| 861 | +} |
| 862 | + |
| 863 | +// Used to trigger fdsan error (b/239222407). |
| 864 | +TEST_F(BinderLibTest, RecvOwnedFileDescriptorsAndWriteInt) { |
| 865 | + GTEST_SKIP() << "triggers fdsan false positive: b/370824489"; |
| 866 | + |
| 867 | + FdLeakDetector fd_leak_detector; |
| 868 | + |
| 869 | + Parcel data; |
| 870 | + Parcel reply; |
| 871 | + EXPECT_EQ(NO_ERROR, |
| 872 | + m_server->transact(BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data, |
| 873 | + &reply)); |
| 874 | + reply.setDataPosition(reply.dataSize()); |
| 875 | + reply.writeInt32(0); |
| 876 | + reply.setDataPosition(0); |
| 877 | + unique_fd a, b; |
| 878 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&a)); |
| 879 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&b)); |
| 880 | +} |
| 881 | + |
| 882 | +// Used to trigger fdsan error (b/239222407). |
| 883 | +TEST_F(BinderLibTest, RecvOwnedFileDescriptorsAndTruncate) { |
| 884 | + GTEST_SKIP() << "triggers fdsan false positive: b/370824489"; |
| 885 | + |
| 886 | + FdLeakDetector fd_leak_detector; |
| 887 | + |
| 888 | + Parcel data; |
| 889 | + Parcel reply; |
| 890 | + EXPECT_EQ(NO_ERROR, |
| 891 | + m_server->transact(BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION, data, |
| 892 | + &reply)); |
| 893 | + reply.setDataSize(reply.dataSize() - sizeof(flat_binder_object)); |
| 894 | + unique_fd a, b; |
| 895 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&a)); |
| 896 | + EXPECT_EQ(BAD_TYPE, reply.readUniqueFileDescriptor(&b)); |
| 897 | +} |
| 898 | + |
| 899 | +TEST_F(BinderLibTest, RecvUnownedFileDescriptors) { |
| 900 | + FdLeakDetector fd_leak_detector; |
| 901 | + |
| 902 | + Parcel data; |
| 903 | + Parcel reply; |
| 904 | + EXPECT_EQ(NO_ERROR, |
| 905 | + m_server->transact(BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data, |
| 906 | + &reply)); |
| 907 | + unique_fd a, b; |
| 908 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&a)); |
| 909 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&b)); |
| 910 | +} |
| 911 | + |
| 912 | +// Used to trigger fdsan error (b/239222407). |
| 913 | +TEST_F(BinderLibTest, RecvUnownedFileDescriptorsAndWriteInt) { |
| 914 | + FdLeakDetector fd_leak_detector; |
| 915 | + |
| 916 | + Parcel data; |
| 917 | + Parcel reply; |
| 918 | + EXPECT_EQ(NO_ERROR, |
| 919 | + m_server->transact(BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data, |
| 920 | + &reply)); |
| 921 | + reply.setDataPosition(reply.dataSize()); |
| 922 | + reply.writeInt32(0); |
| 923 | + reply.setDataPosition(0); |
| 924 | + unique_fd a, b; |
| 925 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&a)); |
| 926 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&b)); |
| 927 | +} |
| 928 | + |
| 929 | +// Used to trigger fdsan error (b/239222407). |
| 930 | +TEST_F(BinderLibTest, RecvUnownedFileDescriptorsAndTruncate) { |
| 931 | + FdLeakDetector fd_leak_detector; |
| 932 | + |
| 933 | + Parcel data; |
| 934 | + Parcel reply; |
| 935 | + EXPECT_EQ(NO_ERROR, |
| 936 | + m_server->transact(BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION, data, |
| 937 | + &reply)); |
| 938 | + reply.setDataSize(reply.dataSize() - sizeof(flat_binder_object)); |
| 939 | + unique_fd a, b; |
| 940 | + EXPECT_EQ(OK, reply.readUniqueFileDescriptor(&a)); |
| 941 | + EXPECT_EQ(BAD_TYPE, reply.readUniqueFileDescriptor(&b)); |
| 942 | +} |
| 943 | + |
815 | 944 | TEST_F(BinderLibTest, PromoteLocal) { |
816 | 945 | sp<IBinder> strong = new BBinder(); |
817 | 946 | wp<IBinder> weak = strong; |
@@ -1445,6 +1574,40 @@ class BinderLibTestService : public BBinder |
1445 | 1574 | if (ret != size) return UNKNOWN_ERROR; |
1446 | 1575 | return NO_ERROR; |
1447 | 1576 | } |
| 1577 | + case BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_OWNED_TRANSACTION: { |
| 1578 | + unique_fd fd1(memfd_create("memfd1", MFD_CLOEXEC)); |
| 1579 | + if (!fd1.ok()) { |
| 1580 | + PLOG(ERROR) << "memfd_create failed"; |
| 1581 | + return UNKNOWN_ERROR; |
| 1582 | + } |
| 1583 | + unique_fd fd2(memfd_create("memfd2", MFD_CLOEXEC)); |
| 1584 | + if (!fd2.ok()) { |
| 1585 | + PLOG(ERROR) << "memfd_create failed"; |
| 1586 | + return UNKNOWN_ERROR; |
| 1587 | + } |
| 1588 | + status_t ret; |
| 1589 | + ret = reply->writeFileDescriptor(fd1.release(), true); |
| 1590 | + if (ret != NO_ERROR) { |
| 1591 | + return ret; |
| 1592 | + } |
| 1593 | + ret = reply->writeFileDescriptor(fd2.release(), true); |
| 1594 | + if (ret != NO_ERROR) { |
| 1595 | + return ret; |
| 1596 | + } |
| 1597 | + return NO_ERROR; |
| 1598 | + } |
| 1599 | + case BINDER_LIB_TEST_GET_FILE_DESCRIPTORS_UNOWNED_TRANSACTION: { |
| 1600 | + status_t ret; |
| 1601 | + ret = reply->writeFileDescriptor(STDOUT_FILENO, false); |
| 1602 | + if (ret != NO_ERROR) { |
| 1603 | + return ret; |
| 1604 | + } |
| 1605 | + ret = reply->writeFileDescriptor(STDERR_FILENO, false); |
| 1606 | + if (ret != NO_ERROR) { |
| 1607 | + return ret; |
| 1608 | + } |
| 1609 | + return NO_ERROR; |
| 1610 | + } |
1448 | 1611 | case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION: |
1449 | 1612 | alarm(10); |
1450 | 1613 | return NO_ERROR; |
|
0 commit comments