From b305eeac6258997b97dd99b9c2d8cf440f612420 Mon Sep 17 00:00:00 2001 From: SirHumza <204067870+SirHumza@users.noreply.github.com> Date: Thu, 24 Sep 2026 19:57:05 +0200 Subject: [PATCH] audit: rollback atomicity, NTP source+window, retire table scripts --- .../retired-tables}/build_art_table.py | 0 .../retired-tables}/gen_nametable.py | 0 {scripts => findings/retired-tables}/titles.txt | 0 orbisrpc/health.c | 3 ++- orbisrpc/timesync.c | 14 ++++++++++++-- 5 files changed, 14 insertions(+), 3 deletions(-) rename {scripts => findings/retired-tables}/build_art_table.py (100%) rename {scripts => findings/retired-tables}/gen_nametable.py (100%) rename {scripts => findings/retired-tables}/titles.txt (100%) diff --git a/scripts/build_art_table.py b/findings/retired-tables/build_art_table.py similarity index 100% rename from scripts/build_art_table.py rename to findings/retired-tables/build_art_table.py diff --git a/scripts/gen_nametable.py b/findings/retired-tables/gen_nametable.py similarity index 100% rename from scripts/gen_nametable.py rename to findings/retired-tables/gen_nametable.py diff --git a/scripts/titles.txt b/findings/retired-tables/titles.txt similarity index 100% rename from scripts/titles.txt rename to findings/retired-tables/titles.txt diff --git a/orbisrpc/health.c b/orbisrpc/health.c index 1ed9452..c41f789 100644 --- a/orbisrpc/health.c +++ b/orbisrpc/health.c @@ -140,7 +140,8 @@ int health_rollback(const char *path){ FILE *f = fopen(bak, "rb"); if(!f) return -1; fclose(f); - remove(path); + /* Atomic replace: never remove(path) first (a failed second step + * would leave no bootable binary at all). */ if(rename(bak, path) != 0) return -1; return health_check_binary(path) ? 0 : -1; } diff --git a/orbisrpc/timesync.c b/orbisrpc/timesync.c index 60eee04..16a959c 100644 --- a/orbisrpc/timesync.c +++ b/orbisrpc/timesync.c @@ -46,7 +46,14 @@ static int sntp_once(const char *host){ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv); setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv); int ok = -1; - if(sendto(fd, pkt, sizeof pkt, 0, res->ai_addr, res->ai_addrlen) == (int)sizeof pkt){ + /* Connect the UDP socket: recv() then only accepts the peer we + * queried, instead of any spoofed datagram on the LAN. */ + if(connect(fd, res->ai_addr, res->ai_addrlen) != 0){ + freeaddrinfo(res); + close(fd); + return -1; + } + if(send(fd, pkt, sizeof pkt, 0) == (int)sizeof pkt){ unsigned char rep[48]; ssize_t n = recv(fd, (char *)rep, sizeof rep, 0); if(n >= 48){ @@ -54,7 +61,10 @@ static int sntp_once(const char *host){ memcpy(&tx, rep + 40, 4); tx = ((tx & 0xff) << 24) | ((tx & 0xff00) << 8) | ((tx & 0xff0000) >> 8) | ((tx & 0xff000000) >> 24); - if(tx > NTP_EPOCH_OFFSET + 1700000000u){ + /* Sanity window Nov 2023..Dec 2034 (uint32 NTP wraps 2036): + * a broken/malicious server cannot fling our clock. */ + if(tx > NTP_EPOCH_OFFSET + 1700000000u && + tx < NTP_EPOCH_OFFSET + 2050000000u){ int64_t ntp_unix = (int64_t)(tx - NTP_EPOCH_OFFSET); s_offset = ntp_unix - (int64_t)time(NULL); s_synced = 1;