Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Nov 1999 01:24:20 -0500
From:      Dan Moschuk <dan@freebsd.org>
To:        freebsd-audit@freebsd.org
Subject:   Last random PID patch before commit
Message-ID:  <19991128012420.A48334@spirit.jaded.net>

next in thread | raw e-mail | index | archive | help

Here's the last functionality change before I commit this.  I doubt that using
random() to generate the key used to shuffle the ARC4 algorithm is the 
absolute best way of doing it, but, It Works(tm).  The other option I looked
at was read_random(),  but I'm not 100% certain that it will have built up
sufficient entropy by the time the code is called (usually at bootup).

At any rate...


Index: i386/conf/files.i386
===================================================================
RCS file: /home/ncvs/src/sys/i386/conf/files.i386,v
retrieving revision 1.281
diff -u -r1.281 files.i386
--- files.i386	1999/11/25 20:45:45	1.281
+++ files.i386	1999/11/28 06:04:52
@@ -373,6 +373,7 @@
 isa/syscons_isa.c		optional	sc
 isa/vga_isa.c			optional	vga
 kern/subr_diskmbr.c		standard
+libkern/arc4random.c		standard
 libkern/bcd.c			standard
 libkern/divdi3.c		standard
 libkern/index.c			standard
Index: kern/kern_fork.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.69
diff -u -r1.69 kern_fork.c
--- kern_fork.c	1999/11/19 21:29:03	1.69
+++ kern_fork.c	1999/11/28 06:05:02
@@ -142,6 +142,9 @@
 int	nprocs = 1;		/* process 0 */
 static int nextpid = 0;
 
+static int randompid = 0;
+SYSCTL_INT(_kern, OID_AUTO, randompid, CTLFLAG_RW, &randompid, 0, "");
+
 int
 fork1(p1, flags, procp)
 	struct proc *p1;
@@ -262,8 +265,8 @@
 	 * restart somewhat above 0, as the low-numbered procs
 	 * tend to include daemons that don't exit.
 	 */
-	if (nextpid >= PID_MAX) {
-		nextpid = 100;
+	if (nextpid >= PID_MAX || randompid) {
+		nextpid = (randompid) ? arc4random() % PID_MAX : 100;
 		pidchecked = 0;
 	}
 	if (nextpid >= pidchecked) {
Index: libkern/arc4random.c
===================================================================
RCS file: arc4random.c
diff -N arc4random.c
--- /dev/null	Sat Nov 27 21:16:45 1999
+++ arc4random.c	Sat Nov 27 22:05:05 1999
@@ -0,0 +1,95 @@
+/*-
+ * THE BEER-WARE LICENSE
+ *
+ * <dan@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff.  If we meet some day, and you
+ * think this stuff is worth it, you can buy me a beer in return.
+ *
+ * Dan Moschuk
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/libkern.h>
+#include <sys/time.h>
+
+static u_int8_t arc4_i, arc4_j;
+static int arc4_initialized = 0;
+static u_int8_t arc4_sbox[256];
+
+static void arc4_init __P((void));
+static u_int8_t arc4_randbyte __P((void));
+static __inline void arc4_swap __P((u_int8_t *, u_int8_t *));
+
+static __inline void
+arc4_swap(a, b)
+	u_int8_t *a;
+	u_int8_t *b;
+{
+	u_int8_t c;
+
+	c = *a;
+	*a = *b;
+	*b = c;
+}	
+
+/*
+ * Initialize our S-box to its beginning defaults.
+ */
+static void
+arc4_init(void)
+{
+	struct timespec ts;
+	u_int8_t key[256];
+	int n;
+
+	for (n = 0; n < 256; n++)
+		arc4_sbox[n] = (u_int8_t) n;
+
+	nanotime(&ts);
+	srandom(ts.tv_sec ^ ts.tv_nsec);
+	for (n = 0; n < 256; n++)
+		key[n] = random() % 256;
+
+	arc4_i = arc4_j = 0;
+	for (n = 0; n < 256; n++)
+	{
+		arc4_j = (arc4_j + arc4_sbox[n] + key[n]);
+		arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
+	}
+	arc4_initialized = 1;
+}
+
+/*
+ * Generate a random byte.
+ */
+static u_int8_t
+arc4_randbyte(void)
+{
+	u_int8_t arc4_t;
+
+	arc4_i = (arc4_i + 1) % 256;
+	arc4_j = (arc4_j + arc4_sbox[arc4_i]) % 256;
+
+	arc4_swap(&arc4_sbox[arc4_i], &arc4_sbox[arc4_j]);
+
+	arc4_t = (arc4_sbox[arc4_i] + arc4_sbox[arc4_j]) % 256;
+	return arc4_sbox[arc4_t];
+}
+
+u_int32_t
+arc4random(void)
+{
+	u_int32_t ret;
+
+	/* Initialize array if needed. */
+	if (!arc4_initialized)
+		arc4_init();
+
+	ret = arc4_randbyte();
+	ret |= arc4_randbyte() << 8;
+	ret |= arc4_randbyte() << 16;
+	ret |= arc4_randbyte() << 24;
+
+	return ret;
+}
Index: sys/libkern.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/libkern.h,v
retrieving revision 1.18
diff -u -r1.18 libkern.h
--- libkern.h	1999/11/21 04:26:47	1.18
+++ libkern.h	1999/11/28 06:05:29
@@ -61,6 +61,7 @@
 static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); }
 
 /* Prototypes for non-quad routines. */
+u_int32_t arc4random __P((void));
 int	 bcmp __P((const void *, const void *, size_t));
 #ifndef HAVE_INLINE_FFS
 int	 ffs __P((int));
-- 
Dan Moschuk (TFreak!dan@freebsd.org)
"Cure for global warming: One giant heatsink and dual fans!"


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991128012420.A48334>