mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-03-04 07:35:10 +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 <libgen.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <syscall.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include <sepolicy.hpp>
|
||||
#include <consts.hpp>
|
||||
@ -14,6 +16,13 @@ using namespace std;
|
||||
static vector<string> rc_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 INIT_RC "init.rc"
|
||||
|
||||
@ -29,6 +38,10 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
|
||||
magic_mount(src, dest);
|
||||
} else {
|
||||
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);
|
||||
magic_mount_list += dest;
|
||||
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) {
|
||||
auto src_dir = xopen_dir(src_path);
|
||||
if (!src_dir) return;
|
||||
@ -327,6 +380,8 @@ void MagiskInit::patch_ro_root() {
|
||||
// Extract overlay archives
|
||||
extract_files(false);
|
||||
|
||||
collect_overlay_contexts(ROOTOVL);
|
||||
|
||||
// Oculus Go will use a special sepolicy if unlocked
|
||||
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
||||
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
||||
|
@ -131,6 +131,10 @@ bool MagiskInit::hijack_sepolicy() {
|
||||
// Load patched policy into kernel
|
||||
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
|
||||
// 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user