summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tags/2.6.18-12/30019_random-fix-seeding-with-zero-entropy.patch')
-rw-r--r--tags/2.6.18-12/30019_random-fix-seeding-with-zero-entropy.patch97
1 files changed, 97 insertions, 0 deletions
diff --git a/tags/2.6.18-12/30019_random-fix-seeding-with-zero-entropy.patch b/tags/2.6.18-12/30019_random-fix-seeding-with-zero-entropy.patch
new file mode 100644
index 0000000..b61a03e
--- /dev/null
+++ b/tags/2.6.18-12/30019_random-fix-seeding-with-zero-entropy.patch
@@ -0,0 +1,97 @@
+commit 7f397dcdb78d699a20d96bfcfb595a2411a5bbd2
+Author: Matt Mackall <mpm@selenic.com>
+Date: Tue May 29 21:58:10 2007 -0500
+
+ random: fix seeding with zero entropy
+
+ Add data from zero-entropy random_writes directly to output pools to
+ avoid accounting difficulties on machines without entropy sources.
+
+ Tested on lguest with all entropy sources disabled.
+
+ Signed-off-by: Matt Mackall <mpm@selenic.com>
+ Acked-by: "Theodore Ts'o" <tytso@mit.edu>
+ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+# Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+--- linux-source-2.6.18/drivers/char/random.c.orig 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/drivers/char/random.c 2007-07-12 23:57:12.000000000 -0600
+@@ -1017,37 +1017,44 @@ random_poll(struct file *file, poll_tabl
+ return mask;
+ }
+
+-static ssize_t
+-random_write(struct file * file, const char __user * buffer,
+- size_t count, loff_t *ppos)
++static int
++write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
+ {
+- int ret = 0;
+ size_t bytes;
+ __u32 buf[16];
+ const char __user *p = buffer;
+- size_t c = count;
+
+- while (c > 0) {
+- bytes = min(c, sizeof(buf));
++ while (count > 0) {
++ bytes = min(count, sizeof(buf));
++ if (copy_from_user(&buf, p, bytes))
++ return -EFAULT;
+
+- bytes -= copy_from_user(&buf, p, bytes);
+- if (!bytes) {
+- ret = -EFAULT;
+- break;
+- }
+- c -= bytes;
++ count -= bytes;
+ p += bytes;
+
+- add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
+- }
+- if (p == buffer) {
+- return (ssize_t)ret;
+- } else {
+- struct inode *inode = file->f_dentry->d_inode;
+- inode->i_mtime = current_fs_time(inode->i_sb);
+- mark_inode_dirty(inode);
+- return (ssize_t)(p - buffer);
++ add_entropy_words(r, buf, (bytes + 3) / 4);
+ }
++
++ return 0;
++}
++
++static ssize_t
++random_write(struct file * file, const char __user * buffer,
++ size_t count, loff_t *ppos)
++{
++ size_t ret;
++ struct inode *inode = file->f_dentry->d_inode;
++
++ ret = write_pool(&blocking_pool, buffer, count);
++ if (ret)
++ return ret;
++ ret = write_pool(&nonblocking_pool, buffer, count);
++ if (ret)
++ return ret;
++
++ inode->i_mtime = current_fs_time(inode->i_sb);
++ mark_inode_dirty(inode);
++ return (ssize_t)count;
+ }
+
+ static int
+@@ -1086,8 +1093,8 @@ random_ioctl(struct inode * inode, struc
+ return -EINVAL;
+ if (get_user(size, p++))
+ return -EFAULT;
+- retval = random_write(file, (const char __user *) p,
+- size, &file->f_pos);
++ retval = write_pool(&input_pool, (const char __user *)p,
++ size);
+ if (retval < 0)
+ return retval;
+ credit_entropy_store(&input_pool, ent_count);