Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Mar 2022 15:48:23 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 626c1423ee93 - releng/13.1 - libc  __sfvwrite(): roll back FILE buffer pointer on fflush error
Message-ID:  <202203141548.22EFmNgw033371@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/13.1 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=626c1423ee93aa95d1d2dd23c406ba661756dfe1

commit 626c1423ee93aa95d1d2dd23c406ba661756dfe1
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-03-06 08:59:39 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-03-14 15:47:24 +0000

    libc  __sfvwrite(): roll back FILE buffer pointer on fflush error
    
    __sfvwrite() advances the pointer before calling fflush.  If fflush()
    fails, it is not enough to roll back inside it, because we cannot know
    how much was advanced by the caller.
    
    Reported by:    Peter <pmc@citylink.dinoex.sub.org>
    Approved by:    re (gjb)
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    Fixes:  86a16ada1ea608408cec370171d9f59353e97c77
    
    (cherry picked from commit bafaa70b6f9098d83d074968c8e6747ecec1e118)
    (cherry picked from commit 647f02d68a60b66d063a15feed3c817966114d52)
---
 lib/libc/stdio/fvwrite.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c
index 50b32b8eca6e..2a161859afa9 100644
--- a/lib/libc/stdio/fvwrite.c
+++ b/lib/libc/stdio/fvwrite.c
@@ -54,6 +54,7 @@ int
 __sfvwrite(FILE *fp, struct __suio *uio)
 {
 	size_t len;
+	unsigned char *old_p;
 	char *p;
 	struct __siov *iov;
 	int w, s;
@@ -137,8 +138,12 @@ __sfvwrite(FILE *fp, struct __suio *uio)
 				COPY(w);
 				/* fp->_w -= w; */ /* unneeded */
 				fp->_p += w;
-				if (__fflush(fp))
+				old_p = fp->_p;
+				if (__fflush(fp) == EOF) {
+					if (old_p == fp->_p)
+						fp->_p -= w;
 					goto err;
+				}
 			} else if (len >= (w = fp->_bf._size)) {
 				/* write directly */
 				w = _swrite(fp, p, w);
@@ -177,8 +182,12 @@ __sfvwrite(FILE *fp, struct __suio *uio)
 				COPY(w);
 				/* fp->_w -= w; */
 				fp->_p += w;
-				if (__fflush(fp))
+				old_p = fp->_p;
+				if (__fflush(fp) == EOF) {
+					if (old_p == fp->_p)
+						fp->_p -= w;
 					goto err;
+				}
 			} else if (s >= (w = fp->_bf._size)) {
 				w = _swrite(fp, p, w);
 				if (w <= 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202203141548.22EFmNgw033371>