// 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 {
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");

bool DropBoundingSet(const CapSet& to_keep) {
    for (size_t cap = 0; cap < to_keep.size(); ++cap) {
        if (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;
}

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

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

}  // namespace anonymous

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