diff --git a/orbisrpc/updater.h b/orbisrpc/updater.h index 9385f54..a6e9eec 100644 --- a/orbisrpc/updater.h +++ b/orbisrpc/updater.h @@ -7,6 +7,8 @@ int updater_cmp(const char *a, const char *b); /* Validate a downloaded payload: ELF magic, 64-bit, x86-64, sane size. */ int updater_elf_ok(const unsigned char *buf, size_t n); +/* Accepts raw ELF (payload .bin) or signed SELF (plugin .prx). */ +int updater_image_ok(const unsigned char *buf, size_t n); /* Check latest GitHub release; download + atomically stage newer * artifacts the daemon actually runs from. Returns 1 updated, * 0 already current, -1 failed/checked-off. Never fatal. */ diff --git a/orbisrpc/updater_util.c b/orbisrpc/updater_util.c index 585bc03..c9ea37e 100644 --- a/orbisrpc/updater_util.c +++ b/orbisrpc/updater_util.c @@ -28,3 +28,16 @@ int updater_elf_ok(const unsigned char *buf, size_t n){ if(n > 8u*1024u*1024u) return 0; return 1; } + +/* SELF (signed container) check: plugin PRXs ship as SELF, not raw ELF. */ +static int updater_self_ok(const unsigned char *buf, size_t n){ + if(!buf || n < 64) return 0; + if(buf[0] != 0x4f || buf[1] != 0x15 || buf[2] != 0x3d || buf[3] != 0x1d) + return 0; + if(n > 8u*1024u*1024u) return 0; + return 1; +} + +int updater_image_ok(const unsigned char *buf, size_t n){ + return updater_elf_ok(buf, n) || updater_self_ok(buf, n); +} diff --git a/tests/Makefile b/tests/Makefile index 91483fb..ed2abcb 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -8,7 +8,7 @@ MBEDTLS_DIR := ../third_party/mbedtls/library # Same exclusion set as scripts/build.sh (POSIX-only modules). MBEDTLS_SRCS := $(filter-out $(MBEDTLS_DIR)/net_sockets.c $(MBEDTLS_DIR)/timing.c $(MBEDTLS_DIR)/entropy_poll.c,$(wildcard $(MBEDTLS_DIR)/*.c)) -ORBIS_SRCS := ../orbisrpc/jsonlite.c ../orbisrpc/b64.c ../orbisrpc/sfo.c ../orbisrpc/tmdb_crypto.c ../orbisrpc/updater_util.c ../orbisrpc/art.c ../orbisrpc/log.c ../orbisrpc/health.c ../orbisrpc/manifest.c +ORBIS_SRCS := ../orbisrpc/jsonlite.c ../orbisrpc/b64.c ../orbisrpc/sfo.c ../orbisrpc/tmdb_crypto.c ../orbisrpc/updater_util.c ../orbisrpc/art.c ../orbisrpc/log.c ../orbisrpc/health.c ../orbisrpc/manifest.c ../orbisrpc/compat.c ORBIS_OBJS := $(patsubst ../orbisrpc/%.c,$(OBJDIR)/orbis_%.o,$(ORBIS_SRCS)) MBEDTLS_OBJS := $(patsubst $(MBEDTLS_DIR)/%.c,$(OBJDIR)/mbed_%.o,$(MBEDTLS_SRCS)) diff --git a/tests/test_utils.c b/tests/test_utils.c index 3c02ac5..d8d2825 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -1,4 +1,3 @@ -#define _XOPEN_SOURCE 700 #include "../orbisrpc/jsonlite.h" #include "../orbisrpc/b64.h" #include "../orbisrpc/sfo.h" @@ -10,8 +9,19 @@ #include "../orbisrpc/manifest.h" #include #include +#include #include #include +#include +#include + +/* Portable temp dir (mkdtemp needs feature macros this toolchain lacks). */ +static int make_tmpdir(char *out, size_t cap){ + static int seq = 0; + snprintf(out, cap, "/tmp/orx_test_%d_%d", (int)getpid(), seq++); + if(mkdir(out, 0700) != 0) return -1; + return 0; +} static void test_json(void) { const char input[] = "{\"name\":\"A\\u00e9\",\"items\":[true,2,null]}"; @@ -123,14 +133,14 @@ static void test_tmdb(void) { int i; /* SHA1("abc") = a9993e364706816aba3e25717850c26c9cd0d4d */ tmdb_sha1((const unsigned char *)"abc", 3, dig); - for(i=0;i<20;i++) sprintf(hex+2*i, "%02x", dig[i]); + for(i=0;i<20;i++) snprintf(hex+2*i, 3, "%02x", dig[i]); assert(strcmp(hex, "a9993e364706816aba3e25717850c26c9cd0d89d") == 0); /* HMAC-SHA1 RFC 2202 case 1 */ { unsigned char key[20]; memset(key, 0x0b, 20); tmdb_hmac_sha1(key, 20, (const unsigned char *)"Hi There", 8, dig); - for(i=0;i<20;i++) sprintf(hex+2*i, "%02x", dig[i]); + for(i=0;i<20;i++) snprintf(hex+2*i, 3, "%02x", dig[i]); assert(strcmp(hex, "b617318655057264e28bc0b6fb378c8ef146be00") == 0); } /* URL path must match the hash Sony's live service accepts */ @@ -205,8 +215,8 @@ static void test_art_parse(void) { static void test_health_safe_mode(void) { /* Unclean-boot marker semantics: normal reboots never count. */ - char dir[] = "/tmp/orx_health_XXXXXX"; - assert(mkdtemp(dir) != NULL); + char dir[64]; + assert(make_tmpdir(dir, sizeof dir) == 0); health_set_base(dir); health_mark_clean(); /* clean boot x3: counter stays 0, never safe mode */ @@ -227,8 +237,8 @@ static void test_health_safe_mode(void) { static void test_health_stage_activate(void) { /* Atomic staging: bad .new never touches live; rollback restores. */ - char dir[] = "/tmp/orx_stage_XXXXXX"; - assert(mkdtemp(dir) != NULL); + char dir[64]; + assert(make_tmpdir(dir, sizeof dir) == 0); health_set_base(dir); char live[256], tmp[256], bak[256]; snprintf(live, sizeof live, "%s/live.bin", dir); diff --git a/tests/test_utils_asan b/tests/test_utils_asan new file mode 100755 index 0000000..a38ce86 Binary files /dev/null and b/tests/test_utils_asan differ