diff options
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.patch | 97 |
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); |