From: kettenis Date: Wed, 1 Dec 2021 17:25:35 +0000 (+0000) Subject: Fix booting from an IDE block device on the Sun Blade 100. Apparently X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=71b09c7362424ca32145208b6f624a81e24f4ff8;p=openbsd Fix booting from an IDE block device on the Sun Blade 100. Apparently writing to disk using the Open Firmware interfaces is buggy and causes corruption of the disk. While it isn't entirely clear what versions of Open Firmware are affected, but it seems to only affect IDE drives. So if we detect an IDE drive, disable writing to it. This results in a small lose of bootloader functionality (bsd.upgrade loop prevention and flagging /etc/random.seed re-use) but that is better than losing the ability to run OpenBSD at all. Based on a diff by Ted Bullock (who did all the hard work of debugging this and coming up with a viable fix). ok deraadt@ --- diff --git a/sys/arch/sparc64/stand/ofwboot/ofdev.c b/sys/arch/sparc64/stand/ofwboot/ofdev.c index c23b4129c66..2a4a37e2f78 100644 --- a/sys/arch/sparc64/stand/ofwboot/ofdev.c +++ b/sys/arch/sparc64/stand/ofwboot/ofdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofdev.c,v 1.31 2020/12/09 18:10:19 krw Exp $ */ +/* $OpenBSD: ofdev.c,v 1.32 2021/12/01 17:25:35 kettenis Exp $ */ /* $NetBSD: ofdev.c,v 1.1 2000/08/20 14:58:41 mrg Exp $ */ /* @@ -520,7 +520,7 @@ devopen(struct open_file *of, const char *name, char **file) char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; - int handle, part; + int dhandle, ihandle, part, parent; int error = 0; #ifdef SOFTRAID char volno; @@ -647,23 +647,24 @@ devopen(struct open_file *of, const char *name, char **file) return 0; } #endif - if ((handle = OF_finddevice(fname)) == -1) + if ((dhandle = OF_finddevice(fname)) == -1) return ENOENT; + DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); - if (OF_getprop(handle, "name", buf, sizeof buf) < 0) + if (OF_getprop(dhandle, "name", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf); - if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) + if (OF_getprop(dhandle, "device_type", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf); DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname); - if ((handle = OF_open(fname)) == -1) { + if ((ihandle = OF_open(fname)) == -1) { DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); return ENXIO; } DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname); bzero(&ofdev, sizeof ofdev); - ofdev.handle = handle; + ofdev.handle = ihandle; ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; if (!strcmp(buf, "block")) { @@ -685,6 +686,16 @@ devopen(struct open_file *of, const char *name, char **file) of->f_dev = devsw; of->f_devdata = &ofdev; + + /* Some PROMS have buggy writing code for IDE block devices */ + parent = OF_parent(dhandle); + if (parent && OF_getprop(parent, "device_type", buf, + sizeof(buf)) > 0 && strcmp(buf, "ide") == 0) { + DNPRINTF(BOOT_D_OFDEV, + "devopen: Disable writing for IDE block device\n"); + of->f_flags |= F_NOWRITE; + } + #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); bcopy(&file_system_ufs2, &file_system[nfsys++], sizeof file_system[0]); @@ -712,7 +723,7 @@ devopen(struct open_file *of, const char *name, char **file) bad: DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n", error); - OF_close(handle); + OF_close(ihandle); ofdev.handle = -1; return error; } diff --git a/sys/arch/sparc64/stand/ofwboot/vers.c b/sys/arch/sparc64/stand/ofwboot/vers.c index 3ca4ec8093b..78466bad3c0 100644 --- a/sys/arch/sparc64/stand/ofwboot/vers.c +++ b/sys/arch/sparc64/stand/ofwboot/vers.c @@ -1 +1 @@ -const char version[] = "1.21"; +const char version[] = "1.22"; diff --git a/sys/lib/libsa/fchmod.c b/sys/lib/libsa/fchmod.c index 7d9bc9cac36..f6252ca9e56 100644 --- a/sys/lib/libsa/fchmod.c +++ b/sys/lib/libsa/fchmod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fchmod.c,v 1.1 2019/08/03 15:22:17 deraadt Exp $ */ +/* $OpenBSD: fchmod.c,v 1.2 2021/12/01 17:25:35 kettenis Exp $ */ /* $NetBSD: stat.c,v 1.3 1994/10/26 05:45:07 cgd Exp $ */ /*- @@ -53,6 +53,11 @@ fchmod(int fd, mode_t m) errno = EOPNOTSUPP; return (-1); } + /* writing is broken or unsupported */ + if (f->f_flags & F_NOWRITE) { + errno = EOPNOTSUPP; + return (-1); + } errno = (f->f_ops->fchmod)(f, m); return (0); diff --git a/sys/lib/libsa/stand.h b/sys/lib/libsa/stand.h index 9720fe6b1c4..cad63ea389a 100644 --- a/sys/lib/libsa/stand.h +++ b/sys/lib/libsa/stand.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stand.h,v 1.71 2021/10/24 17:49:19 deraadt Exp $ */ +/* $OpenBSD: stand.h,v 1.72 2021/12/01 17:25:35 kettenis Exp $ */ /* $NetBSD: stand.h,v 1.18 1996/11/30 04:35:51 gwr Exp $ */ /*- @@ -107,10 +107,11 @@ struct open_file { extern struct open_file files[]; /* f_flags values */ -#define F_READ 0x0001 /* file opened for reading */ -#define F_WRITE 0x0002 /* file opened for writing */ -#define F_RAW 0x0004 /* raw device open - no file system */ -#define F_NODEV 0x0008 /* network open - no device */ +#define F_READ 0x0001 /* file opened for reading */ +#define F_WRITE 0x0002 /* file opened for writing */ +#define F_RAW 0x0004 /* raw device open - no file system */ +#define F_NODEV 0x0008 /* network open - no device */ +#define F_NOWRITE 0x0010 /* bootblock writing broken or unsupported */ #define isupper(c) ((c) >= 'A' && (c) <= 'Z') #define islower(c) ((c) >= 'a' && (c) <= 'z')