mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-03-04 14:05:11 +00:00
init: reset overlay.d files context after sepolicy loaded
This commit is contained in:
parent
b6511a510d
commit
2b7be8b949
@ -1,6 +1,8 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
#include <sys/xattr.h>
|
||||||
|
|
||||||
#include <sepolicy.hpp>
|
#include <sepolicy.hpp>
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
@ -14,6 +16,13 @@ using namespace std;
|
|||||||
static vector<string> rc_list;
|
static vector<string> rc_list;
|
||||||
static string magic_mount_list;
|
static string magic_mount_list;
|
||||||
|
|
||||||
|
struct FileContext {
|
||||||
|
std::string path;
|
||||||
|
std::string con;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<FileContext> mount_contexts;
|
||||||
|
|
||||||
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
||||||
#define INIT_RC "init.rc"
|
#define INIT_RC "init.rc"
|
||||||
|
|
||||||
@ -29,6 +38,10 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
|
|||||||
magic_mount(src, dest);
|
magic_mount(src, dest);
|
||||||
} else {
|
} else {
|
||||||
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
|
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
|
||||||
|
struct stat st;
|
||||||
|
xstat(dest.data(), &st);
|
||||||
|
chmod(src.data(), st.st_mode & 0777);
|
||||||
|
chown(src.data(), st.st_uid, st.st_gid);
|
||||||
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
|
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
|
||||||
magic_mount_list += dest;
|
magic_mount_list += dest;
|
||||||
magic_mount_list += '\n';
|
magic_mount_list += '\n';
|
||||||
@ -37,6 +50,46 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setfilecon(const char* path, const char* con) {
|
||||||
|
int ret = syscall(__NR_setxattr, path, XATTR_NAME_SELINUX, con, strlen(con) + 1, 0);
|
||||||
|
if (ret == -1) PLOGE("setfilecon %s %s", path, con);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getfilecon(const char* path) {
|
||||||
|
char buf[1024];
|
||||||
|
ssize_t sz = syscall(__NR_getxattr, path, XATTR_NAME_SELINUX, buf, sizeof(buf));
|
||||||
|
if (sz == -1) {
|
||||||
|
PLOGE("getfilecon %s", path);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void collect_overlay_contexts(const string &sdir, const string &ddir = "") {
|
||||||
|
auto dir = xopen_dir(sdir.data());
|
||||||
|
if (!dir) return;
|
||||||
|
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||||
|
string src = sdir + "/" + entry->d_name;
|
||||||
|
string dest = ddir + "/" + entry->d_name;
|
||||||
|
if (access(dest.data(), F_OK) == 0) {
|
||||||
|
if (entry->d_type == DT_DIR) {
|
||||||
|
// Recursive
|
||||||
|
collect_overlay_contexts(src, dest);
|
||||||
|
} else {
|
||||||
|
mount_contexts.emplace_back(dest, getfilecon(dest.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_overlay_contexts() {
|
||||||
|
for (auto &attr: mount_contexts) {
|
||||||
|
LOGD("set %s -> %s", attr.path.c_str(), attr.con.c_str());
|
||||||
|
setfilecon(attr.path.c_str(), attr.con.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) {
|
static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) {
|
||||||
auto src_dir = xopen_dir(src_path);
|
auto src_dir = xopen_dir(src_path);
|
||||||
if (!src_dir) return;
|
if (!src_dir) return;
|
||||||
@ -327,6 +380,8 @@ void MagiskInit::patch_ro_root() {
|
|||||||
// Extract overlay archives
|
// Extract overlay archives
|
||||||
extract_files(false);
|
extract_files(false);
|
||||||
|
|
||||||
|
collect_overlay_contexts(ROOTOVL);
|
||||||
|
|
||||||
// Oculus Go will use a special sepolicy if unlocked
|
// Oculus Go will use a special sepolicy if unlocked
|
||||||
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
||||||
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
||||||
|
@ -131,6 +131,10 @@ bool MagiskInit::hijack_sepolicy() {
|
|||||||
// Load patched policy into kernel
|
// Load patched policy into kernel
|
||||||
sepol->to_file(SELINUX_LOAD);
|
sepol->to_file(SELINUX_LOAD);
|
||||||
|
|
||||||
|
// restore mounted files' context after sepolicy loaded
|
||||||
|
void reset_overlay_contexts();
|
||||||
|
reset_overlay_contexts();
|
||||||
|
|
||||||
// Write to the enforce node ONLY after sepolicy is loaded. We need to make sure
|
// Write to the enforce node ONLY after sepolicy is loaded. We need to make sure
|
||||||
// the actual init process is blocked until sepolicy is loaded, or else
|
// the actual init process is blocked until sepolicy is loaded, or else
|
||||||
// restorecon will fail and re-exec won't change context, causing boot failure.
|
// restorecon will fail and re-exec won't change context, causing boot failure.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user