summaryrefslogtreecommitdiff
path: root/server/NetdNativeService.cpp
diff options
context:
space:
mode:
authormarkchien <markchien@google.com>2020-02-24 11:52:20 +0800
committermarkchien <markchien@google.com>2020-03-05 17:38:56 +0800
commitf97bab69bf2d90a665794d5fc9ffd7fd5ffa5379 (patch)
tree939d13f82514533317b02e022de4fda86ec97ef6 /server/NetdNativeService.cpp
parent89863936e13f39108485029ca6c6b65f24c162c9 (diff)
downloadnetd-f97bab69bf2d90a665794d5fc9ffd7fd5ffa5379.tar.gz
Don't check MAINLINE_NETWORK_STACK permission for network stack
Checking permissions requires a binder IPC to the system server. There is cross process dead lock due to binder thread exhaustion. 1. Nework stack fired a IPC to netd. 2. Netd reqired binder IPC to check permission but no free binder thread. 3. System server is waiting the resulting call in netd. Fix this by not checking mainline_network_stack permission if the caller is network stack. Bug: 149766727 Test: ON/OFF hotspot Change-Id: I9715fa0cb7c1157d134279717222dadedf0268c5
Diffstat (limited to 'server/NetdNativeService.cpp')
-rw-r--r--server/NetdNativeService.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 9c912494..09be1754 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -64,10 +64,15 @@ namespace net {
namespace {
const char OPT_SHORT[] = "--short";
+// The input permissions should be equivalent that this function would return ok if any of them is
+// granted.
binder::Status checkAnyPermission(const std::vector<const char*>& permissions) {
pid_t pid = IPCThreadState::self()->getCallingPid();
uid_t uid = IPCThreadState::self()->getCallingUid();
+ // TODO: Do the pure permission check in this function. Have another method
+ // (e.g. checkNetworkStackPermission) to wrap AID_SYSTEM and
+ // AID_NETWORK_STACK uid check.
// If the caller is the system UID, don't check permissions.
// Otherwise, if the system server's binder thread pool is full, and all the threads are
// blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
@@ -80,6 +85,16 @@ binder::Status checkAnyPermission(const std::vector<const char*>& permissions) {
if (uid == AID_SYSTEM) {
return binder::Status::ok();
}
+ // AID_NETWORK_STACK own MAINLINE_NETWORK_STACK permission, don't IPC to system server to check
+ // MAINLINE_NETWORK_STACK permission. Cross-process(netd, networkstack and system server)
+ // deadlock: http://b/149766727
+ if (uid == AID_NETWORK_STACK) {
+ for (const char* permission : permissions) {
+ if (std::strcmp(permission, PERM_MAINLINE_NETWORK_STACK) == 0) {
+ return binder::Status::ok();
+ }
+ }
+ }
for (const char* permission : permissions) {
if (checkPermission(String16(permission), pid, uid)) {