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);