Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f397dcd authored by Matt Mackall's avatar Matt Mackall Committed by Linus Torvalds
Browse files

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: default avatarMatt Mackall <mpm@selenic.com>
Acked-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 602b6aee
Loading
Loading
Loading
Loading
+31 −24
Original line number Original line Diff line number Diff line
@@ -1020,37 +1020,44 @@ random_poll(struct file *file, poll_table * wait)
	return mask;
	return mask;
}
}


static ssize_t
static int
random_write(struct file * file, const char __user * buffer,
write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
	     size_t count, loff_t *ppos)
{
{
	int ret = 0;
	size_t bytes;
	size_t bytes;
	__u32 buf[16];
	__u32 buf[16];
	const char __user *p = buffer;
	const char __user *p = buffer;
	size_t c = count;


	while (c > 0) {
	while (count > 0) {
		bytes = min(c, sizeof(buf));
		bytes = min(count, sizeof(buf));
		if (copy_from_user(&buf, p, bytes))
			return -EFAULT;


		bytes -= copy_from_user(&buf, p, bytes);
		count -= bytes;
		if (!bytes) {
			ret = -EFAULT;
			break;
		}
		c -= bytes;
		p += bytes;
		p += bytes;


		add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
		add_entropy_words(r, buf, (bytes + 3) / 4);
	}
	}
	if (p == buffer) {

		return (ssize_t)ret;
	return 0;
	} else {
}

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;
	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);
	inode->i_mtime = current_fs_time(inode->i_sb);
	mark_inode_dirty(inode);
	mark_inode_dirty(inode);
		return (ssize_t)(p - buffer);
	return (ssize_t)count;
	}
}
}


static int
static int
@@ -1089,8 +1096,8 @@ random_ioctl(struct inode * inode, struct file * file,
			return -EINVAL;
			return -EINVAL;
		if (get_user(size, p++))
		if (get_user(size, p++))
			return -EFAULT;
			return -EFAULT;
		retval = random_write(file, (const char __user *) p,
		retval = write_pool(&input_pool, (const char __user *)p,
				      size, &file->f_pos);
				    size);
		if (retval < 0)
		if (retval < 0)
			return retval;
			return retval;
		credit_entropy_store(&input_pool, ent_count);
		credit_entropy_store(&input_pool, ent_count);