Code:  static void pipe_advance(struct iov_iter *i, size_t size)
 {
 	struct pipe_inode_info *pipe = i->pipe;
	struct pipe_buffer *buf;
	int idx = i->idx;
	size_t off = i->iov_offset, orig_sz;
 	if (unlikely(i->count < size))
 		size = i->count;
	orig_sz = size;
 	if (size) {
 		if (off) /* make it relative to the beginning of buffer */
			size += off - pipe->bufs[idx].offset;
 		while (1) {
 			buf = &pipe->bufs[idx];
			if (size <= buf->len)
 				break;
			size -= buf->len;
 			idx = next_idx(idx, pipe);
 		}
		buf->len = size;
 		i->idx = idx;
		off = i->iov_offset = buf->offset + size;
	}
	if (off)
		idx = next_idx(idx, pipe);
	if (pipe->nrbufs) {
		int unused = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
		/* [curbuf,unused) is in use.  Free [idx,unused) */
		while (idx != unused) {
			pipe_buf_release(pipe, &pipe->bufs[idx]);
			idx = next_idx(idx, pipe);
			pipe->nrbufs--;
		}
 	}
	i->count -= orig_sz;
 }

Vulnerability Type: +Info 
CWE ID: CWE-200
Summary: Off-by-one error in the pipe_advance function in lib/iov_iter.c in the Linux kernel before 4.9.5 allows local users to obtain sensitive information from uninitialized heap-memory locations in opportunistic circumstances by reading from a pipe after an incorrect buffer-release decision.
Commit Message: fix a fencepost error in pipe_advance()

The logics in pipe_advance() used to release all buffers past the new
position failed in cases when the number of buffers to release was equal
to pipe->buffers.  If that happened, none of them had been released,
leaving pipe full.  Worse, it was trivial to trigger and we end up with
pipe full of uninitialized pages.  IOW, it's an infoleak.

Cc: stable@vger.kernel.org # v4.9
Reported-by: "Alan J. Wylie" <alan@wylie.me.uk>
Tested-by: "Alan J. Wylie" <alan@wylie.me.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>