// Copyright (C) 2016 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.

#include "capabilities.h"

#include <sys/capability.h>
#include <sys/prctl.h>

#include <map>
#include <memory>

#include <android-base/logging.h>
#include <android-base/macros.h>

#define CAP_MAP_ENTRY(cap) { #cap, CAP_##cap }

static const std::map<std::string, int> cap_map = {
    CAP_MAP_ENTRY(CHOWN),
    CAP_MAP_ENTRY(DAC_OVERRIDE),
    CAP_MAP_ENTRY(DAC_READ_SEARCH),
    CAP_MAP_ENTRY(FOWNER),
    CAP_MAP_ENTRY(FSETID),
    CAP_MAP_ENTRY(KILL),
    CAP_MAP_ENTRY(SETGID),
    CAP_MAP_ENTRY(SETUID),
    CAP_MAP_ENTRY(SETPCAP),
    CAP_MAP_ENTRY(LINUX_IMMUTABLE),
    CAP_MAP_ENTRY(NET_BIND_SERVICE),
    CAP_MAP_ENTRY(NET_BROADCAST),
    CAP_MAP_ENTRY(NET_ADMIN),
    CAP_MAP_ENTRY(NET_RAW),
    CAP_MAP_ENTRY(IPC_LOCK),
    CAP_MAP_ENTRY(IPC_OWNER),
    CAP_MAP_ENTRY(SYS_MODULE),
    CAP_MAP_ENTRY(SYS_RAWIO),
    CAP_MAP_ENTRY(SYS_CHROOT),
    CAP_MAP_ENTRY(SYS_PTRACE),
    CAP_MAP_ENTRY(SYS_PACCT),
    CAP_MAP_ENTRY(SYS_ADMIN),
    CAP_MAP_ENTRY(SYS_BOOT),
    CAP_MAP_ENTRY(SYS_NICE),
    CAP_MAP_ENTRY(SYS_RESOURCE),
    CAP_MAP_ENTRY(SYS_TIME),
    CAP_MAP_ENTRY(SYS_TTY_CONFIG),
    CAP_MAP_ENTRY(MKNOD),
    CAP_MAP_ENTRY(LEASE),
    CAP_MAP_ENTRY(AUDIT_WRITE),
    CAP_MAP_ENTRY(AUDIT_CONTROL),
    CAP_MAP_ENTRY(SETFCAP),
    CAP_MAP_ENTRY(MAC_OVERRIDE),
    CAP_MAP_ENTRY(MAC_ADMIN),
    CAP_MAP_ENTRY(SYSLOG),
    CAP_MAP_ENTRY(WAKE_ALARM),
    CAP_MAP_ENTRY(BLOCK_SUSPEND),
    CAP_MAP_ENTRY(AUDIT_READ),
};

static_assert(CAP_LAST_CAP == CAP_AUDIT_READ, "CAP_LAST_CAP is not CAP_AUDIT_READ");

static bool ComputeCapAmbientSupported() {
    return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) >= 0;
}

static unsigned int ComputeLastValidCap() {
    // Android does not support kernels < 3.8. 'CAP_WAKE_ALARM' has been present since 3.0, see
    // http://lxr.free-electrons.com/source/include/linux/capability.h?v=3.0#L360.
    unsigned int last_valid_cap = CAP_WAKE_ALARM;
    for (; prctl(PR_CAPBSET_READ, last_valid_cap, 0, 0, 0) >= 0; ++last_valid_cap);

    // |last_valid_cap| will be the first failing value.
    return last_valid_cap - 1;
}

static bool DropBoundingSet(const CapSet& to_keep) {
    unsigned int last_valid_cap = GetLastValidCap();
    // When dropping the bounding set, attempt to drop capabilities reported at
    // run-time, not at compile-time.
    // If the run-time kernel is older than the compile-time headers, this
    // avoids dropping an invalid capability. If the run-time kernel is newer
    // than the headers, this guarantees all capabilities (even those unknown at
    // compile time) will be dropped.
    for (size_t cap = 0; cap <= last_valid_cap; ++cap) {
        if (cap < to_keep.size() && to_keep.test(cap)) {
            // No need to drop this capability.
            continue;
        }
        if (cap_drop_bound(cap) == -1) {
            PLOG(ERROR) << "cap_drop_bound(" << cap << ") failed";
            return false;
        }
    }
    return true;
}

static bool SetProcCaps(const CapSet& to_keep, bool add_setpcap) {
    cap_t caps = cap_init();
    auto deleter = [](cap_t* p) { cap_free(*p); };
    std::unique_ptr<cap_t, decltype(deleter)> ptr_caps(&caps, deleter);

    cap_clear(caps);
    cap_value_t value[1];
    for (size_t cap = 0; cap < to_keep.size(); ++cap) {
        if (to_keep.test(cap)) {
            value[0] = cap;
            if (cap_set_flag(caps, CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
                cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
                PLOG(ERROR) << "cap_set_flag(INHERITABLE|PERMITTED, " << cap << ") failed";
                return false;
            }
        }
    }

    if (add_setpcap) {
        value[0] = CAP_SETPCAP;
        if (cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
            cap_set_flag(caps, CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
            PLOG(ERROR) << "cap_set_flag(PERMITTED|EFFECTIVE, " << CAP_SETPCAP << ") failed";
            return false;
        }
    }

    if (cap_set_proc(caps) != 0) {
        PLOG(ERROR) << "cap_set_proc(" << to_keep.to_ulong() << ") failed";
        return false;
    }
    return true;
}

static bool SetAmbientCaps(const CapSet& to_raise) {
    for (size_t cap = 0; cap < to_raise.size(); ++cap) {
        if (to_raise.test(cap)) {
            if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) != 0) {
                PLOG(ERROR) << "prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, " << cap << ") failed";
                return false;
            }
        }
    }
    return true;
}

int LookupCap(const std::string& cap_name) {
    auto e = cap_map.find(cap_name);
    if (e != cap_map.end()) {
        return e->second;
    } else {
        return -1;
    }
}

bool CapAmbientSupported() {
    static bool cap_ambient_supported = ComputeCapAmbientSupported();
    return cap_ambient_supported;
}

unsigned int GetLastValidCap() {
    static unsigned int last_valid_cap = ComputeLastValidCap();
    return last_valid_cap;
}

bool SetCapsForExec(const CapSet& to_keep) {
    // Need to keep SETPCAP to drop bounding set below.
    bool add_setpcap = true;
    if (!SetProcCaps(to_keep, add_setpcap)) {
        LOG(ERROR) << "failed to apply initial capset";
        return false;
    }

    if (!DropBoundingSet(to_keep)) {
        return false;
    }

    // If SETPCAP wasn't specifically requested, drop it now.
    add_setpcap = false;
    if (!SetProcCaps(to_keep, add_setpcap)) {
        LOG(ERROR) << "failed to apply final capset";
        return false;
    }

    // Add the capabilities to the ambient set so that they are preserved across
    // execve(2).
    // See http://man7.org/linux/man-pages/man7/capabilities.7.html.
    return SetAmbientCaps(to_keep);
}
