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

Commit c9efe511 authored by Al Viro's avatar Al Viro
Browse files

fix a kmap leak in virtio_console



While we are at it, don't do kmap() under kmap_atomic(), *especially*
for a page we'd allocated with GFP_KERNEL.  It's spelled "page_address",
and had that been more than that, we'd have a real trouble - kmap_high()
can block, and doing that while holding kmap_atomic() is a Bad Idea(tm).

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d311d79d
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -890,12 +890,10 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
	} else {
		/* Failback to copying a page */
		struct page *page = alloc_page(GFP_KERNEL);
		char *src = buf->ops->map(pipe, buf, 1);
		char *dst;
		char *src;

		if (!page)
			return -ENOMEM;
		dst = kmap(page);

		offset = sd->pos & ~PAGE_MASK;

@@ -903,9 +901,8 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
		if (len + offset > PAGE_SIZE)
			len = PAGE_SIZE - offset;

		memcpy(dst + offset, src + buf->offset, len);

		kunmap(page);
		src = buf->ops->map(pipe, buf, 1);
		memcpy(page_address(page) + offset, src + buf->offset, len);
		buf->ops->unmap(pipe, buf, src);

		sg_set_page(&(sgl->sg[sgl->n]), page, len, offset);