summaryrefslogtreecommitdiff
path: root/fs/splice.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2019-04-05 14:02:10 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-04 09:15:18 +0200
commitc88a0aa7ace7eb10dca42be59f21e2cbd263575e (patch)
tree4f8e9d7d8c6065bbd9c84ff26ed3fab3a0b64853 /fs/splice.c
parent04198de24771f6aaf6374979db64403101d809df (diff)
fs: prevent page refcount overflow in pipe_buf_get
commit 15fab63e1e57be9fdb5eec1bbc5916e9825e9acb upstream. Change pipe_buf_get() to return a bool indicating whether it succeeded in raising the refcount of the page (if the thing in the pipe is a page). This removes another mechanism for overflowing the page refcount. All callers converted to handle a failure. Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Matthew Wilcox <willy@infradead.org> Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/splice.c b/fs/splice.c
index a598d444abe1..c84ac7e97e21 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1571,7 +1571,11 @@ retry:
* Get a reference to this pipe buffer,
* so we can copy the contents over.
*/
- pipe_buf_get(ipipe, ibuf);
+ if (!pipe_buf_get(ipipe, ibuf)) {
+ if (ret == 0)
+ ret = -EFAULT;
+ break;
+ }
*obuf = *ibuf;
/*
@@ -1645,7 +1649,11 @@ static int link_pipe(struct pipe_inode_info *ipipe,
* Get a reference to this pipe buffer,
* so we can copy the contents over.
*/
- pipe_buf_get(ipipe, ibuf);
+ if (!pipe_buf_get(ipipe, ibuf)) {
+ if (ret == 0)
+ ret = -EFAULT;
+ break;
+ }
obuf = opipe->bufs + nbuf;
*obuf = *ibuf;