summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2004-04-01 20:57:09 +0000
committermiod <miod@openbsd.org>2004-04-01 20:57:09 +0000
commitc16935528a262bba5fdf60a8da464cfc23487e2d (patch)
treef1dfb25080d9cccd22dd817981313a8fc88c062f
parentIt turns out that the so-called fast ffs(3) routines were wrong, as soon as (diff)
downloadwireguard-openbsd-c16935528a262bba5fdf60a8da464cfc23487e2d.tar.xz
wireguard-openbsd-c16935528a262bba5fdf60a8da464cfc23487e2d.zip
Better bounds checking in strategy(), and kill the (unused) rd flags
while there. ok tdeval@ (long ago)
-rw-r--r--sys/dev/ramdisk.c119
1 files changed, 52 insertions, 67 deletions
diff --git a/sys/dev/ramdisk.c b/sys/dev/ramdisk.c
index 7d517bca715..4cf7e473490 100644
--- a/sys/dev/ramdisk.c
+++ b/sys/dev/ramdisk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ramdisk.c,v 1.23 2004/01/14 20:50:49 miod Exp $ */
+/* $OpenBSD: ramdisk.c,v 1.24 2004/04/01 20:57:09 miod Exp $ */
/* $NetBSD: ramdisk.c,v 1.8 1996/04/12 08:30:09 leo Exp $ */
/*
@@ -88,20 +88,18 @@ struct rd_softc {
struct device sc_dev; /* REQUIRED first entry */
struct disk sc_dkdev; /* hook for generic disk handling */
struct rd_conf sc_rd;
+#if RAMDISK_SERVER
struct buf *sc_buflist;
- int sc_flags;
+#endif
};
/* shorthand for fields in sc_rd: */
#define sc_addr sc_rd.rd_addr
#define sc_size sc_rd.rd_size
#define sc_type sc_rd.rd_type
-/* flags */
-#define RD_ISOPEN 0x01
-#define RD_SERVED 0x02
void rdattach(int);
void rd_attach(struct device *, struct device *, void *);
-struct disklabel *rdgetdisklabel(dev_t dev, struct rd_softc *sc);
+void rdgetdisklabel(struct rd_softc *sc);
/*
* Some ports (like i386) use a swapgeneric that wants to
@@ -225,7 +223,6 @@ rdsize(dev_t dev)
{
int part, unit;
struct rd_softc *sc;
- struct disklabel *lp;
/* Disallow control units. */
unit = DISKUNIT(dev);
@@ -238,13 +235,13 @@ rdsize(dev_t dev)
if (sc->sc_type == RD_UNCONFIGURED)
return 0;
- lp = rdgetdisklabel(dev, sc);
+ rdgetdisklabel(sc);
part = DISKPART(dev);
- if (part > lp->d_npartitions)
+ if (part >= sc->sc_dkdev.dk_label->d_npartitions)
return 0;
else
- return lp->d_partitions[part].p_size *
- (lp->d_secsize / DEV_BSIZE);
+ return sc->sc_dkdev.dk_label->d_partitions[part].p_size *
+ (sc->sc_dkdev.dk_label->d_secsize / DEV_BSIZE);
}
int
@@ -281,8 +278,6 @@ rdopen(dev, flag, fmt, proc)
*/
if (sc->sc_type == RD_UNCONFIGURED)
return ENXIO;
- if (sc->sc_flags & RD_ISOPEN)
- return EBUSY;
return 0;
}
@@ -293,17 +288,6 @@ rdclose(dev, flag, fmt, proc)
int flag, fmt;
struct proc *proc;
{
- int unit;
- struct rd_softc *sc;
-
- unit = DISKUNIT(dev);
- sc = ramdisk_devs[unit];
-
- if (RD_IS_CTRL(dev))
- return 0;
-
- /* Normal device. */
- sc->sc_flags = 0;
return 0;
}
@@ -334,15 +318,29 @@ void
rdstrategy(bp)
struct buf *bp;
{
- int unit;
+ int unit, part;
struct rd_softc *sc;
caddr_t addr;
- size_t off, xfer;
+ size_t off, xfer;
int s;
unit = DISKUNIT(bp->b_dev);
sc = ramdisk_devs[unit];
+ /* Sort rogue requests out */
+ if (sc == NULL || bp->b_blkno < 0 ||
+ (bp->b_bcount % sc->sc_dkdev.dk_label->d_secsize) != 0) {
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+
+ /* Do not write on "no trespassing" areas... */
+ part = DISKPART(bp->b_dev);
+ if (part != RAW_PART &&
+ bounds_check_with_label(bp, sc->sc_dkdev.dk_label,
+ sc->sc_dkdev.dk_cpulabel, 1) <= 0)
+ goto bad;
+
switch (sc->sc_type) {
#if RAMDISK_SERVER
case RD_UMEM_SERVER:
@@ -363,12 +361,7 @@ rdstrategy(bp)
/* These are in kernel space. Access directly. */
bp->b_resid = bp->b_bcount;
off = (bp->b_blkno << DEV_BSHIFT);
- if (off >= sc->sc_size) {
- if (bp->b_flags & B_READ)
- break; /* EOF */
- goto set_eio;
- }
- xfer = bp->b_resid;
+ xfer = bp->b_bcount;
if (xfer > (sc->sc_size - off))
xfer = (sc->sc_size - off);
addr = sc->sc_addr + off;
@@ -380,12 +373,13 @@ rdstrategy(bp)
break;
default:
- bp->b_resid = bp->b_bcount;
- set_eio:
bp->b_error = EIO;
+bad:
bp->b_flags |= B_ERROR;
+ bp->b_resid = bp->b_bcount;
break;
}
+
s = splbio();
biodone(bp);
splx(s);
@@ -402,8 +396,6 @@ rdioctl(dev, cmd, data, flag, proc)
int unit;
struct rd_softc *sc;
struct rd_conf *urd;
- struct cpu_disklabel clp;
- struct disklabel lp, *lpp;
int error;
unit = DISKUNIT(dev);
@@ -415,9 +407,8 @@ rdioctl(dev, cmd, data, flag, proc)
if (sc->sc_type == RD_UNCONFIGURED) {
break;
}
- lpp = rdgetdisklabel(dev, sc);
- if (lpp)
- *(struct disklabel *)data = *lpp;
+ rdgetdisklabel(sc);
+ bcopy(sc->sc_dkdev.dk_label, data, sizeof(struct disklabel));
return 0;
case DIOCWDINFO:
@@ -428,12 +419,14 @@ rdioctl(dev, cmd, data, flag, proc)
if ((flag & FWRITE) == 0)
return EBADF;
- error = setdisklabel(&lp, (struct disklabel *)data,
- /*sd->sc_dk.dk_openmask : */0, &clp);
+ error = setdisklabel(sc->sc_dkdev.dk_label,
+ (struct disklabel *)data, /*sd->sc_dk.dk_openmask : */0,
+ sc->sc_dkdev.dk_cpulabel);
if (error == 0) {
if (cmd == DIOCWDINFO)
error = writedisklabel(DISKLABELDEV(dev),
- rdstrategy, &lp, &clp);
+ rdstrategy, sc->sc_dkdev.dk_label,
+ sc->sc_dkdev.dk_cpulabel);
}
return error;
@@ -478,25 +471,21 @@ rdioctl(dev, cmd, data, flag, proc)
return EINVAL;
}
-struct disklabel *
-rdgetdisklabel(dev, sc)
- dev_t dev;
- struct rd_softc *sc;
+void
+rdgetdisklabel(struct rd_softc *sc)
{
- static struct disklabel lp;
- struct cpu_disklabel clp;
- char *errstring;
-
- bzero(&lp, sizeof(struct disklabel));
- bzero(&clp, sizeof(struct cpu_disklabel));
-
- lp.d_secsize = 1 << DEV_BSHIFT;
- lp.d_ntracks = 1;
- lp.d_nsectors = sc->sc_size >> DEV_BSHIFT;
- lp.d_ncylinders = 1;
- lp.d_secpercyl = lp.d_nsectors;
- if (lp.d_secpercyl == 0) {
- lp.d_secpercyl = 100;
+ struct disklabel *lp = sc->sc_dkdev.dk_label;
+
+ bzero(sc->sc_dkdev.dk_label, sizeof(struct disklabel));
+ bzero(sc->sc_dkdev.dk_cpulabel, sizeof(struct cpu_disklabel));
+
+ lp->d_secsize = 1 << DEV_BSHIFT;
+ lp->d_ntracks = 1;
+ lp->d_nsectors = sc->sc_size >> DEV_BSHIFT;
+ lp->d_ncylinders = 1;
+ lp->d_secpercyl = lp->d_nsectors;
+ if (lp->d_secpercyl == 0) {
+ lp->d_secpercyl = 100;
/* as long as it's not 0 - readdisklabel divides by it (?) */
}
@@ -506,7 +495,7 @@ rdgetdisklabel(dev, sc)
lp.d_secperunit = lp.d_nsectors;
lp.d_rpm = 3600;
lp.d_interleave = 1;
- lp.d_flags = 0;
+ lp.d_flags = D_RAMDISK;
lp.d_partitions[RAW_PART].p_offset = 0;
lp.d_partitions[RAW_PART].p_size =
@@ -521,12 +510,8 @@ rdgetdisklabel(dev, sc)
/*
* Call the generic disklabel extraction routine
*/
- errstring = readdisklabel(DISKLABELDEV(dev), rdstrategy, &lp, &clp, 0);
- if (errstring) {
- /*printf("%s: %s\n", sc->sc_dev.dv_xname, errstring);*/
- return NULL;
- }
- return &lp;
+ readdisklabel(DISKLABELDEV(sc->sc_dev.dv_unit), rdstrategy,
+ sc->sc_dkdev.dk_label, sc->sc_dkdev.dk_cpulabel, 0);
}
/*