svn commit: r324394 - in head/sys: dev/random sys

Conrad Meyer cem at FreeBSD.org
Sat Oct 7 19:02:05 UTC 2017


Author: cem
Date: Sat Oct  7 19:02:03 2017
New Revision: 324394
URL: https://svnweb.freebsd.org/changeset/base/324394

Log:
  random(4): Gather entropy from Pure sources
  
  At initialization, hc_source_mask only includes non-Pure sources.
  
  The patch changes source registration to enable the registered source in the
  hc_source_mask bitmask. This mask governs which sources are harvested.
  
  This patch also disallows userspace from disabling such sources.
  
  PR:		222807
  Submitted by:	W. Dean Freeman <badfilemagic AT gmail.com>
  Reviewed by:	jmg (earlier version), delphij
  Approved by:	secteam (delphij)
  Obtained from:	HBSD 0054e3e170e083811acc9f3b637f8be8a86c03e7
  Security:	yes
  Differential Revision:	https://reviews.freebsd.org/D12611

Modified:
  head/sys/dev/random/random_harvestq.c
  head/sys/dev/random/randomdev.c
  head/sys/sys/random.h

Modified: head/sys/dev/random/random_harvestq.c
==============================================================================
--- head/sys/dev/random/random_harvestq.c	Sat Oct  7 18:59:29 2017	(r324393)
+++ head/sys/dev/random/random_harvestq.c	Sat Oct  7 19:02:03 2017	(r324394)
@@ -1,4 +1,6 @@
 /*-
+ * Copyright (c) 2017 Oliver Pinter
+ * Copyright (c) 2017 W. Dean Freeman
  * Copyright (c) 2000-2015 Mark R V Murray
  * Copyright (c) 2013 Arthur Mesh
  * Copyright (c) 2004 Robert N. M. Watson
@@ -240,8 +242,28 @@ read_rate_increment(u_int chunk)
 }
 
 /* ARGSUSED */
-RANDOM_CHECK_UINT(harvestmask, 0, RANDOM_HARVEST_EVERYTHING_MASK);
+static int
+random_check_uint_harvestmask(SYSCTL_HANDLER_ARGS)
+{
+	int error;
+	u_int value, orig_value;
 
+	orig_value = value = harvest_context.hc_source_mask;
+	error = sysctl_handle_int(oidp, &value, 0, req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (flsl(value) > ENTROPYSOURCE)
+		return (EINVAL);
+
+	/*
+	 * Disallow userspace modification of pure entropy sources.
+	 */
+	harvest_context.hc_source_mask = (value & ~RANDOM_HARVEST_PURE_MASK) |
+	    (orig_value & RANDOM_HARVEST_PURE_MASK);
+	return (0);
+}
+
 /* ARGSUSED */
 static int
 random_print_harvestmask(SYSCTL_HANDLER_ARGS)
@@ -252,7 +274,7 @@ random_print_harvestmask(SYSCTL_HANDLER_ARGS)
 	error = sysctl_wire_old_buffer(req, 0);
 	if (error == 0) {
 		sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
-		for (i = RANDOM_ENVIRONMENTAL_END; i >= 0; i--)
+		for (i = ENTROPYSOURCE - 1; i >= 0; i--)
 			sbuf_cat(&sbuf, (harvest_context.hc_source_mask & (1 << i)) ? "1" : "0");
 		error = sbuf_finish(&sbuf);
 		sbuf_delete(&sbuf);
@@ -272,7 +294,7 @@ static const char *random_source_descr[ENTROPYSOURCE] 
 	[RANDOM_SWI] = "SWI",
 	[RANDOM_FS_ATIME] = "FS_ATIME",
 	[RANDOM_UMA] = "UMA", /* ENVIRONMENTAL_END */
-	[RANDOM_PURE_OCTEON] = "PURE_OCTEON",
+	[RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */
 	[RANDOM_PURE_SAFE] = "PURE_SAFE",
 	[RANDOM_PURE_GLXSB] = "PURE_GLXSB",
 	[RANDOM_PURE_UBSEC] = "PURE_UBSEC",
@@ -291,15 +313,22 @@ random_print_harvestmask_symbolic(SYSCTL_HANDLER_ARGS)
 {
 	struct sbuf sbuf;
 	int error, i;
+	bool first;
 
+	first = true;
 	error = sysctl_wire_old_buffer(req, 0);
 	if (error == 0) {
 		sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
-		for (i = RANDOM_ENVIRONMENTAL_END; i >= 0; i--) {
-			sbuf_cat(&sbuf, (i == RANDOM_ENVIRONMENTAL_END) ? "" : ",");
+		for (i = ENTROPYSOURCE - 1; i >= 0; i--) {
+			if (i >= RANDOM_PURE_START &&
+			    (harvest_context.hc_source_mask & (1 << i)) == 0)
+				continue;
+			if (!first)
+				sbuf_cat(&sbuf, ",");
 			sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "[" : "");
 			sbuf_cat(&sbuf, random_source_descr[i]);
 			sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "]" : "");
+			first = false;
 		}
 		error = sbuf_finish(&sbuf);
 		sbuf_delete(&sbuf);
@@ -321,8 +350,7 @@ random_harvestq_init(void *unused __unused)
 	SYSCTL_ADD_PROC(&random_clist,
 	    SYSCTL_CHILDREN(random_sys_o),
 	    OID_AUTO, "mask", CTLTYPE_UINT | CTLFLAG_RW,
-	    &harvest_context.hc_source_mask, 0,
-	    random_check_uint_harvestmask, "IU",
+	    NULL, 0, random_check_uint_harvestmask, "IU",
 	    "Entropy harvesting mask");
 	SYSCTL_ADD_PROC(&random_clist,
 	    SYSCTL_CHILDREN(random_sys_o),
@@ -493,6 +521,20 @@ random_harvest_direct(const void *entropy, u_int size,
 	memcpy(event.he_entropy, entropy, size);
 	random_harvestq_fast_process_event(&event);
 	explicit_bzero(&event, sizeof(event));
+}
+
+void
+random_harvest_register_source(enum random_entropy_source source)
+{
+
+	harvest_context.hc_source_mask |= (1 << source);
+}
+
+void
+random_harvest_deregister_source(enum random_entropy_source source)
+{
+
+	harvest_context.hc_source_mask &= ~(1 << source);
 }
 
 MODULE_VERSION(random_harvestq, 1);

Modified: head/sys/dev/random/randomdev.c
==============================================================================
--- head/sys/dev/random/randomdev.c	Sat Oct  7 18:59:29 2017	(r324393)
+++ head/sys/dev/random/randomdev.c	Sat Oct  7 19:02:03 2017	(r324394)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2017 Oliver Pinter
  * Copyright (c) 2000-2015 Mark R V Murray
  * All rights reserved.
  *
@@ -321,6 +322,8 @@ random_source_register(struct random_source *rsource)
 	rrs = malloc(sizeof(*rrs), M_ENTROPY, M_WAITOK);
 	rrs->rrs_source = rsource;
 
+	random_harvest_register_source(rsource->rs_source);
+
 	printf("random: registering fast source %s\n", rsource->rs_ident);
 	LIST_INSERT_HEAD(&source_list, rrs, rrs_entries);
 }
@@ -331,6 +334,9 @@ random_source_deregister(struct random_source *rsource
 	struct random_sources *rrs = NULL;
 
 	KASSERT(rsource != NULL, ("invalid input to %s", __func__));
+
+	random_harvest_deregister_source(rsource->rs_source);
+
 	LIST_FOREACH(rrs, &source_list, rrs_entries)
 		if (rrs->rrs_source == rsource) {
 			LIST_REMOVE(rrs, rrs_entries);

Modified: head/sys/sys/random.h
==============================================================================
--- head/sys/sys/random.h	Sat Oct  7 18:59:29 2017	(r324393)
+++ head/sys/sys/random.h	Sat Oct  7 19:02:03 2017	(r324394)
@@ -81,7 +81,8 @@ enum random_entropy_source {
 	RANDOM_UMA,	/* Special!! UMA/SLAB Allocator */
 	RANDOM_ENVIRONMENTAL_END = RANDOM_UMA,
 	/* Fast hardware random-number sources from here on. */
-	RANDOM_PURE_OCTEON,
+	RANDOM_PURE_START,
+	RANDOM_PURE_OCTEON = RANDOM_PURE_START,
 	RANDOM_PURE_SAFE,
 	RANDOM_PURE_GLXSB,
 	RANDOM_PURE_UBSEC,
@@ -95,6 +96,7 @@ enum random_entropy_source {
 };
 
 #define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1)
+#define RANDOM_HARVEST_PURE_MASK (((1 << ENTROPYSOURCE) - 1) & (-1UL << RANDOM_PURE_START))
 
 #define RANDOM_LEGACY_BOOT_ENTROPY_MODULE	"/boot/entropy"
 #define RANDOM_CACHED_BOOT_ENTROPY_MODULE	"boot_entropy_cache"
@@ -104,10 +106,14 @@ enum random_entropy_source {
 void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source);
 void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source);
 void random_harvest_direct(const void *, u_int, u_int, enum random_entropy_source);
+void random_harvest_register_source(enum random_entropy_source);
+void random_harvest_deregister_source(enum random_entropy_source);
 #else
 #define random_harvest_queue(a, b, c, d) do {} while (0)
 #define random_harvest_fast(a, b, c, d) do {} while (0)
 #define random_harvest_direct(a, b, c, d) do {} while (0)
+#define random_harvest_register_source(a) do {} while (0)
+#define random_harvest_deregister_source(a) do {} while (0)
 #endif
 
 #if defined(RANDOM_ENABLE_UMA)


More information about the svn-src-head mailing list