Mercurial > illumos > illumos-gate
changeset 9956:1705cb23ec4b
6779206 a read(2) access to /devices/ramdisk:a after the boot is over causes panic
author | William Roche <William.Roche@Sun.COM> |
---|---|
date | Tue, 23 Jun 2009 23:08:42 +0100 |
parents | 0df5d471a4c5 |
children | 8769ec0debbf |
files | usr/src/uts/common/io/ramdisk.c usr/src/uts/sparc/os/bootops.c |
diffstat | 2 files changed, 35 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/ramdisk.c Tue Jun 23 11:52:41 2009 -0700 +++ b/usr/src/uts/common/io/ramdisk.c Tue Jun 23 23:08:42 2009 +0100 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -85,6 +85,14 @@ #include <vm/seg_kmem.h> /* + * Flag to disable the use of real ramdisks (in the OBP - on Sparc) when + * the associated memory is no longer available - set in the bootops section. + */ +#ifdef __sparc +extern int bootops_obp_ramdisk_disabled; +#endif /* __sparc */ + +/* * An opaque handle where information about our set of ramdisk devices lives. */ static void *rd_statep; @@ -820,6 +828,11 @@ goto attach_failed; } } else { +#ifdef __sparc + if (bootops_obp_ramdisk_disabled) + goto attach_failed; +#endif /* __sparc */ + RD_STRIP_PREFIX(name, ddi_node_name(dip)); if (strlen(name) > RD_NAME_LEN) { @@ -1073,6 +1086,13 @@ } } +/* + * On Sparc, this function deals with both pseudo ramdisks and OBP ramdisks. + * In the case where we freed the "bootarchive" ramdisk in bop_free_archive(), + * we stop allowing access to the OBP ramdisks. To do so, we set the + * bootops_obp_ramdisk_disabled flag to true, and we check if the operation + * is for an OBP ramdisk. In this case we indicate an ENXIO error. + */ static int rd_strategy(struct buf *bp) { @@ -1082,7 +1102,13 @@ rsp = ddi_get_soft_state(rd_statep, getminor(bp->b_edev)); offset = bp->b_blkno * DEV_BSIZE; +#ifdef __sparc + if (rsp == NULL || + (bootops_obp_ramdisk_disabled && + (rsp->rd_dip != rd_dip || rd_dip == NULL))) { /* OBP ramdisk */ +#else /* __sparc */ if (rsp == NULL) { +#endif /* __sparc */ bp->b_error = ENXIO; bp->b_flags |= B_ERROR; } else if (offset >= rsp->rd_size) {
--- a/usr/src/uts/sparc/os/bootops.c Tue Jun 23 11:52:41 2009 -0700 +++ b/usr/src/uts/sparc/os/bootops.c Tue Jun 23 23:08:42 2009 +0100 @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Definitions of interfaces that provide services from the secondary * boot program to its clients (primarily Solaris, krtld, kmdb and their @@ -49,6 +47,11 @@ struct bootops kbootops; pnode_t chosennode; +/* + * Flag to disable the use of real ramdisks (in the OBP - on Sparc) when + * the associated memory is no longer available. + */ +int bootops_obp_ramdisk_disabled = 0; #define FAKE_ROOT (pnode_t)1 @@ -522,6 +525,8 @@ prom_getprop(arph, OBP_ADDRESS, (caddr_t)&arbase) == -1) prom_panic("can't free boot archive"); + bootops_obp_ramdisk_disabled = 1; + #if !defined(C_OBP) if (alloc_size == 0) prom_free((caddr_t)(uintptr_t)arbase, arsize);