From nobody Wed Nov 8 01:03:18 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4SQ6K30D73z4yxxs; Wed, 8 Nov 2023 01:03:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4SQ6K26YKQz3Vn0; Wed, 8 Nov 2023 01:03:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1699405398; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LHjgy+mkFsZuBbM5sBAwLo2SDWIlZnjC7sxEyykncLk=; b=J8S8FUmIIUR9/lLGFOMz8wcfqAJop+jrF8YmqGYFVZdOpFXt9Zt5VekNRN0b1hPKwpZWmY mk2l35aNHU36i+I6HkvOdS2R3O1K2JCZOwSgY1jvs2L1by4ziPV1oddtcS6mUfqjfuLkTO plGH1tIIAhNoiobCR9N5fpxHHXO/iycZqm2OhkgbTPAKomJ3W/VzSy/8p9AZkPI3aBTMV+ kxcNlDyhriUKcCdCWRYZxMUsP9sA1lt73zwZJsO25DaYw8P5OHfTNiFxnuRx1iHtNsZpME HktMWSZ/ldXnVZwsQKwfptMf9dxB3DcO603LQbiu9PUEuB9nggdet7mtijug0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1699405398; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LHjgy+mkFsZuBbM5sBAwLo2SDWIlZnjC7sxEyykncLk=; b=Jxt8vZeouaK/Xb4xqP+uUiO4hFDDceWEX8IdD6QgYhFGIVn+kLaUdVihd8x7CHo2f++D23 pQbFhoXYMjV809TdvBnknpW1jWeZNgQbOZ10KmT1edcYWgMUZGDvcPM330HsrpRqeI8e2A iCPVrgyVmMaxHzvy3bI09KwDjo4zYPDs9jNyc1hdqeysPxFQXpgtx7JyZDi51a4AiogV9x T9iudgth6gLsZLQFxwkXUII7Z/EegvfKM3GKJDma6fTH46TMjVVFMkpvQt1SsCfN3V47Bj NALKnIu3h2bzBTq9eEODbUlGt5SjAx5FhcNcTO0XQNY/9omw6yjz4UnSDAxhUQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1699405398; a=rsa-sha256; cv=none; b=rwLT1uv5/Tm7ATs9aNTUx+kmtECkffkGeNZmtkXXcSOSPddFMqE2HLAK8czC86xh3HdTHN oJ4ID1W4VrTzNs46SdzBj0UYrFlautoCRZs128ZUprrsQbGi5V81sJ2LOVx8gkBveAgjAA 0k4pu/fCz++rC3a+rQtCp0bt9A+TgvsQQXBv6MmBkNClqrai01Qd+cGb1aiRCpDw4uyGln 2k40vob/ueQQRGlD59noIS2udvy+O822uWQ5GosrPx+cpiEV671oerJVyuxmfceVS7dgKu VqLwJH2pYMir+sFvKGQDF9NhLT/Iqv9MEZSq78FAT154BBwIrVTnY3+FYcOwyg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4SQ6K25gJvz1CKd; Wed, 8 Nov 2023 01:03:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3A813Ivl004908; Wed, 8 Nov 2023 01:03:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3A813ImR004905; Wed, 8 Nov 2023 01:03:18 GMT (envelope-from git) Date: Wed, 8 Nov 2023 01:03:18 GMT Message-Id: <202311080103.3A813ImR004905@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: 9b3e17e15f94 - releng/12.4 - fflush: correct buffer handling in __sflush List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/releng/12.4 X-Git-Reftype: branch X-Git-Commit: 9b3e17e15f942d1c5d4eaaa327d1eea7d4c9e233 Auto-Submitted: auto-generated The branch releng/12.4 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=9b3e17e15f942d1c5d4eaaa327d1eea7d4c9e233 commit 9b3e17e15f942d1c5d4eaaa327d1eea7d4c9e233 Author: Dag-Erling Smørgrav AuthorDate: 2023-08-03 15:08:03 +0000 Commit: Ed Maste CommitDate: 2023-11-08 01:01:23 +0000 fflush: correct buffer handling in __sflush This fixes CVE-2014-8611 correctly. The commit that purported to fix CVE-2014-8611 (805288c2f062) only hid it behind another bug. Two later commits, 86a16ada1ea6 and 44cf1e5eb470, attempted to address this new bug but mostly just confused the issue. This commit rolls back the three previous changes and fixes CVE-2014-8611 correctly. The key to understanding the bug (and the fix) is that `_w` has different meanings for different stream modes. If the stream is unbuffered, it is always zero. If the stream is fully buffered, it is the amount of space remaining in the buffer (equal to the buffer size when the buffer is empty and zero when the buffer is full). If the stream is line-buffered, it is a negative number reflecting the amount of data in the buffer (zero when the buffer is empty and negative buffer size when the buffer is full). At the heart of `fflush()`, we call the stream's write function in a loop, where `t` represents the return value from the last call and `n` the amount of data that remains to be written. When the write function fails, we need to move the unwritten data to the top of the buffer (unless nothing was written) and adjust `_p` (which points to the next free location in the buffer) and `_w` accordingly. These variables have already been set to the values they should have after a successful flush, so instead of adjusting them down to reflect what was written, we're adjusting them up to reflect what remains. The bug was that while `_p` was always adjusted, we only adjusted `_w` if the stream was fully buffered. The fix is to also adjust `_w` for line-buffered streams. Everything else is just noise. Fixes: 805288c2f062 Fixes: 86a16ada1ea6 Fixes: 44cf1e5eb470 Sponsored by: Klara, Inc. (cherry picked from commit 1f90b4edffe815aebb35e74b79e10593b31f6b75) (cherry picked from commit 1e99535be2ea9c0ef8bc57fc885e9c01fa95d2dd) (cherry picked from commit ccdd8337f9cbd7d34e2e95df1440dd5f7225d0b4) (cherry picked from commit 95fbce59c9f4ed4015b19a88491a37dac9d4e7d5) (cherry picked from commit d09a3bf72c0b5f1779c52269671872368c99f02a) (cherry picked from commit 92709431b14df6c0687446247ac57cfc189ee827) (cherry picked from commit 6cb5690b3495741e9ece6f42ba4a85732932aa83) (cherry picked from commit 3a2ea31568c81f7b29710abd3d3e1ada2fbeb6c9) Approved by: so Security: SA-23:15.stdio Sponsored by: The FreeBSD Foundation --- lib/libc/stdio/fflush.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index f7d2fbdc28e5..75f145fae6a3 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -106,10 +106,10 @@ int __sflush(FILE *fp) { unsigned char *p; - int n, t; + int n, f, t; - t = fp->_flags; - if ((t & __SWR) == 0) + f = fp->_flags; + if ((f & __SWR) == 0) return (0); if ((p = fp->_bf._base) == NULL) @@ -122,19 +122,18 @@ __sflush(FILE *fp) * exchange buffering (via setvbuf) in user write function. */ fp->_p = p; - fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + fp->_w = f & (__SLBF|__SNBF) ? 0 : fp->_bf._size; for (; n > 0; n -= t, p += t) { t = _swrite(fp, (char *)p, n); if (t <= 0) { - /* Reset _p and _w. */ - if (p > fp->_p) { + if (p > fp->_p) /* Some was written. */ memmove(fp->_p, p, n); - fp->_p += n; - if ((fp->_flags & (__SLBF | __SNBF)) == 0) - fp->_w -= n; - } + /* Reset _p and _w. */ + fp->_p += n; + if ((fp->_flags & __SNBF) == 0) + fp->_w -= n; fp->_flags |= __SERR; return (EOF); }