Loading libs/binder/tests/binderRpcBenchmark.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() { auto cert = android::makeSelfSignedCert(pkey.get(), android::kCertValidSeconds); CHECK_NE(cert.get(), nullptr); auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(); auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(OK); auto auth = std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert)); return RpcTransportCtxFactoryTls::make(verifier, std::move(auth)); } Loading libs/binder/tests/include_tls_test_utils/binder/RpcTlsTestUtils.h +5 −1 Original line number Diff line number Diff line Loading @@ -80,7 +80,11 @@ private: // A RpcCertificateVerifier that does not verify anything. class RpcCertificateVerifierNoOp : public RpcCertificateVerifier { public: status_t verify(const SSL*, uint8_t*) override { return OK; } RpcCertificateVerifierNoOp(status_t status) : mStatus(status) {} status_t verify(const SSL*, uint8_t*) override { return mStatus; } private: status_t mStatus; }; } // namespace android libs/binder/tests/rpc_fuzzer/Android.bp +12 −1 Original line number Diff line number Diff line Loading @@ -19,12 +19,19 @@ cc_fuzz { srcs: [ "main.cpp", ], // Not using libbinder_tls_shared_deps to use deterministic boringssl libraries. static_libs: [ "libbase", "libcutils", "liblog", "libbinder_tls_static", "libbinder_tls_test_utils", "libssl_fuzz_unsafe", "libcrypto_fuzz_unsafe", ], cflags: [ "-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE" // for RAND_reset_for_fuzzing ], target: { android: { shared_libs: [ Loading @@ -39,4 +46,8 @@ cc_fuzz { ], }, }, data: [ "server.crt", "server.key", ], } libs/binder/tests/rpc_fuzzer/create_certs.sh 0 → 100755 +15 −0 Original line number Diff line number Diff line #!/bin/sh # As explained in # https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca openssl genrsa -des3 -passout pass:xxxx -out server.pass.key 2048 openssl rsa -passin pass:xxxx -in server.pass.key -out server.key rm -f server.pass.key openssl req \ -subj "/" \ -new -key server.key -out server.csr openssl x509 -req -sha256 -days 99999 -in server.csr -signkey server.key -out server.crt rm -f server.csr libs/binder/tests/rpc_fuzzer/main.cpp +62 −2 Original line number Diff line number Diff line Loading @@ -13,13 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/unique_fd.h> #include <binder/Binder.h> #include <binder/Parcel.h> #include <binder/RpcServer.h> #include <binder/RpcSession.h> #include <binder/RpcTlsTestUtils.h> #include <binder/RpcTransport.h> #include <binder/RpcTransportRaw.h> #include <binder/RpcTransportTls.h> #include <fuzzer/FuzzedDataProvider.h> #include <openssl/rand.h> #include <openssl/ssl.h> #include <sys/resource.h> #include <sys/un.h> Loading Loading @@ -51,13 +58,66 @@ class SomeBinder : public BBinder { } }; int passwordCallback(char* buf, int size, int /*rwflag*/, void* /*u*/) { constexpr const char pass[] = "xxxx"; // See create_certs.sh if (size <= 0) return 0; int numCopy = std::min<int>(size, sizeof(pass)); (void)memcpy(buf, pass, numCopy); return numCopy; } struct ServerAuth { bssl::UniquePtr<EVP_PKEY> pkey; bssl::UniquePtr<X509> cert; }; // Use pre-configured keys because runtime generated keys / certificates are not // deterministic, and the algorithm is time consuming. ServerAuth readServerKeyAndCert() { ServerAuth ret; auto keyPath = android::base::GetExecutableDirectory() + "/data/server.key"; bssl::UniquePtr<BIO> keyBio(BIO_new_file(keyPath.c_str(), "r")); ret.pkey.reset(PEM_read_bio_PrivateKey(keyBio.get(), nullptr, passwordCallback, nullptr)); CHECK_NE(ret.pkey.get(), nullptr); auto certPath = android::base::GetExecutableDirectory() + "/data/server.crt"; bssl::UniquePtr<BIO> certBio(BIO_new_file(certPath.c_str(), "r")); ret.cert.reset(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr)); CHECK_NE(ret.cert.get(), nullptr); return ret; } std::unique_ptr<RpcAuth> createServerRpcAuth() { static auto sAuth = readServerKeyAndCert(); CHECK(EVP_PKEY_up_ref(sAuth.pkey.get())); bssl::UniquePtr<EVP_PKEY> pkey(sAuth.pkey.get()); CHECK(X509_up_ref(sAuth.cert.get())); bssl::UniquePtr<X509> cert(sAuth.cert.get()); return std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert)); } std::unique_ptr<RpcTransportCtxFactory> makeTransportCtxFactory(FuzzedDataProvider* provider) { bool isTls = provider->ConsumeBool(); if (!isTls) { return RpcTransportCtxFactoryRaw::make(); } status_t verifyStatus = provider->ConsumeIntegral<status_t>(); auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(verifyStatus); return RpcTransportCtxFactoryTls::make(verifier, createServerRpcAuth()); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size > 50000) return 0; FuzzedDataProvider provider(data, size); RAND_reset_for_fuzzing(); unlink(kSock.c_str()); sp<RpcServer> server = RpcServer::make(); sp<RpcServer> server = RpcServer::make(makeTransportCtxFactory(&provider)); server->setRootObject(sp<SomeBinder>::make()); server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction(); CHECK_EQ(OK, server->setupUnixDomainServer(kSock.c_str())); Loading Loading
libs/binder/tests/binderRpcBenchmark.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() { auto cert = android::makeSelfSignedCert(pkey.get(), android::kCertValidSeconds); CHECK_NE(cert.get(), nullptr); auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(); auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(OK); auto auth = std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert)); return RpcTransportCtxFactoryTls::make(verifier, std::move(auth)); } Loading
libs/binder/tests/include_tls_test_utils/binder/RpcTlsTestUtils.h +5 −1 Original line number Diff line number Diff line Loading @@ -80,7 +80,11 @@ private: // A RpcCertificateVerifier that does not verify anything. class RpcCertificateVerifierNoOp : public RpcCertificateVerifier { public: status_t verify(const SSL*, uint8_t*) override { return OK; } RpcCertificateVerifierNoOp(status_t status) : mStatus(status) {} status_t verify(const SSL*, uint8_t*) override { return mStatus; } private: status_t mStatus; }; } // namespace android
libs/binder/tests/rpc_fuzzer/Android.bp +12 −1 Original line number Diff line number Diff line Loading @@ -19,12 +19,19 @@ cc_fuzz { srcs: [ "main.cpp", ], // Not using libbinder_tls_shared_deps to use deterministic boringssl libraries. static_libs: [ "libbase", "libcutils", "liblog", "libbinder_tls_static", "libbinder_tls_test_utils", "libssl_fuzz_unsafe", "libcrypto_fuzz_unsafe", ], cflags: [ "-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE" // for RAND_reset_for_fuzzing ], target: { android: { shared_libs: [ Loading @@ -39,4 +46,8 @@ cc_fuzz { ], }, }, data: [ "server.crt", "server.key", ], }
libs/binder/tests/rpc_fuzzer/create_certs.sh 0 → 100755 +15 −0 Original line number Diff line number Diff line #!/bin/sh # As explained in # https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca openssl genrsa -des3 -passout pass:xxxx -out server.pass.key 2048 openssl rsa -passin pass:xxxx -in server.pass.key -out server.key rm -f server.pass.key openssl req \ -subj "/" \ -new -key server.key -out server.csr openssl x509 -req -sha256 -days 99999 -in server.csr -signkey server.key -out server.crt rm -f server.csr
libs/binder/tests/rpc_fuzzer/main.cpp +62 −2 Original line number Diff line number Diff line Loading @@ -13,13 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/unique_fd.h> #include <binder/Binder.h> #include <binder/Parcel.h> #include <binder/RpcServer.h> #include <binder/RpcSession.h> #include <binder/RpcTlsTestUtils.h> #include <binder/RpcTransport.h> #include <binder/RpcTransportRaw.h> #include <binder/RpcTransportTls.h> #include <fuzzer/FuzzedDataProvider.h> #include <openssl/rand.h> #include <openssl/ssl.h> #include <sys/resource.h> #include <sys/un.h> Loading Loading @@ -51,13 +58,66 @@ class SomeBinder : public BBinder { } }; int passwordCallback(char* buf, int size, int /*rwflag*/, void* /*u*/) { constexpr const char pass[] = "xxxx"; // See create_certs.sh if (size <= 0) return 0; int numCopy = std::min<int>(size, sizeof(pass)); (void)memcpy(buf, pass, numCopy); return numCopy; } struct ServerAuth { bssl::UniquePtr<EVP_PKEY> pkey; bssl::UniquePtr<X509> cert; }; // Use pre-configured keys because runtime generated keys / certificates are not // deterministic, and the algorithm is time consuming. ServerAuth readServerKeyAndCert() { ServerAuth ret; auto keyPath = android::base::GetExecutableDirectory() + "/data/server.key"; bssl::UniquePtr<BIO> keyBio(BIO_new_file(keyPath.c_str(), "r")); ret.pkey.reset(PEM_read_bio_PrivateKey(keyBio.get(), nullptr, passwordCallback, nullptr)); CHECK_NE(ret.pkey.get(), nullptr); auto certPath = android::base::GetExecutableDirectory() + "/data/server.crt"; bssl::UniquePtr<BIO> certBio(BIO_new_file(certPath.c_str(), "r")); ret.cert.reset(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr)); CHECK_NE(ret.cert.get(), nullptr); return ret; } std::unique_ptr<RpcAuth> createServerRpcAuth() { static auto sAuth = readServerKeyAndCert(); CHECK(EVP_PKEY_up_ref(sAuth.pkey.get())); bssl::UniquePtr<EVP_PKEY> pkey(sAuth.pkey.get()); CHECK(X509_up_ref(sAuth.cert.get())); bssl::UniquePtr<X509> cert(sAuth.cert.get()); return std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert)); } std::unique_ptr<RpcTransportCtxFactory> makeTransportCtxFactory(FuzzedDataProvider* provider) { bool isTls = provider->ConsumeBool(); if (!isTls) { return RpcTransportCtxFactoryRaw::make(); } status_t verifyStatus = provider->ConsumeIntegral<status_t>(); auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(verifyStatus); return RpcTransportCtxFactoryTls::make(verifier, createServerRpcAuth()); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size > 50000) return 0; FuzzedDataProvider provider(data, size); RAND_reset_for_fuzzing(); unlink(kSock.c_str()); sp<RpcServer> server = RpcServer::make(); sp<RpcServer> server = RpcServer::make(makeTransportCtxFactory(&provider)); server->setRootObject(sp<SomeBinder>::make()); server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction(); CHECK_EQ(OK, server->setupUnixDomainServer(kSock.c_str())); Loading