diff options
author | Marcus Watts <mdw@cvs.openbsd.org> | 2003-05-11 20:22:21 +0000 |
---|---|---|
committer | Marcus Watts <mdw@cvs.openbsd.org> | 2003-05-11 20:22:21 +0000 |
commit | d2b7d3c540a8119cdec0e2d3d9ee80b3b6f7c8ac (patch) | |
tree | 2ec672fac193da2dd9bc8f76c5c3ce77aed92ca7 /sys/arch | |
parent | 07e6111b9778d39f71f987769d0095c40d86da1c (diff) |
don't run off end of strings and use bad pointers
iterate boot list at most once
allow kernel names with - in them
complain about option strings that do not start with -
distinguish between short read & bad read
don't quit if a file can be opened but can't be booted
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sparc64/stand/ofwboot/boot.c | 189 |
1 files changed, 108 insertions, 81 deletions
diff --git a/sys/arch/sparc64/stand/ofwboot/boot.c b/sys/arch/sparc64/stand/ofwboot/boot.c index f5d983f41bb..9a2b3378256 100644 --- a/sys/arch/sparc64/stand/ofwboot/boot.c +++ b/sys/arch/sparc64/stand/ofwboot/boot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: boot.c,v 1.6 2002/03/14 03:16:01 millert Exp $ */ +/* $OpenBSD: boot.c,v 1.7 2003/05/11 20:22:20 mdw Exp $ */ /* $NetBSD: boot.c,v 1.3 2001/05/31 08:55:19 mrg Exp $ */ /* * Copyright (c) 1997, 1999 Eduardo E. Horvath. All rights reserved. @@ -73,7 +73,6 @@ char *kernels[] = { NULL }; -char *kernelname; char bootdev[128]; char bootfile[128]; int boothowto; @@ -107,7 +106,15 @@ prom2boot(dev) } #endif -static void +/* + * parse: + * [kernel-name] [-options] + * leave kernel-name in passed-in string + * put options into *howtop + * return -1 iff syntax error (no - before options) + */ + +static int parseargs(str, howtop) char *str; int *howtop; @@ -115,28 +122,28 @@ parseargs(str, howtop) char *cp; int i; - /* Allow user to drop back to the PROM. */ - if (strcmp(str, "exit") == 0 || strcmp(str, "halt") == 0) - _rtt(); - - /* Insert the kernel name if it is not there. */ - if (str[0] == 0 || str[0] == '-') { - /* Move args down the string */ - i=0; - for (cp = str + strlen(kernelname); str[i]; i++) - cp[i] = str[i]; - /* Copy over kernelname */ - for (i = 0; kernelname[i]; i++) - str[i] = kernelname[i]; - } *howtop = 0; - for (cp = str; *cp; cp++) - if (*cp == ' ' || *cp == '-') - break; - if (!*cp) - return; - - *cp++ = 0; + cp = str; + while (*cp == ' ') + ++cp; + if (*cp != '-') { + while (*cp && *cp != ' ') + *str++ = *cp++; + while (*cp == ' ') + ++cp; + } + *str = 0; + switch(*cp) { + default: + printf ("boot options string <%s> must start with -\n", cp); + return -1; + case 0: + return 0; + case '-': + break; + } + + ++cp; while (*cp) { BOOT_FLAG(*cp, *howtop); /* handle specialties */ @@ -147,10 +154,9 @@ parseargs(str, howtop) case 'D': debug = 2; break; - default: - break; } } + return 0; } @@ -230,7 +236,6 @@ loadfile(fd, args) void *ssym; void *esym; - rval = 1; ssym = NULL; esym = NULL; @@ -238,8 +243,13 @@ loadfile(fd, args) #ifdef DEBUG printf("loadfile: reading header\n"); #endif - if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) { - printf("read header: %s\n", strerror(errno)); + if ((rval = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { + if (rval == -1) + printf("read header: %s\n", strerror(errno)); + else + printf("read header: short read (only %d of %d)\n", + rval, sizeof(hdr)); + rval = 1; goto err; } @@ -260,6 +270,7 @@ loadfile(fd, args) } else #endif { + rval = 1; printf("unknown executable format\n"); } @@ -533,10 +544,9 @@ main() char bootline[512]; /* Should check size? */ char *cp; int i, fd; + char **bootlp; + char *just_bootline[2]; - /* Initialize kernelname */ - kernelname = kernels[0]; - printf(">> %s", version); /* @@ -548,65 +558,82 @@ main() printf("Invalid Openfirmware environment\n"); exit(); } - /*prom2boot(bootdev);*/ - kernelname = kernels[0]; - parseargs(bootline, &boothowto); - for (i=0;;) { - kernelname = kernels[i]; - if (boothowto & RB_ASKNAME) { + + /* + * case 1: boot net -a + * -> gets loop + * case 2: boot net kernel [options] + * -> boot kernel, gets loop + * case 3: boot net [options] + * -> iterate boot list, gets loop + */ + + bootlp = kernels; + if (parseargs(bootline, &boothowto) == -1 + || (boothowto & RB_ASKNAME)) { + bootlp = 0; + } else if (*bootline) { + just_bootline[0] = bootline; + just_bootline[1] = 0; + bootlp = just_bootline; + } + for (;;) { + if (bootlp) { + cp = *bootlp++; + if (!cp) { + printf("\n"); + bootlp = 0; + kernels[0] = 0; /* no more iteration */ + } else if (cp != bootline) { + printf(": trying %s...\n", cp); + strcpy(bootline, cp); + } + } + if (!bootlp) { printf("Boot: "); gets(bootline); - parseargs(bootline, &boothowto); + if (parseargs(bootline, &boothowto) == -1) + continue; + if (!*bootline) { + bootlp = kernels; + continue; + } + if (strcmp(bootline, "exit") == 0 + || strcmp(bootline, "halt") == 0) { + _rtt(); + } } - if ((fd = open(bootline, 0)) >= 0) - break; - if (errno) + if ((fd = open(bootline, 0)) < 0) { printf("open %s: %s\n", opened_name, strerror(errno)); - /* - * if we have are not in askname mode, and we aren't using the - * prom bootfile, try the next one (if it exits). otherwise, - * go into askname mode. - */ - if ((boothowto & RB_ASKNAME) == 0 && - i != -1 && kernels[++i]) { - printf(": trying %s...\n", kernels[i]); - } else { - printf("\n"); - boothowto |= RB_ASKNAME; + continue; } - } #ifdef __notyet__ - OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1); - cp = bootline; + OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1); + cp = bootline; #else - strcpy(bootline, opened_name); - cp = bootline + strlen(bootline); - *cp++ = ' '; + strcpy(bootline, opened_name); + cp = bootline + strlen(bootline); + *cp++ = ' '; #endif - *cp = '-'; - if (boothowto & RB_ASKNAME) - *++cp = 'a'; - if (boothowto & RB_SINGLE) - *++cp = 's'; - if (boothowto & RB_KDB) - *++cp = 'd'; - if (*cp == '-') + *cp = '-'; + if (boothowto & RB_ASKNAME) + *++cp = 'a'; + if (boothowto & RB_SINGLE) + *++cp = 's'; + if (boothowto & RB_KDB) + *++cp = 'd'; + if (*cp == '-') + *--cp = 0; + else + *++cp = 0; #ifdef __notyet__ - *cp = 0; -#else - *--cp = 0; + OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1); #endif - else - *++cp = 0; -#ifdef __notyet__ - OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1); -#endif - /* XXX void, for now */ + /* XXX void, for now */ #ifdef DEBUG - if (debug) - printf("main: Calling loadfile(fd, %s)\n", bootline); + if (debug) + printf("main: Calling loadfile(fd, %s)\n", bootline); #endif - (void)loadfile(fd, bootline); - - _rtt(); + (void)loadfile(fd, bootline); + } } |