Jelajahi Sumber

random: don't zap entropy count in rand_initialize()

The rand_initialize() function was being run fairly late in the kernel
boot sequence.  This was unfortunate, since it zero'ed the entropy
counters, thus throwing away credit that was accumulated earlier in
the boot sequence, and it also meant that initcall functions run
before rand_initialize were using a minimally initialized pool.

To fix this, fix init_std_data() to no longer zap the entropy counter;
it wasn't necessary, and move rand_initialize() to be an early
initcall.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Theodore Ts'o 11 tahun lalu
induk
melakukan
ae9ecd92dd
1 mengubah file dengan 9 tambahan dan 7 penghapusan
  1. 9 7
      drivers/char/random.c

+ 9 - 7
drivers/char/random.c

@@ -1228,14 +1228,11 @@ static void init_std_data(struct entropy_store *r)
 	ktime_t now = ktime_get_real();
 	ktime_t now = ktime_get_real();
 	unsigned long rv;
 	unsigned long rv;
 
 
-	r->entropy_count = 0;
-	r->entropy_total = 0;
-	r->last_data_init = 0;
 	r->last_pulled = jiffies;
 	r->last_pulled = jiffies;
 	mix_pool_bytes(r, &now, sizeof(now), NULL);
 	mix_pool_bytes(r, &now, sizeof(now), NULL);
 	for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
 	for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
 		if (!arch_get_random_long(&rv))
 		if (!arch_get_random_long(&rv))
-			break;
+			rv = random_get_entropy();
 		mix_pool_bytes(r, &rv, sizeof(rv), NULL);
 		mix_pool_bytes(r, &rv, sizeof(rv), NULL);
 	}
 	}
 	mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
 	mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
@@ -1258,7 +1255,7 @@ static int rand_initialize(void)
 	init_std_data(&nonblocking_pool);
 	init_std_data(&nonblocking_pool);
 	return 0;
 	return 0;
 }
 }
-module_init(rand_initialize);
+early_initcall(rand_initialize);
 
 
 #ifdef CONFIG_BLOCK
 #ifdef CONFIG_BLOCK
 void rand_initialize_disk(struct gendisk *disk)
 void rand_initialize_disk(struct gendisk *disk)
@@ -1433,10 +1430,15 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
 		return 0;
 		return 0;
 	case RNDZAPENTCNT:
 	case RNDZAPENTCNT:
 	case RNDCLEARPOOL:
 	case RNDCLEARPOOL:
-		/* Clear the entropy pool counters. */
+		/*
+		 * Clear the entropy pool counters. We no longer clear
+		 * the entropy pool, as that's silly.
+		 */
 		if (!capable(CAP_SYS_ADMIN))
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 			return -EPERM;
-		rand_initialize();
+		input_pool.entropy_count = 0;
+		nonblocking_pool.entropy_count = 0;
+		blocking_pool.entropy_count = 0;
 		return 0;
 		return 0;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;