In comparison to MI boot which only cares about /bsd.upgrade's x bit, powerpc64 rdboot just wants a regular file.
Require and strip u+x before execution to prevent sysupgrade(8) loop. I'm new to powerpc64 and can't think of a reason to be different. Feedback? Objection? OK? Regular boot and sysupgrade keep working. Tested with /bsd.upgrade without /auto_upgrade.conf, i.e. enough to put rdboot into sysupgrade mode, but not the installer into unattended upgrade: # cd /sys/arch/powerpc64/stand # make obj && make -j4 && make install # installboot sd0 # install -m 700 /bsd.rd /bsd.upgrade # reboot [...] >> OpenBSD/powerpc64 BOOT 0.3 probing disks available root devices: sd0 upgrade detected: switching to /bsd.upgrade boot> booting sd0a:/bsd.upgrade [...] Welcome to the OpenBSD/powerpc64 7.3 installation program. (I)nstall, (U)pgrade, (A)utoinstall or (S)hell? s # reboot syncing disks... done xhci0: halt timeout rebooting... [...] >> OpenBSD/powerpc64 BOOT 0.3 probing disks available root devices: sd0 /bsd.upgrade is not u+x boot> NOTE: random seed is being reused. booting sd0a:/bsd [...] # ls -l /bsd.upgrade -rw------- 1 root wheel 12005987 Sep 21 23:58 /bsd.upgrade Index: sys/arch/powerpc64//stand/rdboot/cmd.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc64/stand/rdboot/cmd.c,v retrieving revision 1.1 diff -u -p -r1.1 cmd.c --- sys/arch/powerpc64//stand/rdboot/cmd.c 16 Jul 2020 19:48:58 -0000 1.1 +++ sys/arch/powerpc64//stand/rdboot/cmd.c 21 Sep 2023 21:46:16 -0000 @@ -501,6 +501,10 @@ upgrade(void) return 0; if (stat(path, &sb) == 0 && S_ISREG(sb.st_mode)) ret = 1; + if ((sb.st_mode & S_IXUSR) == 0) { + printf("/bsd.upgrade is not u+x\n"); + ret = 0; + } disk_close(); return ret; Index: sys/arch/powerpc64//stand/rdboot/rdboot.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc64/stand/rdboot/rdboot.c,v retrieving revision 1.3 diff -u -p -r1.3 rdboot.c --- sys/arch/powerpc64//stand/rdboot/rdboot.c 9 Dec 2020 18:10:19 -0000 1.3 +++ sys/arch/powerpc64//stand/rdboot/rdboot.c 21 Sep 2023 21:05:07 -0000 @@ -47,17 +47,17 @@ #define KERNEL "/bsd" int loadrandom(void); -void kexec(void); +void kexec(int); struct cmd_state cmd; int kexecfd = -1; -const char version[] = "0.2"; +const char version[] = "0.3"; int main(void) { u_char bootduid[8]; - int fd, hasboot; + int fd, hasboot, isupgrade = 0; fd = open(_PATH_CONSOLE, O_RDWR); login_tty(fd); @@ -89,6 +89,7 @@ main(void) if (upgrade()) { strlcpy(cmd.image, "/bsd.upgrade", sizeof(cmd.image)); printf("upgrade detected: switching to %s\n", cmd.image); + isupgrade = 1; } hasboot = read_conf(); @@ -103,7 +104,7 @@ main(void) if (loadrandom() == 0) cmd.boothowto |= RB_GOODRANDOM; - kexec(); + kexec(isupgrade); hasboot = 0; strlcpy(cmd.image, KERNEL, sizeof(cmd.image)); @@ -161,7 +162,7 @@ loadrandom(void) } void -kexec(void) +kexec(int isupgrade) { struct kexec_args kargs; struct stat sb; @@ -183,6 +184,13 @@ kexec(void) if (!S_ISREG(sb.st_mode) || sb.st_size == 0) { errno = ENOEXEC; goto load_failed; + } + + /* Prevent re-upgrade: chmod a-x bsd.upgrade */ + if (isupgrade) { + sb.st_mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); + if (fchmod(fd, sb.st_mode) == -1) + printf("fchmod a-x %s: failed\n", path); } kimg = malloc(sb.st_size);