aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Evans <bde@FreeBSD.org>1998-06-21 11:33:32 +0000
committerBruce Evans <bde@FreeBSD.org>1998-06-21 11:33:32 +0000
commit316bbd5c6f7d1a4d82e6e46b63ba8cc24d5df402 (patch)
treeb3e91bd083b64d20356c2e2f0954393f132f6d12
parent8901e749027d19c630e400ab9a5181307e5d0a2a (diff)
downloadsrc-316bbd5c6f7d1a4d82e6e46b63ba8cc24d5df402.tar.gz
src-316bbd5c6f7d1a4d82e6e46b63ba8cc24d5df402.zip
Converted add_interrupt_randomness() to take a `void *' arg. Rewrote
mmioctl() to fix hundreds of style bugs and a few error handling bugs (don't check for superuser privilege for inappropriate ioctls, don't check the input arg for the output-only MEM_RETURNIRQ ioctl, and don't return EPERM for null changes).
Notes
Notes: svn path=/head/; revision=37086
-rw-r--r--sys/amd64/amd64/mem.c115
-rw-r--r--sys/i386/i386/mem.c115
-rw-r--r--sys/i386/include/random.h13
-rw-r--r--sys/i386/isa/random_machdep.c16
-rw-r--r--sys/kern/kern_random.c16
-rw-r--r--sys/sys/random.h13
6 files changed, 152 insertions, 136 deletions
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c
index 8db7d3ce02a0..d26b9ee5ebf5 100644
--- a/sys/amd64/amd64/mem.c
+++ b/sys/amd64/amd64/mem.c
@@ -38,7 +38,7 @@
*
* from: Utah $Hdr: mem.c 1.13 89/10/08$
* from: @(#)mem.c 7.2 (Berkeley) 5/9/91
- * $Id: mem.c,v 1.50 1998/03/12 09:14:18 bde Exp $
+ * $Id: mem.c,v 1.51 1998/06/07 17:10:02 dfr Exp $
*/
/*
@@ -88,6 +88,7 @@ static struct cdevsw mem_cdevsw =
mmioctl, nullstop, nullreset, nodevtotty,/* memory */
mmpoll, memmmap, NULL, "mem", NULL, -1 };
+static struct random_softc random_softc[16];
static caddr_t zbuf;
#ifdef DEVFS
@@ -398,83 +399,85 @@ memmmap(dev_t dev, int offset, int nprot)
}
}
-/*
- * Allow userland to select which interrupts will be used in the muck
- * gathering business.
- */
static int
-mmioctl(dev, cmd, cmdarg, flags, p)
+mmioctl(dev, cmd, data, flags, p)
dev_t dev;
u_long cmd;
- caddr_t cmdarg;
+ caddr_t data;
int flags;
struct proc *p;
{
- static u_int16_t interrupt_allowed = 0;
- u_int16_t interrupt_mask;
- int error;
+ static intrmask_t interrupt_allowed;
+ intrmask_t interrupt_mask;
+ int error, intr;
+ struct random_softc *sc;
- switch(minor(dev)) {
+ switch (minor(dev)) {
case 3:
case 4:
break;
-
#ifdef PERFMON
case 32:
- return perfmon_ioctl(dev, cmd, cmdarg, flags, p);
+ return perfmon_ioctl(dev, cmd, data, flags, p);
#endif
default:
- return ENODEV;
+ return (ENODEV);
}
- if (*(u_int16_t *)cmdarg >= 16)
- return (EINVAL);
-
- /* Only root can do this */
+ /*
+ * We're the random or urandom device. The only ioctls are for
+ * selecting and inspecting which interrupts are used in the muck
+ * gathering business.
+ */
+ if (cmd != MEM_SETIRQ && cmd != MEM_CLEARIRQ && cmd != MEM_RETURNIRQ)
+ return (ENOTTY);
+
+ /*
+ * Even inspecting the state is privileged, since it gives a hint
+ * about how easily the randomness might be guessed.
+ */
error = suser(p->p_ucred, &p->p_acflag);
- if (error) {
+ if (error != 0)
return (error);
- }
- interrupt_mask = 1 << *(u_int16_t *)cmdarg;
- switch (cmd) {
-
- case MEM_SETIRQ:
- if (!(interrupt_allowed & interrupt_mask)) {
- disable_intr();
- interrupt_allowed |= interrupt_mask;
- sec_intr_handler[*(u_int16_t *)cmdarg] =
- intr_handler[*(u_int16_t *)cmdarg];
- intr_handler[*(u_int16_t *)cmdarg] =
- add_interrupt_randomness;
- sec_intr_unit[*(u_int16_t *)cmdarg] =
- intr_unit[*(u_int16_t *)cmdarg];
- intr_unit[*(u_int16_t *)cmdarg] =
- *(u_int16_t *)cmdarg;
- enable_intr();
- }
- else return (EPERM);
- break;
+ /*
+ * XXX the data is 16-bit due to a historical botch, so we use
+ * magic 16's instead of ICU_LEN and can't support 24 interrupts
+ * under SMP.
+ */
+ intr = *(int16_t *)data;
+ if (cmd != MEM_RETURNIRQ && (intr < 0 || intr >= 16))
+ return (EINVAL);
- case MEM_CLEARIRQ:
- if (interrupt_allowed & interrupt_mask) {
- disable_intr();
- interrupt_allowed &= ~(interrupt_mask);
- intr_handler[*(u_int16_t *)cmdarg] =
- sec_intr_handler[*(u_int16_t *)cmdarg];
- intr_unit[*(u_int16_t *)cmdarg] =
- sec_intr_unit[*(u_int16_t *)cmdarg];
- enable_intr();
- }
- else return (EPERM);
+ interrupt_mask = 1 << intr;
+ sc = &random_softc[intr];
+ switch (cmd) {
+ case MEM_SETIRQ:
+ if (interrupt_allowed & interrupt_mask)
break;
-
- case MEM_RETURNIRQ:
- *(u_int16_t *)cmdarg = interrupt_allowed;
+ interrupt_allowed |= interrupt_mask;
+ sc->sc_intr = intr;
+ disable_intr();
+ sc->sc_handler = intr_handler[intr];
+ intr_handler[intr] = add_interrupt_randomness;
+ sc->sc_arg = intr_unit[intr];
+ intr_unit[intr] = sc;
+ enable_intr();
+ break;
+ case MEM_CLEARIRQ:
+ if (!(interrupt_allowed & interrupt_mask))
break;
-
- default:
- return (ENOTTY);
+ interrupt_allowed &= ~interrupt_mask;
+ disable_intr();
+ intr_handler[intr] = sc->sc_handler;
+ intr_unit[intr] = sc->sc_arg;
+ enable_intr();
+ break;
+ case MEM_RETURNIRQ:
+ *(u_int16_t *)data = interrupt_allowed;
+ break;
+ default:
+ return (ENOTTY);
}
return (0);
}
diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c
index 8db7d3ce02a0..d26b9ee5ebf5 100644
--- a/sys/i386/i386/mem.c
+++ b/sys/i386/i386/mem.c
@@ -38,7 +38,7 @@
*
* from: Utah $Hdr: mem.c 1.13 89/10/08$
* from: @(#)mem.c 7.2 (Berkeley) 5/9/91
- * $Id: mem.c,v 1.50 1998/03/12 09:14:18 bde Exp $
+ * $Id: mem.c,v 1.51 1998/06/07 17:10:02 dfr Exp $
*/
/*
@@ -88,6 +88,7 @@ static struct cdevsw mem_cdevsw =
mmioctl, nullstop, nullreset, nodevtotty,/* memory */
mmpoll, memmmap, NULL, "mem", NULL, -1 };
+static struct random_softc random_softc[16];
static caddr_t zbuf;
#ifdef DEVFS
@@ -398,83 +399,85 @@ memmmap(dev_t dev, int offset, int nprot)
}
}
-/*
- * Allow userland to select which interrupts will be used in the muck
- * gathering business.
- */
static int
-mmioctl(dev, cmd, cmdarg, flags, p)
+mmioctl(dev, cmd, data, flags, p)
dev_t dev;
u_long cmd;
- caddr_t cmdarg;
+ caddr_t data;
int flags;
struct proc *p;
{
- static u_int16_t interrupt_allowed = 0;
- u_int16_t interrupt_mask;
- int error;
+ static intrmask_t interrupt_allowed;
+ intrmask_t interrupt_mask;
+ int error, intr;
+ struct random_softc *sc;
- switch(minor(dev)) {
+ switch (minor(dev)) {
case 3:
case 4:
break;
-
#ifdef PERFMON
case 32:
- return perfmon_ioctl(dev, cmd, cmdarg, flags, p);
+ return perfmon_ioctl(dev, cmd, data, flags, p);
#endif
default:
- return ENODEV;
+ return (ENODEV);
}
- if (*(u_int16_t *)cmdarg >= 16)
- return (EINVAL);
-
- /* Only root can do this */
+ /*
+ * We're the random or urandom device. The only ioctls are for
+ * selecting and inspecting which interrupts are used in the muck
+ * gathering business.
+ */
+ if (cmd != MEM_SETIRQ && cmd != MEM_CLEARIRQ && cmd != MEM_RETURNIRQ)
+ return (ENOTTY);
+
+ /*
+ * Even inspecting the state is privileged, since it gives a hint
+ * about how easily the randomness might be guessed.
+ */
error = suser(p->p_ucred, &p->p_acflag);
- if (error) {
+ if (error != 0)
return (error);
- }
- interrupt_mask = 1 << *(u_int16_t *)cmdarg;
- switch (cmd) {
-
- case MEM_SETIRQ:
- if (!(interrupt_allowed & interrupt_mask)) {
- disable_intr();
- interrupt_allowed |= interrupt_mask;
- sec_intr_handler[*(u_int16_t *)cmdarg] =
- intr_handler[*(u_int16_t *)cmdarg];
- intr_handler[*(u_int16_t *)cmdarg] =
- add_interrupt_randomness;
- sec_intr_unit[*(u_int16_t *)cmdarg] =
- intr_unit[*(u_int16_t *)cmdarg];
- intr_unit[*(u_int16_t *)cmdarg] =
- *(u_int16_t *)cmdarg;
- enable_intr();
- }
- else return (EPERM);
- break;
+ /*
+ * XXX the data is 16-bit due to a historical botch, so we use
+ * magic 16's instead of ICU_LEN and can't support 24 interrupts
+ * under SMP.
+ */
+ intr = *(int16_t *)data;
+ if (cmd != MEM_RETURNIRQ && (intr < 0 || intr >= 16))
+ return (EINVAL);
- case MEM_CLEARIRQ:
- if (interrupt_allowed & interrupt_mask) {
- disable_intr();
- interrupt_allowed &= ~(interrupt_mask);
- intr_handler[*(u_int16_t *)cmdarg] =
- sec_intr_handler[*(u_int16_t *)cmdarg];
- intr_unit[*(u_int16_t *)cmdarg] =
- sec_intr_unit[*(u_int16_t *)cmdarg];
- enable_intr();
- }
- else return (EPERM);
+ interrupt_mask = 1 << intr;
+ sc = &random_softc[intr];
+ switch (cmd) {
+ case MEM_SETIRQ:
+ if (interrupt_allowed & interrupt_mask)
break;
-
- case MEM_RETURNIRQ:
- *(u_int16_t *)cmdarg = interrupt_allowed;
+ interrupt_allowed |= interrupt_mask;
+ sc->sc_intr = intr;
+ disable_intr();
+ sc->sc_handler = intr_handler[intr];
+ intr_handler[intr] = add_interrupt_randomness;
+ sc->sc_arg = intr_unit[intr];
+ intr_unit[intr] = sc;
+ enable_intr();
+ break;
+ case MEM_CLEARIRQ:
+ if (!(interrupt_allowed & interrupt_mask))
break;
-
- default:
- return (ENOTTY);
+ interrupt_allowed &= ~interrupt_mask;
+ disable_intr();
+ intr_handler[intr] = sc->sc_handler;
+ intr_unit[intr] = sc->sc_arg;
+ enable_intr();
+ break;
+ case MEM_RETURNIRQ:
+ *(u_int16_t *)data = interrupt_allowed;
+ break;
+ default:
+ return (ENOTTY);
}
return (0);
}
diff --git a/sys/i386/include/random.h b/sys/i386/include/random.h
index 9c4850a37db1..569173a1a6a2 100644
--- a/sys/i386/include/random.h
+++ b/sys/i386/include/random.h
@@ -1,7 +1,7 @@
/*
* random.h -- A strong random number generator
*
- * $Id: random.h,v 1.14 1998/04/06 09:30:18 phk Exp $
+ * $Id: random.h,v 1.15 1998/06/18 15:32:05 bde Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -58,16 +58,19 @@
#ifdef KERNEL
-/* Interrupts to be used in the randomizing process */
+/* Type of the cookie passed to add_interrupt_randomness. */
-extern inthand2_t *sec_intr_handler[];
-extern void *sec_intr_unit[];
+struct random_softc {
+ inthand2_t *sc_handler;
+ void *sc_arg;
+ int sc_intr;
+};
/* Exported functions */
void rand_initialize(void);
void add_keyboard_randomness(u_char scancode);
-void add_interrupt_randomness(int irq);
+inthand2_t add_interrupt_randomness;
#ifdef notused
void add_blkdev_randomness(int major);
#endif
diff --git a/sys/i386/isa/random_machdep.c b/sys/i386/isa/random_machdep.c
index 9f2e610c7ed2..d6356681f208 100644
--- a/sys/i386/isa/random_machdep.c
+++ b/sys/i386/isa/random_machdep.c
@@ -1,7 +1,7 @@
/*
* random_machdep.c -- A strong random number generator
*
- * $Id: random_machdep.c,v 1.27 1998/06/09 13:10:46 phk Exp $
+ * $Id: random_machdep.c,v 1.28 1998/06/18 15:32:07 bde Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -49,6 +49,7 @@
#include <machine/random.h>
#include <i386/isa/icu.h>
+#include <i386/isa/intr_machdep.h>
#define MAX_BLKDEV 4
@@ -104,9 +105,6 @@ static struct timer_rand_state blkdev_timer_state[MAX_BLKDEV];
#endif
static struct wait_queue *random_wait;
-inthand2_t *sec_intr_handler[ICU_LEN];
-void *sec_intr_unit[ICU_LEN];
-
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
@@ -226,10 +224,14 @@ add_keyboard_randomness(u_char scancode)
}
void
-add_interrupt_randomness(int irq)
+add_interrupt_randomness(void *vsc)
{
- (sec_intr_handler[irq])(sec_intr_unit[irq]);
- add_timer_randomness(&random_state, &irq_timer_state[irq], irq);
+ int intr;
+ struct random_softc *sc = vsc;
+
+ (sc->sc_handler)(sc->sc_arg);
+ intr = sc->sc_intr;
+ add_timer_randomness(&random_state, &irq_timer_state[intr], intr);
}
#ifdef notused
diff --git a/sys/kern/kern_random.c b/sys/kern/kern_random.c
index 9f2e610c7ed2..d6356681f208 100644
--- a/sys/kern/kern_random.c
+++ b/sys/kern/kern_random.c
@@ -1,7 +1,7 @@
/*
* random_machdep.c -- A strong random number generator
*
- * $Id: random_machdep.c,v 1.27 1998/06/09 13:10:46 phk Exp $
+ * $Id: random_machdep.c,v 1.28 1998/06/18 15:32:07 bde Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -49,6 +49,7 @@
#include <machine/random.h>
#include <i386/isa/icu.h>
+#include <i386/isa/intr_machdep.h>
#define MAX_BLKDEV 4
@@ -104,9 +105,6 @@ static struct timer_rand_state blkdev_timer_state[MAX_BLKDEV];
#endif
static struct wait_queue *random_wait;
-inthand2_t *sec_intr_handler[ICU_LEN];
-void *sec_intr_unit[ICU_LEN];
-
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
@@ -226,10 +224,14 @@ add_keyboard_randomness(u_char scancode)
}
void
-add_interrupt_randomness(int irq)
+add_interrupt_randomness(void *vsc)
{
- (sec_intr_handler[irq])(sec_intr_unit[irq]);
- add_timer_randomness(&random_state, &irq_timer_state[irq], irq);
+ int intr;
+ struct random_softc *sc = vsc;
+
+ (sc->sc_handler)(sc->sc_arg);
+ intr = sc->sc_intr;
+ add_timer_randomness(&random_state, &irq_timer_state[intr], intr);
}
#ifdef notused
diff --git a/sys/sys/random.h b/sys/sys/random.h
index 9c4850a37db1..569173a1a6a2 100644
--- a/sys/sys/random.h
+++ b/sys/sys/random.h
@@ -1,7 +1,7 @@
/*
* random.h -- A strong random number generator
*
- * $Id: random.h,v 1.14 1998/04/06 09:30:18 phk Exp $
+ * $Id: random.h,v 1.15 1998/06/18 15:32:05 bde Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -58,16 +58,19 @@
#ifdef KERNEL
-/* Interrupts to be used in the randomizing process */
+/* Type of the cookie passed to add_interrupt_randomness. */
-extern inthand2_t *sec_intr_handler[];
-extern void *sec_intr_unit[];
+struct random_softc {
+ inthand2_t *sc_handler;
+ void *sc_arg;
+ int sc_intr;
+};
/* Exported functions */
void rand_initialize(void);
void add_keyboard_randomness(u_char scancode);
-void add_interrupt_randomness(int irq);
+inthand2_t add_interrupt_randomness;
#ifdef notused
void add_blkdev_randomness(int major);
#endif