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

Commit fcf3d207 authored by Nick Kralevich's avatar Nick Kralevich Committed by Gerrit Code Review
Browse files

Merge "adb: configure /system file permission with fs_config"

parents 4958d85d 20d33f4d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)

LOCAL_STATIC_LIBRARIES := liblog libcutils libc libmincrypt
LOCAL_STATIC_LIBRARIES := liblog libcutils libc libmincrypt libselinux
include $(BUILD_EXECUTABLE)


+64 −9
Original line number Diff line number Diff line
@@ -22,19 +22,32 @@
#include <sys/types.h>
#include <dirent.h>
#include <utime.h>
#include <unistd.h>

#include <errno.h>

#include <private/android_filesystem_config.h>
#include <selinux/android.h>
#include "sysdeps.h"

#define TRACE_TAG  TRACE_SYNC
#include "adb.h"
#include "file_sync_service.h"

/* TODO: use fs_config to configure permissions on /data */
static bool is_on_system(const char *name) {
    const char *SYSTEM = "/system/";
    return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0);
}

static int mkdirs(char *name)
{
    int ret;
    char *x = name + 1;
    unsigned int uid, gid;
    unsigned int mode = 0775;
    uint64_t cap = 0;
    uid = getuid();
    gid = getgid();

    if(name[0] != '/') return -1;

@@ -42,11 +55,21 @@ static int mkdirs(char *name)
        x = adb_dirstart(x);
        if(x == 0) return 0;
        *x = 0;
        ret = adb_mkdir(name, 0775);
        if (is_on_system(name)) {
            fs_config(name, 1, &uid, &gid, &mode, &cap);
        }
        ret = adb_mkdir(name, mode);
        if((ret < 0) && (errno != EEXIST)) {
            D("mkdir(\"%s\") -> %s\n", name, strerror(errno));
            *x = '/';
            return ret;
        } else if(ret == 0) {
            ret = chown(name, uid, gid);
            if (ret < 0) {
                *x = '/';
                return ret;
            }
            selinux_android_restorecon(name);
        }
        *x++ = '/';
    }
@@ -149,7 +172,8 @@ static int fail_errno(int s)
    return fail_message(s, strerror(errno));
}

static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
static int handle_send_file(int s, char *path, unsigned int uid,
        unsigned int gid, mode_t mode, char *buffer)
{
    syncmsg msg;
    unsigned int timestamp = 0;
@@ -157,9 +181,14 @@ static int handle_send_file(int s, char *path, mode_t mode, char *buffer)

    fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
    if(fd < 0 && errno == ENOENT) {
        mkdirs(path);
        if(mkdirs(path) != 0) {
            if(fail_errno(s))
                return -1;
            fd = -1;
        } else {
            fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
        }
    }
    if(fd < 0 && errno == EEXIST) {
        fd = adb_open_mode(path, O_WRONLY, mode);
    }
@@ -167,6 +196,16 @@ static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
        if(fail_errno(s))
            return -1;
        fd = -1;
    } else {
        if(fchown(fd, uid, gid) != 0) {
            fail_errno(s);
            errno = 0;
        }
        /* fchown clears the setuid bit - restore it if present */
        if(fchmod(fd, mode) != 0) {
            fail_errno(s);
            errno = 0;
        }
    }

    for(;;) {
@@ -206,6 +245,7 @@ static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
    if(fd >= 0) {
        struct utimbuf u;
        adb_close(fd);
        selinux_android_restorecon(path);
        u.actime = timestamp;
        u.modtime = timestamp;
        utime(path, &u);
@@ -249,7 +289,10 @@ static int handle_send_link(int s, char *path, char *buffer)

    ret = symlink(buffer, path);
    if(ret && errno == ENOENT) {
        mkdirs(path);
        if(mkdirs(path) != 0) {
            fail_errno(s);
            return -1;
        }
        ret = symlink(buffer, path);
    }
    if(ret) {
@@ -277,7 +320,7 @@ static int handle_send_link(int s, char *path, char *buffer)
static int do_send(int s, char *path, char *buffer)
{
    char *tmp;
    mode_t mode;
    unsigned int mode;
    int is_link, ret;

    tmp = strrchr(path,',');
@@ -288,7 +331,7 @@ static int do_send(int s, char *path, char *buffer)
#ifndef HAVE_SYMLINKS
        is_link = 0;
#else
        is_link = S_ISLNK(mode);
        is_link = S_ISLNK((mode_t) mode);
#endif
        mode &= 0777;
    }
@@ -307,11 +350,23 @@ static int do_send(int s, char *path, char *buffer)
#else
    {
#endif
        unsigned int uid, gid;
        uint64_t cap = 0;
        uid = getuid();
        gid = getgid();

        /* copy user permission bits to "group" and "other" permissions */
        mode |= ((mode >> 3) & 0070);
        mode |= ((mode >> 3) & 0007);

        ret = handle_send_file(s, path, mode, buffer);
        tmp = path;
        if(*tmp == '/') {
            tmp++;
        }
        if (is_on_system(path)) {
            fs_config(tmp, 0, &uid, &gid, &mode, &cap);
        }
        ret = handle_send_file(s, path, uid, gid, mode, buffer);
    }

    return ret;