Adopt MI re-upgrade prevention
authorkn <kn@openbsd.org>
Fri, 20 Oct 2023 19:58:16 +0000 (19:58 +0000)
committerkn <kn@openbsd.org>
Fri, 20 Oct 2023 19:58:16 +0000 (19:58 +0000)
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) loops.

OK kettenis

sys/arch/powerpc64/stand/rdboot/cmd.c
sys/arch/powerpc64/stand/rdboot/rdboot.c

index ed93604..21f326a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cmd.c,v 1.1 2020/07/16 19:48:58 kettenis Exp $        */
+/*     $OpenBSD: cmd.c,v 1.2 2023/10/20 19:58:16 kn Exp $      */
 
 /*
  * Copyright (c) 1997-1999 Michael Shalayeff
@@ -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 5dc0d58..5b9254a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rdboot.c,v 1.3 2020/12/09 18:10:19 krw Exp $  */
+/*     $OpenBSD: rdboot.c,v 1.4 2023/10/20 19:58:16 kn Exp $   */
 
 /*
  * Copyright (c) 2019-2020 Visa Hankala
 #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;
@@ -185,6 +186,13 @@ kexec(void)
                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);
        if (kimg == NULL)
                goto load_failed;