Skip to content

Commit ff13ff3

Browse files
committed
fix: module list mismatch between ReZygiskd and libzygisk.so
This commit fixes a bug where if a module failed to load, or didn't have an entry, ReZygisk Zygote library would exclude it from the "zygisk_modules" list, making the index for future modules shift from place when compared to the list in ReZygiskd. This would make Zygiskd calls return the response from the wrong module, e.g. module 0 is the one that failed to load. If the new module 0 requested a companion, it would get the companion for the old module 0, causing issues. This commit addresses it by allowing ReZygisk Zygote library to ask ReZygiskd to remove its from its list.
1 parent c13b891 commit ff13ff3

5 files changed

Lines changed: 70 additions & 3 deletions

File tree

loader/src/common/daemon.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,22 @@ bool rezygiskd_update_mns(enum mount_namespace_state nms_state, char *buf, size_
355355

356356
return true;
357357
}
358+
359+
bool rezygiskd_remove_module(size_t index) {
360+
int fd = rezygiskd_connect(1);
361+
if (fd == -1) {
362+
PLOGE("connection to ReZygiskd");
363+
364+
return false;
365+
}
366+
367+
write_uint8_t(fd, (uint8_t)RemoveModule);
368+
write_size_t(fd, index);
369+
370+
uint8_t res = 0;
371+
read_uint8_t(fd, &res);
372+
373+
close(fd);
374+
375+
return res == 1;
376+
}

loader/src/include/daemon.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ enum rezygiskd_actions {
2222
GetModuleDir,
2323
ZygoteRestart,
2424
SystemServerStarted,
25-
UpdateMountNamespace
25+
UpdateMountNamespace,
26+
RemoveModule
2627
};
2728

2829
struct zygisk_modules {
@@ -79,4 +80,6 @@ void rezygiskd_system_server_started();
7980

8081
bool rezygiskd_update_mns(enum mount_namespace_state nms_state, char *buf, size_t buf_size);
8182

83+
bool rezygiskd_remove_module(size_t index);
84+
8285
#endif /* DAEMON_H */

loader/src/injector/hook.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,13 @@ static bool load_modules_only(void) {
881881
if (!csoloader_load(&zygisk_modules[zygisk_module_length].lib, lib_path)) {
882882
LOGE("Failed to load module [%s]", lib_path);
883883

884+
/* INFO: In case a module failed to load, update the list of available modules
885+
in ReZygiskd to avoid a mismatch between the loaded modules in ReZygisk
886+
Zygote library and the available modules in ReZygiskd. */
887+
/* TODO: Update the list of modules for ReZygisk monitor, so that it can update
888+
for WebUI. That is simply cosmetic, though. */
889+
rezygiskd_remove_module(i);
890+
884891
continue;
885892
}
886893

@@ -890,6 +897,8 @@ static bool load_modules_only(void) {
890897

891898
csoloader_unload(&zygisk_modules[zygisk_module_length].lib);
892899

900+
rezygiskd_remove_module(i);
901+
893902
continue;
894903
}
895904

@@ -951,7 +960,6 @@ static void rz_run_modules_post(struct zygisk_context *ctx) {
951960
static void rz_app_specialize_pre(struct zygisk_context *ctx) {
952961
FLAG_SET(ctx, APP_SPECIALIZE);
953962

954-
955963
/* INFO: Isolated services have different UIDs than the main apps. Because
956964
numerous root implementations base themselves in the UID of the
957965
app, we need to ensure that the UID sent to ReZygiskd to search

zygiskd/src/constants.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ enum DaemonSocketAction {
2727
GetModuleDir = 5,
2828
ZygoteRestart = 6,
2929
SystemServerStarted = 7,
30-
UpdateMountNamespace = 8
30+
UpdateMountNamespace = 8,
31+
RemoveModule = 9
3132
};
3233

3334
enum ProcessFlags: uint32_t {

zygiskd/src/zygiskd.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,42 @@ void zygiskd_start(char *restrict argv[]) {
627627
ret = write_uint32_t(client_fd, (uint32_t)ns_fd);
628628
ASSURE_SIZE_WRITE_BREAK("UpdateMountNamespace", "ns_fd", ret, sizeof(ns_fd));
629629

630+
break;
631+
}
632+
case RemoveModule: {
633+
size_t index = 0;
634+
ssize_t ret = read_size_t(client_fd, &index);
635+
ASSURE_SIZE_READ_BREAK("RemoveModule", "index", ret, sizeof(index));
636+
637+
if (index >= context.len) {
638+
LOGE("Invalid module index: %zu\n", index);
639+
640+
ret = write_uint8_t(client_fd, 0);
641+
ASSURE_SIZE_WRITE_BREAK("RemoveModule", "response", ret, sizeof(uint8_t));
642+
643+
close(client_fd);
644+
645+
break;
646+
}
647+
648+
struct Module *module = &context.modules[index];
649+
if (module->companion >= 0) {
650+
close(module->companion);
651+
module->companion = -1;
652+
}
653+
654+
free(module->name);
655+
module->name = NULL;
656+
657+
close(module->lib_fd);
658+
module->lib_fd = -1;
659+
660+
memmove(&context.modules[index], &context.modules[index + 1], (context.len - index - 1) * sizeof(struct Module));
661+
context.len--;
662+
663+
ret = write_uint8_t(client_fd, 1);
664+
ASSURE_SIZE_WRITE_BREAK("RemoveModule", "response", ret, sizeof(uint8_t));
665+
630666
break;
631667
}
632668
}

0 commit comments

Comments
 (0)