mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-03 09:31:55 +00:00
Improve builtin selinux implementation
This commit is contained in:
@@ -25,6 +25,13 @@ static int stub(const char *, char **ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stub(int, const char *) { return 0; }
|
||||
|
||||
static int stub(int, char **ctx) {
|
||||
*ctx = strdup("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Builtin implementation
|
||||
|
||||
static void __freecon(char *s) {
|
||||
@@ -44,25 +51,61 @@ static int __setcon(const char *ctx) {
|
||||
static int __getfilecon(const char *path, char **ctx) {
|
||||
char buf[1024];
|
||||
int rc = syscall(__NR_getxattr, path, XATTR_NAME_SELINUX, buf, sizeof(buf) - 1);
|
||||
if (rc > 0)
|
||||
*ctx = strdup(buf);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
*ctx = strdup(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __lgetfilecon(const char *path, char **ctx) {
|
||||
char buf[1024];
|
||||
int rc = syscall(__NR_lgetxattr, path, XATTR_NAME_SELINUX, buf, sizeof(buf) - 1);
|
||||
if (rc > 0)
|
||||
*ctx = strdup(buf);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
*ctx = strdup(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __fgetfilecon(int fd, char **ctx) {
|
||||
char buf[1024];
|
||||
int rc = syscall(__NR_fgetxattr, fd, XATTR_NAME_SELINUX, buf, sizeof(buf) - 1);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
*ctx = strdup(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __setfilecon(const char *path, const char *ctx) {
|
||||
return syscall(__NR_setxattr, path, XATTR_NAME_SELINUX, ctx, strlen(ctx) + 1, 0);
|
||||
int rc = syscall(__NR_setxattr, path, XATTR_NAME_SELINUX, ctx, strlen(ctx) + 1, 0);
|
||||
if (rc) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __lsetfilecon(const char *path, const char *ctx) {
|
||||
return syscall(__NR_lsetxattr, path, XATTR_NAME_SELINUX, ctx, strlen(ctx) + 1, 0);
|
||||
int rc = syscall(__NR_lsetxattr, path, XATTR_NAME_SELINUX, ctx, strlen(ctx) + 1, 0);
|
||||
if (rc) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __fsetfilecon(int fd, const char *ctx) {
|
||||
int rc = syscall(__NR_fsetxattr, fd, XATTR_NAME_SELINUX, ctx, strlen(ctx) + 1, 0);
|
||||
if (rc) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Function pointers
|
||||
@@ -71,15 +114,32 @@ void (*freecon)(char *) = __freecon;
|
||||
int (*setcon)(const char *) = stub;
|
||||
int (*getfilecon)(const char *, char **) = stub;
|
||||
int (*lgetfilecon)(const char *, char **) = stub;
|
||||
int (*fgetfilecon)(int, char **) = stub;
|
||||
int (*setfilecon)(const char *, const char *) = stub;
|
||||
int (*lsetfilecon)(const char *, const char *) = stub;
|
||||
int (*fsetfilecon)(int, const char *) = stub;
|
||||
|
||||
void getfilecon_at(int dirfd, const char *name, char **con) {
|
||||
char path[4096];
|
||||
fd_pathat(dirfd, name, path, sizeof(path));
|
||||
if (lgetfilecon(path, con))
|
||||
*con = strdup("");
|
||||
}
|
||||
|
||||
void setfilecon_at(int dirfd, const char *name, const char *con) {
|
||||
char path[4096];
|
||||
fd_pathat(dirfd, name, path, sizeof(path));
|
||||
lsetfilecon(path, con);
|
||||
}
|
||||
|
||||
void selinux_builtin_impl() {
|
||||
setcon = __setcon;
|
||||
getfilecon = __getfilecon;
|
||||
lgetfilecon = __lgetfilecon;
|
||||
fgetfilecon = __fgetfilecon;
|
||||
setfilecon = __setfilecon;
|
||||
lsetfilecon = __lsetfilecon;
|
||||
fsetfilecon = __fsetfilecon;
|
||||
}
|
||||
|
||||
void dload_selinux() {
|
||||
@@ -95,33 +155,32 @@ void dload_selinux() {
|
||||
static void restore_syscon(int dirfd) {
|
||||
struct dirent *entry;
|
||||
DIR *dir;
|
||||
char *con;
|
||||
|
||||
char path[PATH_MAX], *con;
|
||||
|
||||
fd_getpath(dirfd, path, sizeof(path));
|
||||
size_t len = strlen(path);
|
||||
getfilecon(path, &con);
|
||||
fgetfilecon(dirfd, &con);
|
||||
if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
|
||||
lsetfilecon(path, SYSTEM_CON);
|
||||
fsetfilecon(dirfd, SYSTEM_CON);
|
||||
freecon(con);
|
||||
|
||||
dir = xfdopendir(dirfd);
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
int fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
if (entry->d_type == DT_DIR) {
|
||||
int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
restore_syscon(fd);
|
||||
close(fd);
|
||||
} else {
|
||||
path[len] = '/';
|
||||
strcpy(path + len + 1, entry->d_name);
|
||||
lgetfilecon(path, &con);
|
||||
if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
|
||||
lsetfilecon(path, SYSTEM_CON);
|
||||
} else if (entry->d_type == DT_REG) {
|
||||
fgetfilecon(fd, &con);
|
||||
if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0)
|
||||
fsetfilecon(fd, SYSTEM_CON);
|
||||
freecon(con);
|
||||
} else if (entry->d_type == DT_LNK) {
|
||||
getfilecon_at(dirfd, entry->d_name, &con);
|
||||
if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0)
|
||||
setfilecon_at(dirfd, entry->d_name, con);
|
||||
freecon(con);
|
||||
path[len] = '\0';
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,28 +188,21 @@ static void restore_magiskcon(int dirfd) {
|
||||
struct dirent *entry;
|
||||
DIR *dir;
|
||||
|
||||
char path[PATH_MAX];
|
||||
|
||||
fd_getpath(dirfd, path, sizeof(path));
|
||||
size_t len = strlen(path);
|
||||
lsetfilecon(path, MAGISK_CON);
|
||||
lchown(path, 0, 0);
|
||||
fsetfilecon(dirfd, MAGISK_CON);
|
||||
fchown(dirfd, 0, 0);
|
||||
|
||||
dir = xfdopendir(dirfd);
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
if (entry->d_type == DT_DIR) {
|
||||
int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
restore_magiskcon(fd);
|
||||
close(fd);
|
||||
} else {
|
||||
path[len] = '/';
|
||||
strcpy(path + len + 1, entry->d_name);
|
||||
lsetfilecon(path, MAGISK_CON);
|
||||
lchown(path, 0, 0);
|
||||
path[len] = '\0';
|
||||
} else if (entry->d_type) {
|
||||
fsetfilecon(fd, MAGISK_CON);
|
||||
fchown(fd, 0, 0);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user