// 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 }

namespace android {
namespace init {

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);
}

}  // namespace init
}  // namespace android
