mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 15:40:44 +00:00
Fix setdumpdev():
- the major number wasn't checked, so accesses beyond the end of bdevsw[] were possible. Bogus major numbers are easy to get because `sysctl -w' doesn't handle dev_t's reasonably - it doesn't convert names to dev_t's and it converts the number 1025 to the dev_t 0x35323031. - Driver d_psize() functions return -1 to indicate error ENXIO or ENODEV (the interface is too braindamaged to say which). -1 was interpreted as a size and resulted in the bogus error ENOSPC. - it was possible to set the dumpdev for devices without a d_psize() function. This is equivalent to setting the dumpdev to NODEV except it confuses sysctl. - change a 512 to DEV_BSIZE. There is an official macro dtoc() for converting "pages" to disk blocks but it is never used in /usr/src/sys. There is much confusion between PAGE_SIZE sized pages and NBPG sized pages. Maxmem consists of both. Not fixed: - there is nothing to invalidate the dumpdev if the media goes away. This reduces the benefits of the early calculation of dumplo. Bounds checking in the dump routines is relied on to reduce the risk of damage and little would be lost by relying on the dump routines to calculate dumplo. - no attempt is made to stay away from the start of the device to avoid clobbering labels. Fix wrong && anachronistic comment about the type of bootdev. Reviewed by: davidg Submitted by: Bruce Evans
This commit is contained in:
parent
77f53bcf27
commit
ac8d676972
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=8833
|
@ -34,7 +34,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
|
||||
* $Id: autoconf.c,v 1.30 1995/05/12 19:17:11 wollman Exp $
|
||||
* $Id: autoconf.c,v 1.31 1995/05/14 02:59:51 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -212,27 +212,34 @@ configure()
|
|||
}
|
||||
|
||||
int
|
||||
setdumpdev(dev_t dev)
|
||||
setdumpdev(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
long newdumplo, psize;
|
||||
if (dev != NODEV && bdevsw[major(dev)].d_psize) {
|
||||
psize = bdevsw[major(dev)].d_psize(dev);
|
||||
newdumplo = bdevsw[major(dev)].d_psize(dev) - Maxmem*NBPG/512;
|
||||
if (newdumplo >= 0) {
|
||||
dumpdev = dev;
|
||||
dumplo = newdumplo;
|
||||
return 0;
|
||||
}
|
||||
return ENOSPC;
|
||||
} else {
|
||||
int maj, psize;
|
||||
long newdumplo;
|
||||
|
||||
if (dev == NODEV) {
|
||||
dumpdev = dev;
|
||||
dumplo = 0;
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
maj = major(dev);
|
||||
if (maj >= nblkdev)
|
||||
return (ENXIO);
|
||||
if (bdevsw[maj].d_psize == NULL)
|
||||
return (ENXIO); /* XXX should sometimes be ENODEV */
|
||||
psize = bdevsw[maj].d_psize(dev);
|
||||
if (psize == -1)
|
||||
return (ENXIO); /* XXX should sometimes be ENODEV */
|
||||
newdumplo = psize - Maxmem * NBPG / DEV_BSIZE;
|
||||
if (newdumplo < 0)
|
||||
return (ENOSPC);
|
||||
dumpdev = dev;
|
||||
dumplo = newdumplo;
|
||||
return (0);
|
||||
}
|
||||
|
||||
u_long bootdev = 0; /* should be dev_t, but not until 32 bits */
|
||||
u_long bootdev = 0; /* not a dev_t - encoding is different */
|
||||
|
||||
static char devname[][2] = {
|
||||
{'w','d'}, /* 0 = wd */
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
|
||||
* $Id: autoconf.c,v 1.30 1995/05/12 19:17:11 wollman Exp $
|
||||
* $Id: autoconf.c,v 1.31 1995/05/14 02:59:51 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -212,27 +212,34 @@ configure()
|
|||
}
|
||||
|
||||
int
|
||||
setdumpdev(dev_t dev)
|
||||
setdumpdev(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
long newdumplo, psize;
|
||||
if (dev != NODEV && bdevsw[major(dev)].d_psize) {
|
||||
psize = bdevsw[major(dev)].d_psize(dev);
|
||||
newdumplo = bdevsw[major(dev)].d_psize(dev) - Maxmem*NBPG/512;
|
||||
if (newdumplo >= 0) {
|
||||
dumpdev = dev;
|
||||
dumplo = newdumplo;
|
||||
return 0;
|
||||
}
|
||||
return ENOSPC;
|
||||
} else {
|
||||
int maj, psize;
|
||||
long newdumplo;
|
||||
|
||||
if (dev == NODEV) {
|
||||
dumpdev = dev;
|
||||
dumplo = 0;
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
maj = major(dev);
|
||||
if (maj >= nblkdev)
|
||||
return (ENXIO);
|
||||
if (bdevsw[maj].d_psize == NULL)
|
||||
return (ENXIO); /* XXX should sometimes be ENODEV */
|
||||
psize = bdevsw[maj].d_psize(dev);
|
||||
if (psize == -1)
|
||||
return (ENXIO); /* XXX should sometimes be ENODEV */
|
||||
newdumplo = psize - Maxmem * NBPG / DEV_BSIZE;
|
||||
if (newdumplo < 0)
|
||||
return (ENOSPC);
|
||||
dumpdev = dev;
|
||||
dumplo = newdumplo;
|
||||
return (0);
|
||||
}
|
||||
|
||||
u_long bootdev = 0; /* should be dev_t, but not until 32 bits */
|
||||
u_long bootdev = 0; /* not a dev_t - encoding is different */
|
||||
|
||||
static char devname[][2] = {
|
||||
{'w','d'}, /* 0 = wd */
|
||||
|
|
Loading…
Reference in a new issue