From fd89126ef14bd5ee581668e460cdd006956ccec4 Mon Sep 17 00:00:00 2001 From: SirHumza <204067870+SirHumza@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:48:55 +0200 Subject: [PATCH] evict.elf: SIGTERM-then-SIGKILL deploy tool for locked daemon --- scripts/build_evict.sh | 13 ++++++ tools/evict.c | 95 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100755 scripts/build_evict.sh create mode 100644 tools/evict.c diff --git a/scripts/build_evict.sh b/scripts/build_evict.sh new file mode 100755 index 0000000..4896926 --- /dev/null +++ b/scripts/build_evict.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# build_evict.sh - evict.elf via ps4-payload-sdk (daemon-world linkage only). +# Usage: PS4_PAYLOAD_SDK=/path ./scripts/build_evict.sh +set -e +SDK="${PS4_PAYLOAD_SDK:-$HOME/ps4-payload-sdk/ps4-payload-sdk}" +CC="$SDK/bin/orbis-clang" +export PS4_PAYLOAD_SDK="$SDK" +export PATH="$HOME/llvmshim:$PATH" +OUT="build-sdk" +mkdir -p "$OUT" +echo "=== evict (SDK) ===" +"$CC" -O2 -Wall -DORBISRPC_SDK_PAYLOAD -o "$OUT/evict.elf" tools/evict.c || { echo "FAIL: evict"; exit 1; } +ls -la "$OUT/evict.elf" diff --git a/tools/evict.c b/tools/evict.c new file mode 100644 index 0000000..fb9791a --- /dev/null +++ b/tools/evict.c @@ -0,0 +1,95 @@ +/* evict.c - stop a running orbisRPC daemon so a fresh payload can take over. + * Reads /data/orbisRPC/daemon.lock, verifies the holder is a live "Payload" + * process via the same sysctl walk as lock.c, then SIGTERM (clean stop: + * banks session, clears presence, releases lock) with a SIGKILL fallback. + * Refuses to signal anything that is not a live Payload peer. + * Build: ./scripts/build_evict.sh -> build-sdk/evict.elf + * Run: send via elfldr:9021, then send the fresh orbisrpc_sdk.elf. + * Result: /data/orbisRPC/evict.txt + klog printf. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCK_PATH "/data/orbisRPC/daemon.lock" +#define RESULT_PATH "/data/orbisRPC/evict.txt" + +static void report(const char *msg){ + printf("evict: %s\n", msg); + int fd = open(RESULT_PATH, O_CREAT|O_TRUNC|O_WRONLY, 0644); + if(fd >= 0){ (void)write(fd, msg, strlen(msg)); (void)write(fd, "\n", 1); close(fd); } +} + +/* 1 = pid is a live "Payload" process, 0 otherwise. Mirrors lock.c. */ +static int payload_live(int pid){ + if(pid <= 0 || pid == (int)getpid()) return 0; + int mib[4] = { 1, 14, 8, 0 }; + size_t sz = 0; + if(sysctl(mib, 4, NULL, &sz, NULL, 0) != 0) return 0; + static unsigned char buf[256*1024]; + if(sz > sizeof buf) return 0; /* unreadable table: fail closed */ + if(sysctl(mib, 4, buf, &sz, NULL, 0) != 0) return 0; + size_t off = 0; + while(off + 4 <= sz){ + int recsz = *(int *)(buf + off); + if(recsz <= 0 || off + (size_t)recsz > sz) break; + if(recsz >= 479 && *(int *)(buf + off + 72) == pid) + return !memcmp(buf + off + 447, "Payload", 8); + off += (size_t)recsz; + } + return 0; +} + +int main(void){ + char msg[128]; + int fd = open(LOCK_PATH, O_RDONLY); + if(fd < 0){ report("NO_LOCK nothing running"); return 0; } + char b[32]; ssize_t n = read(fd, b, sizeof b - 1); close(fd); + if(n <= 0){ report("LOCK_UNREADABLE"); return 1; } + b[n] = 0; + int pid = 0; + if(sscanf(b, "%d", &pid) != 1 || pid <= 0){ + remove(LOCK_PATH); + report("LOCK_GARBAGE removed"); + return 0; + } + if(!payload_live(pid)){ + remove(LOCK_PATH); + snprintf(msg, sizeof msg, "STALE holder=%d not a live Payload; lock removed", pid); + report(msg); + return 0; + } + if(kill(pid, SIGTERM) != 0 && errno == ESRCH){ + remove(LOCK_PATH); + report("HOLDER_GONE lock removed"); + return 0; + } + /* Grace period: clean stop banks session + releases lock. */ + for(int i = 0; i < 24; i++){ + sleep(1); + if(!payload_live(pid)){ + remove(LOCK_PATH); + snprintf(msg, sizeof msg, "EVICTED holder=%d clean stop", pid); + report(msg); + return 0; + } + } + /* Wedged (e.g. stuck in blocking connect): SIGKILL fallback. */ + (void)kill(pid, SIGKILL); + for(int i = 0; i < 10; i++){ + sleep(1); + if(!payload_live(pid)){ + remove(LOCK_PATH); + snprintf(msg, sizeof msg, "EVICTED holder=%d SIGKILL fallback", pid); + report(msg); + return 0; + } + } + snprintf(msg, sizeof msg, "STUCK holder=%d still alive; reboot console", pid); + report(msg); + return 2; +}