threads / patch / 45713

patchserver-info: avoid calling fclose(3) twice in update_info_file()

Subject: [PATCH] server-info: avoid calling fclose(3) twice in update_info_file()

## tl;dr

2 messages between Apr 16, 2017 and Apr 17, 2017. Diffs are folded; open one to read it.

replies: 1people: 2as markdown or json

René Scharfe· Apr 16, 2017, 16:55 UTC · lore

If an error occurs when or after closing the stream we call fclose(3) again in the error handler. The second call can exhibit undefined behavior, so make sure to call fclose(3) at most once. Also avoid calling close(2) after fd has been successfully associated with the stream, as fclose(3) has become responsible for doing that beyond this point.

Found with Cppcheck.
Signed-off-by: Rene Scharfe <l.s.r@web.de>
---
 server-info.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
Show changes to server-info.c +5 −3
diff --git a/server-info.c b/server-info.c
index 7bc4e75d22..f6c1a3dfb0 100644
--- a/server-info.c
+++ b/server-info.c
@@ -14,19 +14,21 @@ static int update_info_file(char *path, int (*generate)(FILE *))
 	char *tmp = mkpathdup("%s_XXXXXX", path);
 	int ret = -1;
 	int fd = -1;
-	FILE *fp = NULL;
+	FILE *fp = NULL, *to_close;
 
 	safe_create_leading_directories(path);
 	fd = git_mkstemp_mode(tmp, 0666);
 	if (fd < 0)
 		goto out;
-	fp = fdopen(fd, "w");
+	to_close = fp = fdopen(fd, "w");
 	if (!fp)
 		goto out;
+	fd = -1;
 	ret = generate(fp);
 	if (ret)
 		goto out;
-	if (fclose(fp))
+	fp = NULL;
+	if (fclose(to_close))
 		goto out;
 	if (adjust_shared_perm(tmp) < 0)
 		goto out;
-- 
2.12.2
Jeff King· Apr 17, 2017, 01:37 UTC · re: René Scharfe · lore

Re: [PATCH] server-info: avoid calling fclose(3) twice in update_info_file()

On Sun, Apr 16, 2017 at 06:55:58PM +0200, René Scharfe wrote:
> If an error occurs when or after closing the stream we call fclose(3)
> again in the error handler.  The second call can exhibit undefined
> behavior, so make sure to call fclose(3) at most once.
Yikes. Good catch.
> Also avoid
> calling close(2) after fd has been successfully associated with the
> stream, as fclose(3) has become responsible for doing that beyond
> this point.

Yeah, the "else if" in the error-code was supposed to handle that, but it comes back when you fix the double-fclose by setting fp to NULL.

So the whole thing looks good to me. Thanks for cleaning up my mess.
-Peff

← back to recent threads