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

Commit 30800d99 authored by Kees Cook's avatar Kees Cook
Browse files

pstore: simplify write_user_compat()



Nothing actually uses write_user_compat() currently, but there is no
reason to reuse the dmesg buffer. Instead, just allocate a new record
buffer, copy in from userspace, and pass it to write() as normal.

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent 4c9ec219
Loading
Loading
Loading
Loading
+20 −26
Original line number Diff line number Diff line
@@ -635,33 +635,27 @@ static void pstore_unregister_console(void) {}
static int pstore_write_user_compat(struct pstore_record *record,
				    const char __user *buf)
{
	unsigned long flags = 0;
	size_t i, bufsize, total_size = record->size;
	long ret = 0;

	if (unlikely(!access_ok(VERIFY_READ, buf, total_size)))
		return -EFAULT;
	bufsize = total_size;
	if (bufsize > psinfo->bufsize)
		bufsize = psinfo->bufsize;
	record->buf = psinfo->buf;
	spin_lock_irqsave(&psinfo->buf_lock, flags);
	for (i = 0; i < total_size; ) {
		size_t c = min(total_size - i, bufsize);
	int ret = 0;

	if (record->buf)
		return -EINVAL;

		ret = __copy_from_user(record->buf, buf + i, c);
		if (unlikely(ret != 0)) {
	record->buf = kmalloc(record->size, GFP_KERNEL);
	if (!record->buf)
		return -ENOMEM;

	if (unlikely(copy_from_user(record->buf, buf, record->size))) {
		ret = -EFAULT;
			break;
		goto out;
	}
		record->size = c;

	ret = record->psi->write(record);
		if (unlikely(ret < 0))
			break;
		i += c;
	}
	spin_unlock_irqrestore(&psinfo->buf_lock, flags);
	return unlikely(ret < 0) ? ret : total_size;

out:
	kfree(record->buf);
	record->buf = NULL;

	return unlikely(ret < 0) ? ret : record->size;
}

/*