Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7f397dcdb78d699a20d96bfcfb595a2411a5bbd2 Commit: 7f397dcdb78d699a20d96bfcfb595a2411a5bbd2 Parent: 602b6aeefe8932dd8bb15014e8fe6bb25d736361 Author: Matt Mackall <[EMAIL PROTECTED]> AuthorDate: Tue May 29 21:58:10 2007 -0500 Committer: Linus Torvalds <[EMAIL PROTECTED]> CommitDate: Tue May 29 20:09:34 2007 -0700
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 <[EMAIL PROTECTED]> Acked-by: "Theodore Ts'o" <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> --- drivers/char/random.c | 55 +++++++++++++++++++++++++++--------------------- 1 files changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 9705b43..0474cac 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1020,37 +1020,44 @@ random_poll(struct file *file, poll_table * wait) 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_path.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_path.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 @@ -1089,8 +1096,8 @@ random_ioctl(struct inode * inode, struct file * file, 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); - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html