You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
fix: root related mounts leak in APatch in isolated services
This commit fixes the issue where mounts related to APatch and ReZygisk would be leaked in isolated services for APatch environments as the UID between the main process and isolated service is different, resulting it to not be found in "package_config" and default to not switch to clean mount namespace.
This commit is contained in:
@@ -62,6 +62,7 @@ void apatch_get_existence(struct root_impl_state *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct package_config {
|
struct package_config {
|
||||||
|
char *process;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
bool root_granted;
|
bool root_granted;
|
||||||
bool umount_needed;
|
bool umount_needed;
|
||||||
@@ -104,7 +105,7 @@ bool _apatch_get_package_config(struct packages_config *restrict config) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strtok(line, ",");
|
config->configs[config->size].process = strdup(strtok(line, ","));
|
||||||
|
|
||||||
char *exclude_str = strtok(NULL, ",");
|
char *exclude_str = strtok(NULL, ",");
|
||||||
if (exclude_str == NULL) continue;
|
if (exclude_str == NULL) continue;
|
||||||
@@ -128,6 +129,10 @@ bool _apatch_get_package_config(struct packages_config *restrict config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _apatch_free_package_config(struct packages_config *restrict config) {
|
void _apatch_free_package_config(struct packages_config *restrict config) {
|
||||||
|
for (size_t i = 0; i < config->size; i++) {
|
||||||
|
free(config->configs[i].process);
|
||||||
|
}
|
||||||
|
|
||||||
free(config->configs);
|
free(config->configs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +160,7 @@ bool apatch_uid_granted_root(uid_t uid) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool apatch_uid_should_umount(uid_t uid) {
|
bool apatch_uid_should_umount(uid_t uid, const char *const process) {
|
||||||
struct packages_config config;
|
struct packages_config config;
|
||||||
if (!_apatch_get_package_config(&config)) {
|
if (!_apatch_get_package_config(&config)) {
|
||||||
_apatch_free_package_config(&config);
|
_apatch_free_package_config(&config);
|
||||||
@@ -163,8 +168,22 @@ bool apatch_uid_should_umount(uid_t uid) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* INFO: Some can take advantage of the UID being different in an app's
|
||||||
|
isolated service, bypassing this check, so we must check against
|
||||||
|
process name in case it is an isolated service. This can happen in
|
||||||
|
all root implementations. */
|
||||||
|
size_t targeted_process_length = 0;
|
||||||
|
if (IS_ISOLATED_SERVICE(uid)) targeted_process_length = strlen(process);
|
||||||
|
|
||||||
for (size_t i = 0; i < config.size; i++) {
|
for (size_t i = 0; i < config.size; i++) {
|
||||||
if (config.configs[i].uid != uid) continue;
|
if (IS_ISOLATED_SERVICE(uid)) {
|
||||||
|
size_t config_process_length = strlen(config.configs[i].process);
|
||||||
|
size_t smallest_process_length = targeted_process_length < config_process_length ? targeted_process_length : config_process_length;
|
||||||
|
|
||||||
|
if (strncmp(config.configs[i].process, process, smallest_process_length) != 0) continue;
|
||||||
|
} else {
|
||||||
|
if (config.configs[i].uid != uid) continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* INFO: This allow us to copy the information to avoid use-after-free */
|
/* INFO: This allow us to copy the information to avoid use-after-free */
|
||||||
bool umount_needed = config.configs[i].umount_needed;
|
bool umount_needed = config.configs[i].umount_needed;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ void apatch_get_existence(struct root_impl_state *state);
|
|||||||
|
|
||||||
bool apatch_uid_granted_root(uid_t uid);
|
bool apatch_uid_granted_root(uid_t uid);
|
||||||
|
|
||||||
bool apatch_uid_should_umount(uid_t uid);
|
bool apatch_uid_should_umount(uid_t uid, const char *const process);
|
||||||
|
|
||||||
bool apatch_uid_is_manager(uid_t uid);
|
bool apatch_uid_is_manager(uid_t uid);
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ bool uid_should_umount(uid_t uid, const char *const process) {
|
|||||||
return ksu_uid_should_umount(uid);
|
return ksu_uid_should_umount(uid);
|
||||||
}
|
}
|
||||||
case APatch: {
|
case APatch: {
|
||||||
return apatch_uid_should_umount(uid);
|
return apatch_uid_should_umount(uid, process);
|
||||||
}
|
}
|
||||||
case Magisk: {
|
case Magisk: {
|
||||||
return magisk_uid_should_umount(process);
|
return magisk_uid_should_umount(process);
|
||||||
|
|||||||
@@ -65,6 +65,9 @@
|
|||||||
return -1; \
|
return -1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define IS_ISOLATED_SERVICE(uid) \
|
||||||
|
((uid) >= 90000 && (uid) < 1000000)
|
||||||
|
|
||||||
#define write_func_def(type) \
|
#define write_func_def(type) \
|
||||||
ssize_t write_## type(int fd, type val)
|
ssize_t write_## type(int fd, type val)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user