Loading libs/binder/ndk/ibinder.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -24,10 +24,13 @@ #include <android-base/logging.h> #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <private/android_filesystem_config.h> using DeathRecipient = ::android::IBinder::DeathRecipient; using ::android::IBinder; using ::android::IResultReceiver; using ::android::Parcel; using ::android::sp; using ::android::status_t; Loading Loading @@ -158,6 +161,45 @@ status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parce binder_status_t status = getClass()->onTransact(this, code, &in, &out); return PruneStatusT(status); } else if (code == SHELL_COMMAND_TRANSACTION) { int in = data.readFileDescriptor(); int out = data.readFileDescriptor(); int err = data.readFileDescriptor(); int argc = data.readInt32(); std::vector<String8> utf8Args; // owns memory of utf8s std::vector<const char*> utf8Pointers; // what can be passed over NDK API for (int i = 0; i < argc && data.dataAvail() > 0; i++) { utf8Args.push_back(String8(data.readString16())); utf8Pointers.push_back(utf8Args[i].c_str()); } data.readStrongBinder(); // skip over the IShellCallback sp<IResultReceiver> resultReceiver = IResultReceiver::asInterface(data.readStrongBinder()); // Shell commands should only be callable by ADB. uid_t uid = AIBinder_getCallingUid(); if (uid != AID_ROOT && uid != AID_SHELL) { if (resultReceiver != nullptr) { resultReceiver->send(-1); } return STATUS_PERMISSION_DENIED; } // Check that the file descriptors are valid. if (in == STATUS_BAD_TYPE || out == STATUS_BAD_TYPE || err == STATUS_BAD_TYPE) { if (resultReceiver != nullptr) { resultReceiver->send(-1); } return STATUS_BAD_VALUE; } binder_status_t status = getClass()->handleShellCommand( this, in, out, err, utf8Pointers.data(), utf8Pointers.size()); if (resultReceiver != nullptr) { resultReceiver->send(status); } return status; } else { return BBinder::onTransact(code, data, reply, flags); } Loading Loading @@ -266,6 +308,13 @@ void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) { clazz->onDump = onDump; } void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz, AIBinder_handleShellCommand handleShellCommand) { CHECK(clazz != nullptr) << "setHandleShellCommand requires non-null clazz"; clazz->handleShellCommand = handleShellCommand; } void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) { CHECK(who == mWho); Loading libs/binder/ndk/ibinder_internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <android/binder_ibinder.h> #include <android/binder_shell.h> #include "ibinder_internal.h" #include <atomic> Loading Loading @@ -115,6 +116,7 @@ struct AIBinder_Class { // optional methods for a class AIBinder_onDump onDump; AIBinder_handleShellCommand handleShellCommand; private: // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to Loading libs/binder/ndk/include_ndk/android/binder_interface_utils.h +40 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,11 @@ #include <android/binder_auto_utils.h> #include <android/binder_ibinder.h> #if __has_include(<android/binder_shell.h>) #include <android/binder_shell.h> #define HAS_BINDER_SHELL_COMMAND #endif //_has_include #include <assert.h> #include <memory> Loading Loading @@ -108,7 +113,15 @@ class ICInterface : public SharedRefBase { /** * Dumps information about the interface. By default, dumps nothing. */ virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/); virtual inline binder_status_t dump(int fd, const char** args, uint32_t numArgs); #ifdef HAS_BINDER_SHELL_COMMAND /** * Process shell commands. By default, does nothing. */ virtual inline binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc); #endif /** * Interprets this binder as this underlying interface if this has stored an ICInterface in the Loading Loading @@ -136,6 +149,11 @@ class ICInterface : public SharedRefBase { static inline void onDestroy(void* userData); static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args, uint32_t numArgs); #ifdef HAS_BINDER_SHELL_COMMAND static inline binder_status_t handleShellCommand(AIBinder* binder, int in, int out, int err, const char** argv, uint32_t argc); #endif }; }; Loading Loading @@ -191,6 +209,13 @@ binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /* return STATUS_OK; } #ifdef HAS_BINDER_SHELL_COMMAND binder_status_t ICInterface::handleShellCommand(int /*in*/, int /*out*/, int /*err*/, const char** /*argv*/, uint32_t /*argc*/) { return STATUS_OK; } #endif std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) { return ICInterfaceData::getInterface(binder); } Loading @@ -203,9 +228,12 @@ AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor, return nullptr; } // We can't know if this method is overriden by a subclass interface, so we must register // ourselves. The default (nothing to dump) is harmless. // We can't know if these methods are overridden by a subclass interface, so we must register // ourselves. The defaults are harmless. AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump); #ifdef HAS_BINDER_SHELL_COMMAND AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand); #endif return clazz; } Loading Loading @@ -234,6 +262,15 @@ binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, c return interface->dump(fd, args, numArgs); } #ifdef HAS_BINDER_SHELL_COMMAND binder_status_t ICInterface::ICInterfaceData::handleShellCommand(AIBinder* binder, int in, int out, int err, const char** argv, uint32_t argc) { std::shared_ptr<ICInterface> interface = getInterface(binder); return interface->handleShellCommand(in, out, err, argv, argc); } #endif template <typename INTERFACE> SpAIBinder BnCInterface<INTERFACE>::asBinder() { std::lock_guard<std::mutex> l(mMutex); Loading libs/binder/ndk/include_platform/android/binder_shell.h 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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 /** * Function to execute a shell command. * * Available since API level 30. * * \param binder the binder executing the command * \param in input file descriptor, should be flushed, ownership is not passed * \param out output file descriptor, should be flushed, ownership is not passed * \param err error file descriptor, should be flushed, ownership is not passed * \param argv array of null-terminated strings for command (may be null if argc * is 0) * \param argc length of argv array * * \return binder_status_t result of transaction */ typedef binder_status_t (*AIBinder_handleShellCommand)(AIBinder* binder, int in, int out, int err, const char** argv, uint32_t argc); /** * This sets the implementation of handleShellCommand for a class. * * If this isn't set, nothing will be executed when handleShellCommand is called. * * Available since API level 30. * * \param handleShellCommand function to call when a shell transaction is * received */ void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz, AIBinder_handleShellCommand handleShellCommand) __INTRODUCED_IN(30); __END_DECLS libs/binder/ndk/libbinder_ndk.map.txt +1 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ LIBBINDER_NDK30 { # introduced=30 AIBinder_markSystemStability; # apex AIBinder_markVendorStability; # llndk AIBinder_markVintfStability; # apex llndk AIBinder_Class_setHandleShellCommand; # apex llndk local: *; }; Loading
libs/binder/ndk/ibinder.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -24,10 +24,13 @@ #include <android-base/logging.h> #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <private/android_filesystem_config.h> using DeathRecipient = ::android::IBinder::DeathRecipient; using ::android::IBinder; using ::android::IResultReceiver; using ::android::Parcel; using ::android::sp; using ::android::status_t; Loading Loading @@ -158,6 +161,45 @@ status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parce binder_status_t status = getClass()->onTransact(this, code, &in, &out); return PruneStatusT(status); } else if (code == SHELL_COMMAND_TRANSACTION) { int in = data.readFileDescriptor(); int out = data.readFileDescriptor(); int err = data.readFileDescriptor(); int argc = data.readInt32(); std::vector<String8> utf8Args; // owns memory of utf8s std::vector<const char*> utf8Pointers; // what can be passed over NDK API for (int i = 0; i < argc && data.dataAvail() > 0; i++) { utf8Args.push_back(String8(data.readString16())); utf8Pointers.push_back(utf8Args[i].c_str()); } data.readStrongBinder(); // skip over the IShellCallback sp<IResultReceiver> resultReceiver = IResultReceiver::asInterface(data.readStrongBinder()); // Shell commands should only be callable by ADB. uid_t uid = AIBinder_getCallingUid(); if (uid != AID_ROOT && uid != AID_SHELL) { if (resultReceiver != nullptr) { resultReceiver->send(-1); } return STATUS_PERMISSION_DENIED; } // Check that the file descriptors are valid. if (in == STATUS_BAD_TYPE || out == STATUS_BAD_TYPE || err == STATUS_BAD_TYPE) { if (resultReceiver != nullptr) { resultReceiver->send(-1); } return STATUS_BAD_VALUE; } binder_status_t status = getClass()->handleShellCommand( this, in, out, err, utf8Pointers.data(), utf8Pointers.size()); if (resultReceiver != nullptr) { resultReceiver->send(status); } return status; } else { return BBinder::onTransact(code, data, reply, flags); } Loading Loading @@ -266,6 +308,13 @@ void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) { clazz->onDump = onDump; } void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz, AIBinder_handleShellCommand handleShellCommand) { CHECK(clazz != nullptr) << "setHandleShellCommand requires non-null clazz"; clazz->handleShellCommand = handleShellCommand; } void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) { CHECK(who == mWho); Loading
libs/binder/ndk/ibinder_internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <android/binder_ibinder.h> #include <android/binder_shell.h> #include "ibinder_internal.h" #include <atomic> Loading Loading @@ -115,6 +116,7 @@ struct AIBinder_Class { // optional methods for a class AIBinder_onDump onDump; AIBinder_handleShellCommand handleShellCommand; private: // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to Loading
libs/binder/ndk/include_ndk/android/binder_interface_utils.h +40 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,11 @@ #include <android/binder_auto_utils.h> #include <android/binder_ibinder.h> #if __has_include(<android/binder_shell.h>) #include <android/binder_shell.h> #define HAS_BINDER_SHELL_COMMAND #endif //_has_include #include <assert.h> #include <memory> Loading Loading @@ -108,7 +113,15 @@ class ICInterface : public SharedRefBase { /** * Dumps information about the interface. By default, dumps nothing. */ virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/); virtual inline binder_status_t dump(int fd, const char** args, uint32_t numArgs); #ifdef HAS_BINDER_SHELL_COMMAND /** * Process shell commands. By default, does nothing. */ virtual inline binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc); #endif /** * Interprets this binder as this underlying interface if this has stored an ICInterface in the Loading Loading @@ -136,6 +149,11 @@ class ICInterface : public SharedRefBase { static inline void onDestroy(void* userData); static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args, uint32_t numArgs); #ifdef HAS_BINDER_SHELL_COMMAND static inline binder_status_t handleShellCommand(AIBinder* binder, int in, int out, int err, const char** argv, uint32_t argc); #endif }; }; Loading Loading @@ -191,6 +209,13 @@ binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /* return STATUS_OK; } #ifdef HAS_BINDER_SHELL_COMMAND binder_status_t ICInterface::handleShellCommand(int /*in*/, int /*out*/, int /*err*/, const char** /*argv*/, uint32_t /*argc*/) { return STATUS_OK; } #endif std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) { return ICInterfaceData::getInterface(binder); } Loading @@ -203,9 +228,12 @@ AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor, return nullptr; } // We can't know if this method is overriden by a subclass interface, so we must register // ourselves. The default (nothing to dump) is harmless. // We can't know if these methods are overridden by a subclass interface, so we must register // ourselves. The defaults are harmless. AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump); #ifdef HAS_BINDER_SHELL_COMMAND AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand); #endif return clazz; } Loading Loading @@ -234,6 +262,15 @@ binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, c return interface->dump(fd, args, numArgs); } #ifdef HAS_BINDER_SHELL_COMMAND binder_status_t ICInterface::ICInterfaceData::handleShellCommand(AIBinder* binder, int in, int out, int err, const char** argv, uint32_t argc) { std::shared_ptr<ICInterface> interface = getInterface(binder); return interface->handleShellCommand(in, out, err, argv, argc); } #endif template <typename INTERFACE> SpAIBinder BnCInterface<INTERFACE>::asBinder() { std::lock_guard<std::mutex> l(mMutex); Loading
libs/binder/ndk/include_platform/android/binder_shell.h 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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 /** * Function to execute a shell command. * * Available since API level 30. * * \param binder the binder executing the command * \param in input file descriptor, should be flushed, ownership is not passed * \param out output file descriptor, should be flushed, ownership is not passed * \param err error file descriptor, should be flushed, ownership is not passed * \param argv array of null-terminated strings for command (may be null if argc * is 0) * \param argc length of argv array * * \return binder_status_t result of transaction */ typedef binder_status_t (*AIBinder_handleShellCommand)(AIBinder* binder, int in, int out, int err, const char** argv, uint32_t argc); /** * This sets the implementation of handleShellCommand for a class. * * If this isn't set, nothing will be executed when handleShellCommand is called. * * Available since API level 30. * * \param handleShellCommand function to call when a shell transaction is * received */ void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz, AIBinder_handleShellCommand handleShellCommand) __INTRODUCED_IN(30); __END_DECLS
libs/binder/ndk/libbinder_ndk.map.txt +1 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ LIBBINDER_NDK30 { # introduced=30 AIBinder_markSystemStability; # apex AIBinder_markVendorStability; # llndk AIBinder_markVintfStability; # apex llndk AIBinder_Class_setHandleShellCommand; # apex llndk local: *; };