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

Commit ca61e6bf authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "fuse: fix page dereference after free"

parents 0bf1f4df 11c6fc8b
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -854,15 +854,16 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
	struct page *newpage;
	struct pipe_buffer *buf = cs->pipebufs;

	get_page(oldpage);
	err = unlock_request(cs->req);
	if (err)
		return err;
		goto out_put_old;

	fuse_copy_finish(cs);

	err = pipe_buf_confirm(cs->pipe, buf);
	if (err)
		return err;
		goto out_put_old;

	BUG_ON(!cs->nr_segs);
	cs->currbuf = buf;
@@ -902,7 +903,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
	err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
	if (err) {
		unlock_page(newpage);
		return err;
		goto out_put_old;
	}

	get_page(newpage);
@@ -921,14 +922,19 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
	if (err) {
		unlock_page(newpage);
		put_page(newpage);
		return err;
		goto out_put_old;
	}

	unlock_page(oldpage);
	/* Drop ref for ap->pages[] array */
	put_page(oldpage);
	cs->len = 0;

	return 0;
	err = 0;
out_put_old:
	/* Drop ref obtained in this function */
	put_page(oldpage);
	return err;

out_fallback_unlock:
	unlock_page(newpage);
@@ -937,10 +943,10 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
	cs->offset = buf->offset;

	err = lock_request(cs->req);
	if (err)
		return err;
	if (!err)
		err = 1;

	return 1;
	goto out_put_old;
}

static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
@@ -952,14 +958,16 @@ static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
	if (cs->nr_segs == cs->pipe->buffers)
		return -EIO;

	get_page(page);
	err = unlock_request(cs->req);
	if (err)
	if (err) {
		put_page(page);
		return err;
	}

	fuse_copy_finish(cs);

	buf = cs->pipebufs;
	get_page(page);
	buf->page = page;
	buf->offset = offset;
	buf->len = count;