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

Commit 627eb30f authored by Nick Kralevich's avatar Nick Kralevich
Browse files

Update OTA installer to understand SELinux filesystem labels

Modify the OTA installer to understand SELinux filesystem labels.

We do this by introducing new set_perm2 / set_perm2_recursive
calls, which understand SELinux filesystem labels. These filesystem
labels are applied at the same time that we apply the
UID / GID / permission changes.

For compatibility, we preserve the behavior of the existing
set_perm / set_perm_recursive calls.

If the destination kernel doesn't support security labels, don't
fail. SELinux isn't enabled on all kernels.

Bug: 8985290
Change-Id: I99800499f01784199e4918a82e3e2db1089cf25b
parent 51c84694
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <errno.h>
#include <dirent.h>
#include <limits.h>
#include <selinux/selinux.h>

#include "DirUtil.h"

@@ -237,7 +238,7 @@ dirUnlinkHierarchy(const char *path)

int
dirSetHierarchyPermissions(const char *path,
        int uid, int gid, int dirMode, int fileMode)
        int uid, int gid, int dirMode, int fileMode, const char* secontext)
{
    struct stat st;
    if (lstat(path, &st)) {
@@ -255,6 +256,10 @@ dirSetHierarchyPermissions(const char *path,
        return -1;
    }

    if ((secontext != NULL) && lsetfilecon(path, secontext) && (errno != ENOTSUP)) {
        return -1;
    }

    /* recurse over directory components */
    if (S_ISDIR(st.st_mode)) {
        DIR *dir = opendir(path);
@@ -271,7 +276,7 @@ dirSetHierarchyPermissions(const char *path,

            char dn[PATH_MAX];
            snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
            if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode)) {
            if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode, secontext)) {
                errno = 0;
            } else if (errno == 0) {
                errno = -1;
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ int dirUnlinkHierarchy(const char *path);
 * Sets directories to <dirMode> and files to <fileMode>.  Skips symlinks.
 */
int dirSetHierarchyPermissions(const char *path,
         int uid, int gid, int dirMode, int fileMode);
         int uid, int gid, int dirMode, int fileMode, const char* secontext);

#ifdef __cplusplus
}
+24 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <selinux/selinux.h>

#include "cutils/misc.h"
#include "cutils/properties.h"
@@ -521,9 +522,10 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {

Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    bool recursive = (strcmp(name, "set_perm_recursive") == 0);
    bool recursive = (strcmp(name, "set_perm_recursive") == 0) || (strcmp(name, "set_perm2_recursive") == 0);
    bool has_selabel = (strcmp(name, "set_perm2") == 0) || (strcmp(name, "set_perm2_recursive") == 0);

    int min_args = 4 + (recursive ? 1 : 0);
    int min_args = 4 + (has_selabel ? 1 : 0) + (recursive ? 1 : 0);
    if (argc < min_args) {
        return ErrorAbort(state, "%s() expects %d+ args, got %d",
                          name, min_args, argc);
@@ -562,8 +564,13 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
            goto done;
        }

        for (i = 4; i < argc; ++i) {
            dirSetHierarchyPermissions(args[i], uid, gid, dir_mode, file_mode);
        char* secontext = NULL;
        if (has_selabel) {
            secontext = args[4];
        }

        for (i = 4 + (has_selabel ? 1 : 0); i < argc; ++i) {
            dirSetHierarchyPermissions(args[i], uid, gid, dir_mode, file_mode, secontext);
        }
    } else {
        int mode = strtoul(args[2], &end, 0);
@@ -572,7 +579,12 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
            goto done;
        }

        for (i = 3; i < argc; ++i) {
        char* secontext = NULL;
        if (has_selabel) {
            secontext = args[3];
        }

        for (i = 3 + (has_selabel ? 1 : 0); i < argc; ++i) {
            if (chown(args[i], uid, gid) < 0) {
                printf("%s: chown of %s to %d %d failed: %s\n",
                        name, args[i], uid, gid, strerror(errno));
@@ -583,6 +595,11 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
                        name, args[i], mode, strerror(errno));
                ++bad;
            }
            if (has_selabel && lsetfilecon(args[i], secontext) && (errno != ENOTSUP)) {
                printf("%s: lsetfilecon of %s to %s failed: %s\n",
                        name, args[i], secontext, strerror(errno));
                ++bad;
            }
        }
    }
    result = strdup("");
@@ -1135,6 +1152,8 @@ void RegisterInstallFunctions() {
    RegisterFunction("symlink", SymlinkFn);
    RegisterFunction("set_perm", SetPermFn);
    RegisterFunction("set_perm_recursive", SetPermFn);
    RegisterFunction("set_perm2", SetPermFn);
    RegisterFunction("set_perm2_recursive", SetPermFn);

    RegisterFunction("getprop", GetPropFn);
    RegisterFunction("file_getprop", FileGetPropFn);