Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 403c0440 authored by Luke Huang's avatar Luke Huang
Browse files

Add a binder service endpoint in libnetd_resolv

Create a new binder service endpoint in libnetd_resolv.

Bug: 126141549
Test: built, flashed, booted
      system/netd/tests/runtests.sh pass

Change-Id: I420be2a0df9dd65bdd78a50fcb1f61fbb427c7ec
parent 35bfddfb
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -3,6 +3,16 @@ cc_library_headers {
    export_include_dirs: ["include"],
}

aidl_interface {
    name: "dnsresolver_aidl_interface",
    local_include_dir: "binder",
    srcs: [
        "binder/android/net/IDnsResolver.aidl",
    ],
    api_dir: "binder/api",
    // Enable gen_log after it is supported in NDK backend. b/126501406
}

cc_library {
    name: "libnetd_resolv",
    version_script: "libnetd_resolv.map.txt",
@@ -21,6 +31,7 @@ cc_library {
        "res_state.cpp",
        "res_stats.cpp",
        "DnsProxyListener.cpp",
        "DnsResolverService.cpp",
        "DnsTlsDispatcher.cpp",
        "DnsTlsQueryMap.cpp",
        "DnsTlsTransport.cpp",
@@ -42,6 +53,7 @@ cc_library {
        "libssl",
        "libsysutils",
        "netd_event_listener_interface-ndk_platform",
        "dnsresolver_aidl_interface-ndk_platform",
    ],
    shared_libs: [
        "libbinder_ndk",
@@ -71,6 +83,7 @@ cc_test {
    srcs: [
        "dns_responder/dns_responder.cpp",
        "resolver_test.cpp",
        "dnsresolver_binder_test.cpp",
    ],
    include_dirs: [
        "system/netd/resolv/include",
@@ -92,6 +105,7 @@ cc_test {
        "libnetdutils",
        "netd_aidl_interface-cpp",
        "netd_event_listener_interface-cpp",
        "dnsresolver_aidl_interface-cpp",
    ],
    compile_multilib: "both",
    sanitize: {
+6 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@

// TODO: Considering moving ResponseCode.h Stopwatch.h thread_util.h to libnetdutils.
#include "DnsProxyListener.h"
#include "DnsResolverService.h"
#include "NetdClient.h"  // NETID_USE_LOCAL_NAMESERVERS
#include "NetdPermissions.h"
#include "ResolverEventReporter.h"
@@ -80,6 +81,11 @@ bool resolv_init(const dnsproxylistener_callbacks& callbacks) {
        ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));
        return false;
    }
    binder_status_t ret;
    if ((ret = android::net::DnsResolverService::start(callbacks)) != STATUS_OK) {
        ALOGE("Unable to start DnsResolverService: %d", ret);
        return false;
    }
    return true;
}

DnsResolverService.cpp

0 → 100644
+117 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2019, 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.
 */

#define LOG_TAG "DnsResolverService"

#include <set>
#include <vector>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>  // AID_SYSTEM

#include "DnsResolverService.h"
#include "NetdPermissions.h"  // PERM_*

using android::base::Join;
using android::base::StringPrintf;

namespace android {
namespace net {

namespace {

#define ENFORCE_ANY_PERMISSION(...)                                      \
    do {                                                                 \
        ::ndk::ScopedAStatus status = checkAnyPermission({__VA_ARGS__}); \
        if (!status.isOk()) {                                            \
            return status;                                               \
        }                                                                \
    } while (0)

#define ENFORCE_INTERNAL_PERMISSIONS() \
    ENFORCE_ANY_PERMISSION(PERM_CONNECTIVITY_INTERNAL, PERM_MAINLINE_NETWORK_STACK)

#define ENFORCE_NETWORK_STACK_PERMISSIONS() \
    ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK)

}  // namespace

binder_status_t DnsResolverService::start(const dnsproxylistener_callbacks& callbacks) {
    // TODO: Add disableBackgroundScheduling(true) after libbinder_ndk support it. b/126506010
    // NetdNativeService does call disableBackgroundScheduling currently, so it is fine now.
    DnsResolverService* resolverService = new DnsResolverService(callbacks);
    binder_status_t status =
            AServiceManager_addService(resolverService->asBinder().get(), getServiceName());
    if (status != STATUS_OK) {
        return status;
    }

    ABinderProcess_startThreadPool();

    // TODO: register log callback if binder NDK backend support it. b/126501406

    return STATUS_OK;
}

::ndk::ScopedAStatus DnsResolverService::isAlive(bool* alive) {
    ENFORCE_INTERNAL_PERMISSIONS();

    *alive = true;

    return ::ndk::ScopedAStatus(AStatus_newOk());
}

::ndk::ScopedAStatus DnsResolverService::checkAnyPermission(
        const std::vector<const char*>& permissions) {
    // TODO: Remove callback and move this to unnamed namespace after libbiner_ndk supports
    // check_permission.
    if (!mCallbacks.check_calling_permission) {
        return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
                EX_NULL_POINTER, "check_calling_permission is null"));
    }
    pid_t pid = AIBinder_getCallingPid();
    uid_t uid = AIBinder_getCallingUid();

    // 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
    //
    // From a security perspective, there is currently no difference, because:
    // 1. The only permissions we check in netd's binder interface are CONNECTIVITY_INTERNAL
    //    and NETWORK_STACK, which the system server always has (or MAINLINE_NETWORK_STACK, which
    //    is equivalent to having both CONNECTIVITY_INTERNAL and NETWORK_STACK).
    // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
    if (uid == AID_SYSTEM) {
        return ::ndk::ScopedAStatus(AStatus_newOk());
    }

    for (const char* permission : permissions) {
        if (mCallbacks.check_calling_permission(permission)) {
            return ::ndk::ScopedAStatus(AStatus_newOk());
        }
    }

    auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s",
                            uid, pid, Join(permissions, ',').c_str());
    return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str()));
}

}  // namespace net
}  // namespace android

DnsResolverService.h

0 → 100644
+49 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2019, 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.
 */

#ifndef _DNS_RESOLVER_SERVICE_H_
#define _DNS_RESOLVER_SERVICE_H_

#include <vector>

#include <aidl/android/net/BnDnsResolver.h>
#include <android/binder_ibinder.h>

#include "netd_resolv/resolv.h"

namespace android {
namespace net {

class DnsResolverService : public aidl::android::net::BnDnsResolver {
  public:
    DnsResolverService(const dnsproxylistener_callbacks& callbacks) : mCallbacks(callbacks) {}
    static binder_status_t start(const dnsproxylistener_callbacks& callbacks);
    static char const* getServiceName() { return "dnsresolver"; }
    // TODO: Add dump() after libbinder_ndk support it.

    ::ndk::ScopedAStatus isAlive(bool* alive) override;

  private:
    // TODO: Remove below items after libbiner_ndk supports check_permission.
    ::ndk::ScopedAStatus checkAnyPermission(const std::vector<const char*>& permissions);

    dnsproxylistener_callbacks mCallbacks{};
};

}  // namespace net
}  // namespace android

#endif  // _DNS_RESOLVER_SERVICE_H_
+25 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2019, 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.
 */

package android.net;

/** {@hide} */
interface IDnsResolver {
    /**
     * Returns true if the service is responding.
     */
    boolean isAlive();
}
Loading