summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2019-07-10 18:35:46 -0700
committer Steven Moreland <smoreland@google.com> 2019-07-11 20:32:41 +0000
commitf0f97d362a7ca644ac41542a12cc674e090135d3 (patch)
tree947cad4f9082c42e7fa848833bd0dda57e161d4b
parentadd824adfe02d6c2e710d5f94ea5597f165ee1fa (diff)
libbinder: require shell/root UID for shell
The APIs under SHELL_COMMAND_TRANSACTION are considered to be development APIs and are not suitable for actual usage on the device, especially where the APIs need to be stable over long periods of time. Bug: N/A Test: as follows walleye:/ # su root cmd package list packages <successful output> walleye:/ # su shell cmd package list packages <successful output> walleye:/ # su system cmd package list packages cmd: Failure calling service package: Operation not permitted (1) Change-Id: I236281ba0346711f89507d026eadd5ae3c9337b1
-rw-r--r--libs/binder/Binder.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 96ee29556c..7324cf5bea 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -17,12 +17,15 @@
#include <binder/Binder.h>
#include <atomic>
-#include <utils/misc.h>
#include <binder/BpBinder.h>
#include <binder/IInterface.h>
+#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
#include <binder/IShellCallback.h>
#include <binder/Parcel.h>
+#include <cutils/android_filesystem_config.h>
+#include <cutils/compiler.h>
+#include <utils/misc.h>
#include <stdio.h>
@@ -125,6 +128,19 @@ status_t BBinder::transact(
{
data.setDataPosition(0);
+ // Shell command transaction is conventionally implemented by
+ // overriding onTransact by copy/pasting the parceling code from
+ // this file. So, we must check permissions for it before we call
+ // onTransact. This check is here because shell APIs aren't
+ // guaranteed to be stable, and so they should only be used by
+ // developers.
+ if (CC_UNLIKELY(code == SHELL_COMMAND_TRANSACTION)) {
+ uid_t uid = IPCThreadState::self()->getCallingUid();
+ if (uid != AID_SHELL && uid != AID_ROOT) {
+ return PERMISSION_DENIED;
+ }
+ }
+
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION: