Date: Sun, 17 Mar 2002 19:04:43 +0100 (CET) From: Thomas Quinot <thomas@cuivre.fr.eu.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: i386/36015: [patch] boot2.c deobfuscation Message-ID: <20020317180443.6A9D42C3D1@melusine.cuivre.fr.eu.org>
next in thread | raw e-mail | index | archive | help
>Number: 36015 >Category: i386 >Synopsis: [patch] boot2.c deobfuscation >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Mar 17 10:10:01 PST 2002 >Closed-Date: >Last-Modified: >Originator: Thomas Quinot >Release: FreeBSD 4.5-STABLE i386 >Organization: >Environment: System: FreeBSD melusine.cuivre.fr.eu.org 4.5-STABLE FreeBSD 4.5-STABLE #1: Thu Jan 31 22:48:26 CET 2002 thomas@melusine.cuivre.fr.eu.org:/usr2/obj/usr2/src/sys/MELUSINE i386 >Description: The code in boot2.c is rather obscure. >How-To-Repeat: Look at the sources. >Fix: The following patches clarifies the stream of control at the beginning of main() by making autoboot a two-state variable (instead of a 3-state), with no functional at all. Magical numeric values for ioctrl are replaced with #define'd macros. Hard-coded tick values for calls to keyhit are replaced by static expressions in terms of multiples of a SECOND #define. This change introduces a functional difference: the first time-out will be 1 tick shorter. Index: sys/boot/i386/boot2/boot2.c =================================================================== RCS file: /home/ncvs/src/sys/boot/i386/boot2/boot2.c,v retrieving revision 1.37 diff -u -r1.37 boot2.c --- sys/boot/i386/boot2/boot2.c 13 Mar 2002 11:03:36 -0000 1.37 +++ sys/boot/i386/boot2/boot2.c 15 Mar 2002 12:46:54 -0000 @@ -37,6 +37,11 @@ #include "boot2.h" #include "lib.h" +#define IO_KEYBOARD 1 +#define IO_SERIAL 2 + +#define SECOND 18 /* Circa that many ticks in a second. */ + #define RBX_ASKNAME 0x0 /* -a */ #define RBX_SINGLE 0x1 /* -s */ #define RBX_DFLTROOT 0x5 /* -r */ @@ -136,7 +141,7 @@ static struct bootinfo bootinfo; static int ls; static uint32_t fs_off; -static uint8_t ioctrl = 0x1; +static uint8_t ioctrl = IO_KEYBOARD; void exit(int); static void load(const char *); @@ -279,34 +284,39 @@ bootinfo.bi_memsizes_valid++; for (i = 0; i < N_BIOS_GEOM; i++) bootinfo.bi_bios_geom[i] = drvinfo(i); - autoboot = 2; + + /* Process configuration file */ + + autoboot = 1; readfile(PATH_CONFIG, cmd, sizeof(cmd)); if (*cmd) { printf("%s: %s", PATH_CONFIG, cmd); if (parse(cmd)) autoboot = 0; - *cmd = 0; } - if (autoboot && !*kname) { - if (autoboot == 2) { - memcpy(kname, PATH_BOOT3, sizeof(PATH_BOOT3)); - if (!keyhit(0x37)) { - load(kname); - autoboot = 1; - } - } - if (autoboot == 1) + + /* Try to exec stage 3 boot loader. If interrupted by a keypress, * + * or in case of failure, try to load a kernel directly instaed. */ + + if (autoboot) { + memcpy(kname, PATH_BOOT3, sizeof(PATH_BOOT3)); + if (!keyhit(3 * SECOND)) { + load(kname); memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL)); + } } + + /* Present the user with the boot2 prompt. */ + for (;;) { printf(" \n>> FreeBSD/i386 BOOT\n" "Default: %u:%s(%u,%c)%s\n" "boot: ", dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, 'a' + dsk.part, kname); - if (ioctrl & 0x2) + if (ioctrl & IO_SERIAL) sio_flush(); - if (!autoboot || keyhit(0x5a)) + if (!autoboot || keyhit(5 * SECOND)) getstr(cmd, sizeof(cmd)); else putchar('\n'); @@ -445,9 +455,9 @@ opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; opts &= ~(1 << RBX_PROBEKBD); } - ioctrl = opts & 1 << RBX_DUAL ? 0x3 : - opts & 1 << RBX_SERIAL ? 0x2 : 0x1; - if (ioctrl & 0x2) + ioctrl = opts & 1 << RBX_DUAL ? (IO_SERIAL | IO_KEYBOARD) : + opts & 1 << RBX_SERIAL ? IO_SERIAL : IO_KEYBOARD; + if (ioctrl & IO_SERIAL) sio_init(); } else { for (q = arg--; *q && *q != '('; q++); @@ -790,9 +800,9 @@ static int xputc(int c) { - if (ioctrl & 0x1) + if (ioctrl & IO_KEYBOARD) putc(c); - if (ioctrl & 0x2) + if (ioctrl & IO_SERIAL) sio_putc(c); return c; } @@ -801,9 +811,9 @@ xgetc(int fn) { for (;;) { - if (ioctrl & 0x1 && getc(1)) + if (ioctrl & IO_KEYBOARD && getc(1)) return fn ? 1 : getc(0); - if (ioctrl & 0x2 && sio_ischar()) + if (ioctrl & IO_SERIAL && sio_ischar()) return fn ? 1 : sio_getc(); if (fn) return 0; >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020317180443.6A9D42C3D1>