diff options
author | 2020-07-09 20:22:22 +0000 | |
---|---|---|
committer | 2020-07-09 20:22:22 +0000 | |
commit | 6c03e13d4b0c8df8cbdd06aa3fc5a94abdb3ddb5 (patch) | |
tree | 08d917256bfda2e4a20700e7cd85d9bdb48d7379 | |
parent | c281055a2bfc190143793978431370d8eb36ea30 (diff) | |
parent | 2f405f540b03d7f9d0457f19b3acd5c8e3295d9b (diff) |
Merge "libbinder_ndk: AIBinder_{setRequesting,getCalling}Sid"
-rw-r--r-- | libs/binder/include/binder/IPCThreadState.h | 2 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder.cpp | 16 | ||||
-rw-r--r-- | libs/binder/ndk/include_platform/android/binder_ibinder_platform.h | 46 | ||||
-rw-r--r-- | libs/binder/ndk/libbinder_ndk.map.txt | 8 | ||||
-rw-r--r-- | libs/binder/ndk/tests/IBinderNdkUnitTest.aidl | 2 | ||||
-rw-r--r-- | libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp | 25 |
6 files changed, 96 insertions, 3 deletions
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index b4e4a428b5..8d51cdc049 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -50,7 +50,7 @@ public: * Returns the SELinux security identifier of the process which has * made the current binder call. If not in a binder call this will * return nullptr. If this isn't requested with - * IBinder::setRequestingSid, it will also return nullptr. + * Binder::setRequestingSid, it will also return nullptr. * * This can't be restored once it's cleared, and it does not return the * context of the current process when not in a binder call. diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 743ef893fc..7540cae391 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -15,6 +15,7 @@ */ #include <android/binder_ibinder.h> +#include <android/binder_ibinder_platform.h> #include "ibinder_internal.h" #include <android/binder_stability.h> @@ -682,3 +683,18 @@ binder_status_t AIBinder_setExtension(AIBinder* binder, AIBinder* ext) { rawBinder->setExtension(ext->getBinder()); return STATUS_OK; } + +// platform methods follow + +void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) { + ABBinder* localBinder = binder->asABBinder(); + if (localBinder == nullptr) { + LOG(FATAL) << "AIBinder_setRequestingSid must be called on a local binder"; + } + + localBinder->setRequestingSid(requestingSid); +} + +const char* AIBinder_getCallingSid() { + return ::android::IPCThreadState::self()->getCallingSid(); +} diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h new file mode 100644 index 0000000000..1f5a2373a2 --- /dev/null +++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <android/binder_ibinder.h> + +__BEGIN_DECLS + +/** + * Makes calls to AIBinder_getCallingSid work if the kernel supports it. This + * must be called on a local binder server before it is sent out to any othe + * process. If this is a remote binder, it will abort. If the kernel doesn't + * support this feature, you'll always get null from AIBinder_getCallingSid. + * + * \param binder local server binder to request security contexts on + */ +void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) __INTRODUCED_IN(31); + +/** + * Returns the selinux context of the callee. + * + * In order for this to work, the following conditions must be met: + * - The kernel must be new enough to support this feature. + * - The server must have called AIBinder_setRequestingSid. + * - The callee must be a remote process. + * + * \return security context or null if unavailable. The lifetime of this context + * is the lifetime of the transaction. + */ +__attribute__((warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31); + +__END_DECLS diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index a9eba47380..d58b75c2d2 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -115,6 +115,14 @@ LIBBINDER_NDK30 { # introduced=30 *; }; +LIBBINDER_NDK31 { # introduced=31 + global: + AIBinder_getCallingSid; # apex + AIBinder_setRequestingSid; # apex + local: + *; +}; + LIBBINDER_NDK_PLATFORM { global: AParcel_getAllowFds; diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl index 6e8e463ff1..4bba9e4317 100644 --- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl +++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl @@ -24,4 +24,6 @@ import IEmpty; interface IBinderNdkUnitTest { void takeInterface(IEmpty test); void forceFlushCommands(); + + boolean getsRequestedSid(); } diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index fd30d87c76..6869220727 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -19,6 +19,7 @@ #include <aidl/BnEmpty.h> #include <android-base/logging.h> #include <android/binder_ibinder_jni.h> +#include <android/binder_ibinder_platform.h> #include <android/binder_manager.h> #include <android/binder_process.h> #include <gtest/gtest.h> @@ -34,6 +35,7 @@ #include <sys/prctl.h> #include <chrono> #include <condition_variable> +#include <iostream> #include <mutex> using namespace android; @@ -52,6 +54,12 @@ class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest { android::IPCThreadState::self()->flushCommands(); return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus getsRequestedSid(bool* out) { + const char* sid = AIBinder_getCallingSid(); + std::cout << "Got security context: " << (sid ?: "null") << std::endl; + *out = sid != nullptr; + return ndk::ScopedAStatus::ok(); + } binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args, uint32_t numArgs) override { for (uint32_t i = 0; i < numArgs; i++) { @@ -66,8 +74,11 @@ int generatedService() { ABinderProcess_setThreadPoolMaxThreadCount(0); auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>(); - binder_status_t status = - AServiceManager_addService(service->asBinder().get(), kBinderNdkUnitTestService); + auto binder = service->asBinder(); + + AIBinder_setRequestingSid(binder.get(), true); + + binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService); if (status != STATUS_OK) { LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService; @@ -274,6 +285,16 @@ TEST(NdkBinder, AddServiceMultipleTimes) { EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2)); } +TEST(NdkBinder, RequestedSidWorks) { + ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService)); + std::shared_ptr<aidl::IBinderNdkUnitTest> service = + aidl::IBinderNdkUnitTest::fromBinder(binder); + + bool gotSid = false; + EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk()); + EXPECT_TRUE(gotSid); +} + TEST(NdkBinder, SentAidlBinderCanBeDestroyed) { static volatile bool destroyed = false; static std::mutex dMutex; |