On Thu, Sep 21, 2023 at 10:30:01PM +0000, Klemens Nanni wrote: > 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:
Same diff, test and behaviour on octeon. # cd /sys/arch/octeon/stand # make obj && make -j8 && make install # installboot sd0 # install -m 700 /bsd.rd /bsd.upgrade # reboot [...] U-Boot 2013.07 (UBNT Build Version: e1000_003_c6018) (May 27 2019 - 06:43:21) [...] >> OpenBSD/octeon BOOT 1.4 upgrade detected: switching to /bsd.upgrade boot> booting sd0a:/bsd.upgrade [...] Welcome to the OpenBSD/octeon 7.4 installation program. (I)nstall, (U)pgrade, (A)utoinstall or (S)hell? s # reboot [...] >> OpenBSD/octeon BOOT 1.4 /bsd.upgrade is not u+x boot> NOTE: random seed is being reused. booting sd0a:/bsd [...] # ls -l /bsd.upgrade -rw------- 1 root wheel 8872243 Sep 22 17:20 /bsd.upgrade Index: sys/arch/octeon/stand/rdboot/cmd.c =================================================================== RCS file: /cvs/src/sys/arch/octeon/stand/rdboot/cmd.c,v retrieving revision 1.3 diff -u -p -r1.3 cmd.c --- sys/arch/octeon/stand/rdboot/cmd.c 1 Aug 2019 04:52:56 -0000 1.3 +++ sys/arch/octeon/stand/rdboot/cmd.c 22 Sep 2023 12:20:53 -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/octeon/stand/rdboot/rdboot.c =================================================================== RCS file: /cvs/src/sys/arch/octeon/stand/rdboot/rdboot.c,v retrieving revision 1.8 diff -u -p -r1.8 rdboot.c --- sys/arch/octeon/stand/rdboot/rdboot.c 9 Dec 2020 18:10:19 -0000 1.8 +++ sys/arch/octeon/stand/rdboot/rdboot.c 22 Sep 2023 12:35:27 -0000 @@ -47,17 +47,17 @@ #define KERNEL "/bsd" int loadrandom(void); -void kexec(void); +void kexec(int); struct cmd_state cmd; int octbootfd = -1; -const char version[] = "1.3"; +const char version[] = "1.4"; int main(void) { char rootdev[PATH_MAX]; - int fd, hasboot; + int fd, hasboot, isupgrade = 0; fd = open(_PATH_CONSOLE, O_RDWR); login_tty(fd); @@ -91,6 +91,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(); @@ -105,7 +106,7 @@ main(void) if (loadrandom() == 0) cmd.boothowto |= RB_GOODRANDOM; - kexec(); + kexec(isupgrade); hasboot = 0; strlcpy(cmd.image, KERNEL, sizeof(cmd.image)); @@ -163,7 +164,7 @@ loadrandom(void) } void -kexec(void) +kexec(int isupgrade) { struct octboot_kexec_args kargs; struct stat sb; @@ -187,6 +188,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);