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

Commit 0c8d6d27 authored by Tom Cherry's avatar Tom Cherry
Browse files

init: split security functions out of init.cpp

This change splits out the selinux initialization and supporting
functionality into selinux.cpp and splits the security related
initialization of the rng, etc to security.cpp.  It also provides
additional documentation for SEPolicy loading as this has been
requested by some teams.

It additionally cleans up sehandle and sehandle_prop.  The former is
static within selinux.cpp and new wrapper functions are created around
selabel_lookup*() to better serve the users.  The latter is moved to
property_service.cpp as it is isolated to that file for its usage.

Test: boot bullhead
Merged-In: Idc95d493cebc681fbe686b5160502f36af149f60
Change-Id: Idc95d493cebc681fbe686b5160502f36af149f60
parent bb2f03f3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ cc_library_static {
        "log.cpp",
        "parser.cpp",
        "property_service.cpp",
        "security.cpp",
        "selinux.cpp",
        "service.cpp",
        "tokenizer.cpp",
        "uevent_listener.cpp",
+12 −25
Original line number Diff line number Diff line
@@ -225,24 +225,23 @@ static int do_insmod(const std::vector<std::string>& args) {
    return insmod(filename.c_str(), options.c_str(), flags);
}

// mkdir <path> [mode] [owner] [group]
static int do_mkdir(const std::vector<std::string>& args) {
    mode_t mode = 0755;
    int ret;

    /* mkdir <path> [mode] [owner] [group] */

    if (args.size() >= 3) {
        mode = std::strtoul(args[2].c_str(), 0, 8);
    }

    ret = make_dir(args[1].c_str(), mode, sehandle);
    if (!make_dir(args[1], mode)) {
        /* chmod in case the directory already exists */
    if (ret == -1 && errno == EEXIST) {
        ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW);
        if (errno == EEXIST) {
            if (fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW) == -1) {
                return -errno;
            }
    if (ret == -1) {
        } else {
            return -errno;
        }
    }

    if (args.size() >= 4) {
        uid_t uid;
@@ -266,8 +265,7 @@ static int do_mkdir(const std::vector<std::string>& args) {

        /* chown may have cleared S_ISUID and S_ISGID, chmod again */
        if (mode & (S_ISUID | S_ISGID)) {
            ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW);
            if (ret == -1) {
            if (fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW) == -1) {
                return -errno;
            }
        }
@@ -895,17 +893,6 @@ static int do_wait_for_prop(const std::vector<std::string>& args) {
    return 0;
}

/*
 * Callback to make a directory from the ext4 code
 */
static int do_installkeys_ensure_dir_exists(const char* dir) {
    if (make_dir(dir, 0700, sehandle) && errno != EEXIST) {
        return -1;
    }

    return 0;
}

static bool is_file_crypto() {
    return android::base::GetProperty("ro.crypto.type", "") == "file";
}
@@ -915,7 +902,7 @@ static int do_installkey(const std::vector<std::string>& args) {
        return 0;
    }
    auto unencrypted_dir = args[1] + e4crypt_unencrypted_folder;
    if (do_installkeys_ensure_dir_exists(unencrypted_dir.c_str())) {
    if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) {
        PLOG(ERROR) << "Failed to create " << unencrypted_dir;
        return -1;
    }
+1 −2
Original line number Diff line number Diff line
@@ -86,8 +86,7 @@ int SocketInfo::Create(const std::string& context) const {
    int flags =
        ((types[0] == "stream" ? SOCK_STREAM : (types[0] == "dgram" ? SOCK_DGRAM : SOCK_SEQPACKET)));
    bool passcred = types.size() > 1 && types[1] == "passcred";
    return CreateSocket(name().c_str(), flags, passcred, perm(), uid(), gid(), context.c_str(),
                        sehandle);
    return CreateSocket(name().c_str(), flags, passcred, perm(), uid(), gid(), context.c_str());
}

const std::string SocketInfo::key() const {
+14 −20
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <selinux/android.h>
#include <selinux/selinux.h>

#include "selinux.h"
#include "ueventd.h"
#include "util.h"

@@ -224,18 +225,13 @@ void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, i
    auto[mode, uid, gid] = GetDevicePermissions(path, links);
    mode |= (block ? S_IFBLK : S_IFCHR);

    char* secontext = nullptr;
    if (sehandle_) {
        std::vector<const char*> c_links;
        for (const auto& link : links) {
            c_links.emplace_back(link.c_str());
        }
        c_links.emplace_back(nullptr);
        if (selabel_lookup_best_match(sehandle_, &secontext, path.c_str(), &c_links[0], mode)) {
    std::string secontext;
    if (!SelabelLookupFileContextBestMatch(path, links, mode, &secontext)) {
        PLOG(ERROR) << "Device '" << path << "' not created; cannot find SELinux label";
        return;
    }
        setfscreatecon(secontext);
    if (!secontext.empty()) {
        setfscreatecon(secontext.c_str());
    }

    dev_t dev = makedev(major, minor);
@@ -250,7 +246,7 @@ void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, i
    }
    /* If the node already exists update its SELinux label to handle cases when
     * it was created with the wrong context during coldboot procedure. */
    if (mknod(path.c_str(), mode, dev) && (errno == EEXIST) && secontext) {
    if (mknod(path.c_str(), mode, dev) && (errno == EEXIST) && !secontext.empty()) {
        char* fcon = nullptr;
        int rc = lgetfilecon(path.c_str(), &fcon);
        if (rc < 0) {
@@ -258,10 +254,10 @@ void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, i
            goto out;
        }

        bool different = strcmp(fcon, secontext) != 0;
        bool different = fcon != secontext;
        freecon(fcon);

        if (different && lsetfilecon(path.c_str(), secontext)) {
        if (different && lsetfilecon(path.c_str(), secontext.c_str())) {
            PLOG(ERROR) << "Cannot set '" << secontext << "' SELinux label on '" << path
                        << "' device";
        }
@@ -273,8 +269,7 @@ out:
        PLOG(FATAL) << "setegid(AID_ROOT) failed";
    }

    if (secontext) {
        freecon(secontext);
    if (!secontext.empty()) {
        setfscreatecon(nullptr);
    }
}
@@ -351,7 +346,7 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
    if (action == "add") {
        MakeDevice(devpath, block, major, minor, links);
        for (const auto& link : links) {
            if (mkdir_recursive(Dirname(link), 0755, sehandle_)) {
            if (!mkdir_recursive(Dirname(link), 0755)) {
                PLOG(ERROR) << "Failed to create directory " << Dirname(link);
            }

@@ -415,7 +410,7 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
        devpath = "/dev/" + Basename(uevent.path);
    }

    mkdir_recursive(Dirname(devpath), 0755, sehandle_);
    mkdir_recursive(Dirname(devpath), 0755);

    HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links);
}
@@ -426,7 +421,6 @@ DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
    : dev_permissions_(std::move(dev_permissions)),
      sysfs_permissions_(std::move(sysfs_permissions)),
      subsystems_(std::move(subsystems)),
      sehandle_(selinux_android_file_context_handle()),
      skip_restorecon_(skip_restorecon),
      sysfs_mount_point_("/sys") {}

+0 −1
Original line number Diff line number Diff line
@@ -124,7 +124,6 @@ class DeviceHandler {
    std::vector<Permissions> dev_permissions_;
    std::vector<SysfsPermissions> sysfs_permissions_;
    std::vector<Subsystem> subsystems_;
    selabel_handle* sehandle_;
    bool skip_restorecon_;
    std::string sysfs_mount_point_;
};
Loading