Return-Path: Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:52890 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750961AbcBMSm3 (ORCPT ); Sat, 13 Feb 2016 13:42:29 -0500 Received: from ben by shadbolt.decadent.org.uk with local (Exim 4.84) (envelope-from ) id 1aUf9G-0002Kd-9s for stable@vger.kernel.org; Sat, 13 Feb 2016 18:42:27 +0000 Date: Sat, 13 Feb 2016 18:42:26 +0000 From: Ben Hutchings To: stable@vger.kernel.org Message-ID: <20160213184225.GA5231@decadent.org.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="Q68bSM7Ycu6FN28Q" Content-Disposition: inline Subject: [PATCH 2.6.32-3.14] pipe: Fix buffer offset after partially failed read Sender: stable-owner@vger.kernel.org List-ID: --Q68bSM7Ycu6FN28Q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Quoting the RHEL advisory: > It was found that the fix for CVE-2015-1805 incorrectly kept buffer > offset and buffer length in sync on a failed atomic read, potentially > resulting in a pipe buffer state corruption. A local, unprivileged user > could use this flaw to crash the system or leak kernel memory to user > space. (CVE-2016-0774, Moderate) The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. =20 We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds. References: https://rhn.redhat.com/errata/RHSA-2016-0103.html Signed-off-by: Ben Hutchings --- --- a/fs/pipe.c +++ b/fs/pipe.c @@ -395,6 +395,7 @@ pipe_read(struct kiocb *iocb, const stru void *addr; size_t chars =3D buf->len, remaining; int error, atomic; + int offset; =20 if (chars > total_len) chars =3D total_len; @@ -408,9 +409,10 @@ pipe_read(struct kiocb *iocb, const stru =20 atomic =3D !iov_fault_in_pages_write(iov, chars); remaining =3D chars; + offset =3D buf->offset; redo: addr =3D ops->map(pipe, buf, atomic); - error =3D pipe_iov_copy_to_user(iov, addr, &buf->offset, + error =3D pipe_iov_copy_to_user(iov, addr, &offset, &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { @@ -426,6 +428,7 @@ redo: break; } ret +=3D chars; + buf->offset +=3D chars; buf->len -=3D chars; =20 /* Was it a packet buffer? Clean up and exit */ --Q68bSM7Ycu6FN28Q Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUBVr95Eee/yOyVhhEJAQpOZQ//cLyKJhA0yWmvtz7EQpLFeEI15urdRM/9 ORbMa5dVjphoaovn41d8G/Ku+PpB5+KHvv2H41gTn4T+uBoyQ4YNG+9rJNaSn4wo fq43Gj8MRLLm/Ksxz/Xnp4QQPxgNPOMNBwHB04c6BC3hh9iy/CmdqUyFxbPAysNL mEg/jlU8rHSIkI7nfeQcf1la6Zv5EDldIvsi42+jrWKnkvdkyuRAKb6CtSX+Y5OM aOfP0NWV4gEUe85bBGZsEzo3f2IT6SaFpcgjsNE7Gl8RvgbvPdTYDE8I64A1TgD5 E2brkzbWWxAklAOj6SwuQb26xUtO1je1O+I9Oo04ZdMHN93Ci9xEoLIeA9imy10A BKDHWAkGlkswLGIyw5X7GwH9kPOzcr4H6icK3B0QVnqP1NCnR0Y70c7t4ysl8jn0 p8WHEZLY2phrsIkUlxpPC0TlQfRhZi1d+36P5RPZw4q68VwC2RU6fo/QprSjcoFI IujVJ8Z0g1DRUIoSfYaoKroJcIrcKtTVuiBMkQbvj+FwzZzsJCxKgrbo0zAbjst7 pu4UC+JynTl/DsjhtCONDgtyes7UOaQly183UO/ZieXcOzdK1vD6MD5qJYMZwdB7 pdZ+qN6g/zVIugxu2SWxA5QD7sjWpvmgY9zG4B8rqS0TZKPFic3WGkM8/cUmUqTb D+bpQVfZrIc= =x8V2 -----END PGP SIGNATURE----- --Q68bSM7Ycu6FN28Q--