From 95b0b63a98238149f6f777efa817deef791df3cb Mon Sep 17 00:00:00 2001 From: Nick Chan Date: Mon, 30 Jan 2023 21:41:15 +0800 Subject: [PATCH] fix races --- include/common.h | 13 +++++-- src/Makefile | 2 +- src/dfuhelper.c | 27 +++++++------- src/lock_vars.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 12 +++++-- src/pongo_helper.c | 9 +++-- src/pongo_usb.c | 4 +-- 7 files changed, 129 insertions(+), 27 deletions(-) create mode 100644 src/lock_vars.c diff --git a/include/common.h b/include/common.h index d691249..272d89b 100644 --- a/include/common.h +++ b/include/common.h @@ -96,7 +96,7 @@ typedef int usb_ret_t; typedef libusb_device_handle *usb_device_handle_t; extern unsigned int verbose; -extern int spin, demote; +extern int demote; extern char* pongo_path; @@ -115,7 +115,9 @@ extern override_file_t override_ramdisk, override_kpf, override_overlay; extern uint32_t checkrain_flags, palerain_flags, kpf_flags; extern pthread_mutex_t log_mutex; -extern int enable_rootful, do_pongo_sleep, demote, found_pongo; +extern pthread_mutex_t spin_mutex, found_pongo_mutex, ecid_dfu_wait_mutex; + +extern int enable_rootful, do_pongo_sleep, demote; extern int pongo_thr_running, dfuhelper_thr_running; extern bool ohio, start_from_pongo; extern char xargs_cmd[0x270]; @@ -158,4 +160,11 @@ int issue_pongo_command(); int upload_pongo_file(); int tui(); int optparse(int argc, char* argv[]); + +bool get_spin(); +bool set_spin(bool val); +bool get_found_pongo(); +bool set_found_pongo(bool val); +uint64_t get_ecid_wait_for_dfu(); +uint64_t set_ecid_wait_for_dfu(uint64_t ecid); #endif \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index 230a08a..8ed1738 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ all: palera1n OBJECTS = main.o dfuhelper.o devhelper.o lockdown_helper.o exec_checkra1n.o OBJECTS += pongo_usb.o optparse.o override_file.o pongo_helper.o log.o OBJECTS += xxd-checkra1n.o xxd-checkra1n-kpf-pongo.o xxd-ramdisk.dmg.o -OBJECTS += xxd-binpack.dmg.o +OBJECTS += xxd-binpack.dmg.o lock_vars.o ifeq ($(DEV_BUILD),1) OBJECTS += tui_screen_enter_recovery.o tui_screen_enter_dfu.o tui_main.o OBJECTS += tui_screen_jailbreak.o tui_screen_main.o tui_screen_options.o diff --git a/src/dfuhelper.c b/src/dfuhelper.c index 5a64845..3530bee 100644 --- a/src/dfuhelper.c +++ b/src/dfuhelper.c @@ -32,9 +32,6 @@ #define NOHOME (cpid == 0x8015 || (cpid == 0x8010 && (bdid == 0x08 || bdid == 0x0a || bdid == 0x0c || bdid == 0x0e))) -int spin = 1; -uint64_t ecid_wait_for_dfu = 0; - void step(int time, int time2, char *text, bool (*cond)(uint64_t), uint64_t cond_arg) { for (int i = time2; i < time; i++) { printf(CYN "\r\e[K%s (%d)" CRESET, text, time - i + time2); @@ -82,7 +79,7 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) { } static bool conditional(uint64_t ecid) { - return ecid_wait_for_dfu != ecid; + return get_ecid_wait_for_dfu() != ecid; } void* connected_recovery_mode(struct irecv_device_info* info) { @@ -108,12 +105,12 @@ void* connected_recovery_mode(struct irecv_device_info* info) { step(4, 2, "Hold Volume Down + Side button", NULL, 0); else step(4, 2, "Hold Home + Power Button", NULL, 0); - ecid_wait_for_dfu = info->ecid; + set_ecid_wait_for_dfu(info->ecid); ret = exitrecv_cmd(info->ecid); info = NULL; if (ret) { LOG(LOG_ERROR, "Cannot exit recovery mode"); - ecid_wait_for_dfu = 0; + set_ecid_wait_for_dfu(0); return NULL; } printf("\r\e[K"); @@ -126,25 +123,26 @@ void* connected_recovery_mode(struct irecv_device_info* info) { step(10, 0, "Hold Volume Down button", conditional, ecid); else step(10, 0, "Hold Home button", conditional, ecid); - ecid_wait_for_dfu = 0; - if (ecid_wait_for_dfu != ecid) { + if (get_ecid_wait_for_dfu() != ecid) { } else { LOG(LOG_WARNING, "Whoops, device did not enter DFU mode"); LOG(LOG_INFO, "Waiting for device to reconnect..."); + set_ecid_wait_for_dfu(0); return NULL; } + set_ecid_wait_for_dfu(0); pthread_exit(NULL); return NULL; } void* connected_dfu_mode(struct irecv_device_info* info) { - if (ecid_wait_for_dfu == info->ecid) { - ecid_wait_for_dfu = 0; + if (get_ecid_wait_for_dfu() == info->ecid) { + set_ecid_wait_for_dfu(0); puts(""); LOG(LOG_INFO, "Device entered DFU mode successfully"); } unsubscribe_cmd(); - spin = 0; + set_spin(0); pthread_exit(NULL); return NULL; } @@ -176,16 +174,15 @@ void irecv_device_event_cb(const irecv_device_event_t *event, void* userdata) { } break; case IRECV_DEVICE_REMOVE: - if (event->device_info->ecid == ecid_wait_for_dfu) { - LOG(LOG_VERBOSE, "Recovery mode device %ld disconnected", event->device_info->ecid); - } + LOG(LOG_VERBOSE, "Recovery mode device disconnected"); break; } } void *dfuhelper(void* ptr) { subscribe_cmd(device_event_cb, irecv_device_event_cb); - while (spin) { + set_spin(1); + while (get_spin()) { sleep(1); }; return 0; diff --git a/src/lock_vars.c b/src/lock_vars.c new file mode 100644 index 0000000..a64facf --- /dev/null +++ b/src/lock_vars.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +pthread_mutex_t spin_mutex, found_pongo_mutex, ecid_dfu_wait_mutex; + +bool spin, found_pongo = 0; +uint64_t ecid_wait_for_dfu = 0; + +bool get_spin() { + LOG(LOG_VERBOSE5, "locking spin mutex for get"); + pthread_mutex_lock(&spin_mutex); + bool ret = spin; + LOG(LOG_VERBOSE5, "UN-locking spin mutex, spin value is %d", spin); + pthread_mutex_unlock(&spin_mutex); + return ret; +} + +bool set_spin(bool val) { + LOG(LOG_VERBOSE5, "locking spin mutex for set spin = %d", val); + pthread_mutex_lock(&spin_mutex); + spin = val; + LOG(LOG_VERBOSE5, "UN-locking spin mutex after setting spin\n"); + pthread_mutex_unlock(&spin_mutex); + return val; +} + +bool get_found_pongo() { + LOG(LOG_VERBOSE5, "locking found pongo mutex for get"); + pthread_mutex_lock(&found_pongo_mutex); + bool ret = found_pongo; + LOG(LOG_VERBOSE5, "UN-locking pongo mutex, found_pongo value is %d", found_pongo); + pthread_mutex_unlock(&found_pongo_mutex); + return ret; +} + +bool set_found_pongo(bool val) { + LOG(LOG_VERBOSE5, "locking found pongo mutex for set found_pongo = %d", val); + pthread_mutex_lock(&found_pongo_mutex); + found_pongo = val; + LOG(LOG_VERBOSE5, "UN-locking pongo mutex after setting found_pongo"); + pthread_mutex_unlock(&found_pongo_mutex); + return val; +} + +uint64_t get_ecid_wait_for_dfu() { + LOG(LOG_VERBOSE5, "locking ecid wait for dfu mutex for get"); + pthread_mutex_lock(&ecid_dfu_wait_mutex); + uint64_t ret = ecid_wait_for_dfu; + LOG(LOG_VERBOSE5, "UN-locking ecid wait for dfu mutex, ecid_wait_for_dfu value is %llu", ret); + pthread_mutex_unlock(&ecid_dfu_wait_mutex); + return ret; +} + +uint64_t set_ecid_wait_for_dfu(uint64_t ecid) { + LOG(LOG_VERBOSE5, "locking ecid wait for dfu value for set ecid_wait_for_dfu = %llu", ecid); + pthread_mutex_lock(&ecid_dfu_wait_mutex); + ecid_wait_for_dfu = ecid; + LOG(LOG_VERBOSE5, "UN-locking ecid wait for dfu mutex afrer setting ecid_wait_for_dfu"); + pthread_mutex_unlock(&ecid_dfu_wait_mutex); + return ecid; +} diff --git a/src/main.c b/src/main.c index 39075c2..33728e3 100644 --- a/src/main.c +++ b/src/main.c @@ -88,6 +88,9 @@ bool use_tui = false; int palera1n(int argc, char *argv[]) { int ret = 0; pthread_mutex_init(&log_mutex, NULL); + pthread_mutex_init(&spin_mutex, NULL); + pthread_mutex_init(&found_pongo_mutex, NULL); + pthread_mutex_init(&ecid_dfu_wait_mutex, NULL); if ((ret = build_checks())) return ret; if ((ret = optparse(argc, argv))) goto cleanup; if (palerain_version) goto normal_exit; @@ -111,13 +114,13 @@ int palera1n(int argc, char *argv[]) { if (pongo_exit || demote) goto normal_exit; pongo: - spin = true; + set_spin(1); if (do_pongo_sleep) sleep(2); else LOG(LOG_INFO, "Waiting for PongoOS devices..."); wait_for_pongo(); - while (spin) + while (get_spin()) { sleep(1); } @@ -156,9 +159,14 @@ cleanup: munmap(override_overlay.ptr, (size_t)override_overlay.len); close(override_overlay.fd); } + pthread_mutex_destroy(&log_mutex); + pthread_mutex_destroy(&spin_mutex); + pthread_mutex_destroy(&found_pongo_mutex); + pthread_mutex_destroy(&ecid_dfu_wait_mutex); return ret; } + int main (int argc, char* argv[]) { return palera1n(argc, argv); } diff --git a/src/pongo_helper.c b/src/pongo_helper.c index e6138bf..4403082 100644 --- a/src/pongo_helper.c +++ b/src/pongo_helper.c @@ -12,13 +12,12 @@ #include -int found_pongo = 0; void* pongo_helper(void* ptr) { pongo_thr_running = 1; pthread_cleanup_push(thr_cleanup, &pongo_thr_running); wait_for_pongo(); - while (spin) { + while (get_spin()) { sleep(1); } pthread_cleanup_pop(1); @@ -26,9 +25,9 @@ void* pongo_helper(void* ptr) { } void *pongo_usb_callback(void *arg) { - if (found_pongo) + if (get_found_pongo()) return NULL; - found_pongo = 1; + set_found_pongo(1); strncat(xargs_cmd, " rootdev=md0", 0x270 - strlen(xargs_cmd) - 1); if (checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful)) { strncat(xargs_cmd, " wdt=-1", 0x270 - strlen(xargs_cmd) - 1); @@ -55,6 +54,6 @@ void *pongo_usb_callback(void *arg) { issue_pongo_command(handle, "kpf"); issue_pongo_command(handle, "bootux"); LOG(LOG_INFO, "Booting Kernel..."); - spin = false; + set_spin(0); return NULL; } \ No newline at end of file diff --git a/src/pongo_usb.c b/src/pongo_usb.c index c38db4f..47977c3 100644 --- a/src/pongo_usb.c +++ b/src/pongo_usb.c @@ -267,7 +267,7 @@ int wait_for_pongo(void) } libusb_free_device_list(list, 0); - while(spin) + while(get_spin()) { r = libusb_handle_events(NULL); if(r != LIBUSB_SUCCESS) @@ -290,7 +290,7 @@ static void io_start(stuff_t *stuff) ERR("pthread_create: %s", strerror(r)); exit(-1); // TODO: ok with libusb? } - pongo_usb_callback(&stuff->handle); + pthread_join(stuff->th, NULL); } static void io_stop(stuff_t *stuff)