diff --git a/jni/Android.mk b/jni/Android.mk index 516efffb1..1abc9ce44 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -93,8 +93,8 @@ include $(BUILD_EXECUTABLE) ifeq ($(TARGET_ARCH_ABI), arm64-v8a) include $(CLEAR_VARS) LOCAL_MODULE := magiskinit -LOCAL_STATIC_LIBRARIES := libsepol libselinux_static -LOCAL_C_INCLUDES := jni/include $(LIBSEPOL) $(LIBSELINUX) +LOCAL_STATIC_LIBRARIES := libsepol +LOCAL_C_INCLUDES := jni/include $(LIBSEPOL) LOCAL_SRC_FILES := \ magiskinit.c \ magiskboot/boot_utils.c \ @@ -103,6 +103,7 @@ LOCAL_SRC_FILES := \ magiskpolicy/rules.c \ magiskpolicy/sepolicy.c \ magiskpolicy/api.c +LOCAL_CFLAGS := -DNO_SELINUX LOCAL_LDFLAGS := -static include $(BUILD_EXECUTABLE) endif diff --git a/jni/external/Android.mk b/jni/external/Android.mk index 41138688a..dae2530af 100644 --- a/jni/external/Android.mk +++ b/jni/external/Android.mk @@ -14,14 +14,6 @@ LOCAL_C_INCLUDES := $(LIBSELINUX) LOCAL_SRC_FILES := stubs/selinux_stub.c include $(BUILD_SHARED_LIBRARY) -# libselinux_static.a (stub) -include $(CLEAR_VARS) -LOCAL_MODULE:= libselinux_static -LOCAL_C_INCLUDES := $(LIBSELINUX) -LOCAL_SRC_FILES := stubs/selinux_stub.c -include $(BUILD_STATIC_LIBRARY) - - # libfdt include $(CLEAR_VARS) LOCAL_MODULE:= libfdt diff --git a/jni/include/utils.h b/jni/include/utils.h index c22d93a10..d979bd622 100644 --- a/jni/include/utils.h +++ b/jni/include/utils.h @@ -99,6 +99,7 @@ struct file_attr { char con[128]; }; +int fd_getpath(int fd, char *path, size_t size); int mkdir_p(const char *pathname, mode_t mode); void rm_rf(const char *path); void frm_rf(int dirfd); diff --git a/jni/utils/file.c b/jni/utils/file.c index e50d25d30..0ce2e881a 100644 --- a/jni/utils/file.c +++ b/jni/utils/file.c @@ -5,7 +5,10 @@ #include #include #include + +#ifndef NO_SELINUX #include +#endif #include "utils.h" @@ -19,6 +22,13 @@ static int is_excl(const char *name) { return 0; } +int fd_getpath(int fd, char *path, size_t size) { + snprintf(path, size, "/proc/self/fd/%d", fd); + if (xreadlink(path, path, size) == -1) + return -1; + return 0; +} + int mkdir_p(const char *pathname, mode_t mode) { char *path = strdup(pathname), *p; errno = 0; @@ -201,16 +211,22 @@ void clone_dir(int src, int dest) { } int getattr(const char *path, struct file_attr *a) { - int fd = open(path, O_PATH | O_NOFOLLOW | O_CLOEXEC); - if (fd < 0) + if (xlstat(path, &a->st) == -1) return -1; - int ret = fgetattr(fd, a); - close(fd); - return ret; + char *con = ""; +#ifndef NO_SELINUX + if (lgetfilecon(path, &con) == -1) + return -1; + strcpy(a->con, con); + freecon(con); +#else + a->con[0] = '\0'; +#endif + return 0; } int getattrat(int dirfd, const char *pathname, struct file_attr *a) { - int fd = openat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC); + int fd = xopenat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC); if (fd < 0) return -1; int ret = fgetattr(fd, a); @@ -219,27 +235,32 @@ int getattrat(int dirfd, const char *pathname, struct file_attr *a) { } int fgetattr(int fd, struct file_attr *a) { - if (fstat(fd, &a->st) < 0) +#ifndef NO_SELINUX + char path[PATH_MAX]; + fd_getpath(fd, path, sizeof(path)); + return getattr(path, a); +#else + if (fstat(fd, &a->st) == -1) return -1; - char *con = ""; - if (fgetfilecon(fd, &con) < 0) - return -1; - strcpy(a->con, con); - freecon(con); + a->con[0] = '\0'; return 0; +#endif } int setattr(const char *path, struct file_attr *a) { - int fd = open(path, O_PATH | O_NOFOLLOW | O_CLOEXEC); - if (fd < 0) + if (chmod(path, a->st.st_mode & 0777) < 0) return -1; - int ret = fsetattr(fd, a); - close(fd); - return ret; + if (chown(path, a->st.st_uid, a->st.st_gid) < 0) + return -1; +#ifndef NO_SELINUX + if (strlen(a->con) && lsetfilecon(path, a->con) < 0) + return -1; +#endif + return 0; } int setattrat(int dirfd, const char *pathname, struct file_attr *a) { - int fd = openat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC); + int fd = xopenat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC); if (fd < 0) return -1; int ret = fsetattr(fd, a); @@ -248,13 +269,17 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a) { } int fsetattr(int fd, struct file_attr *a) { +#ifndef NO_SELINUX + char path[PATH_MAX]; + fd_getpath(fd, path, sizeof(path)); + return setattr(path, a); +#else if (fchmod(fd, a->st.st_mode & 0777) < 0) return -1; if (fchown(fd, a->st.st_uid, a->st.st_gid) < 0) return -1; - if (strlen(a->con) && fsetfilecon(fd, a->con) < 0) - return -1; return 0; +#endif } void clone_attr(const char *source, const char *target) { @@ -269,6 +294,8 @@ void fclone_attr(const int sourcefd, const int targetfd) { fsetattr(targetfd, &a); } +#ifndef NO_SELINUX + #define UNLABEL_CON "u:object_r:unlabeled:s0" #define SYSTEM_CON "u:object_r:system_file:s0" @@ -276,11 +303,12 @@ void restorecon(int dirfd, int force) { struct dirent *entry; DIR *dir; int fd; - char *con; + char path[PATH_MAX], *con; - fgetfilecon(dirfd, &con); + fd_getpath(dirfd, path, sizeof(path)); + lgetfilecon(path, &con); if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) - fsetfilecon(dirfd, SYSTEM_CON); + lsetfilecon(path, SYSTEM_CON); freecon(con); dir = xfdopendir(dirfd); @@ -292,11 +320,14 @@ void restorecon(int dirfd, int force) { restorecon(fd, force); } else { fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); - fgetfilecon(fd, &con); + fd_getpath(fd, path, sizeof(path)); + lgetfilecon(path, &con); if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) - fsetfilecon(fd, SYSTEM_CON); + lsetfilecon(path, SYSTEM_CON); freecon(con); } close(fd); } } + +#endif // NO_SELINUX diff --git a/jni/utils/img.c b/jni/utils/img.c index 11fafea21..ea5fb5f31 100644 --- a/jni/utils/img.c +++ b/jni/utils/img.c @@ -163,6 +163,7 @@ void umount_image(const char *target, const char *device) { int merge_img(const char *source, const char *target) { if (access(source, F_OK) == -1) return 0; + LOGI("* Merging %s -> %s\n", source, target); if (access(target, F_OK) == -1) { xrename(source, target); return 0;