diff options
author | markchien <markchien@google.com> | 2020-02-24 11:52:20 +0800 |
---|---|---|
committer | markchien <markchien@google.com> | 2020-03-05 17:38:56 +0800 |
commit | f97bab69bf2d90a665794d5fc9ffd7fd5ffa5379 (patch) | |
tree | 939d13f82514533317b02e022de4fda86ec97ef6 /server/NetdNativeService.cpp | |
parent | 89863936e13f39108485029ca6c6b65f24c162c9 (diff) | |
download | netd-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.cpp | 15 |
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)) { |