sed/backport-sed-avoid-potential-double-fclose.patch
laotan2 3bf271807e backport upstream patch
1.maint-avoid-new-warning-about-deprecated-security_co.patch
2.maint-update-obsolete-constructs-in-configure.ac.patch
3.sed-avoid-potential-double-fclose.patch
4.sed-fix-temp-file-cleanup.patch
5.adapt sed-c-flag.patch

Signed-off-by: laotan2 <tanjinghui1@huawei.com>
(cherry picked from commit 805226fb095690044748f410acf3df9778c94069)
2022-10-25 16:44:55 +08:00

88 lines
2.5 KiB
Diff

From 6568d364f4d21df69027319f55bcc903bfb32e0a Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering@fb.com>
Date: Sat, 10 Jul 2021 17:34:39 -0700
Subject: [PATCH 10/44] sed: avoid potential double-fclose
Upon a failed temp file fclose, do_ck_fclose would call panic,
which would then attempt to fclose and unlink that same pointer.
Caught by gcc's new -Wanalyzer-double-fclose.
* sed/utils.c (struct open_file) [fclose_failed]: New member.
(panic): Don't double-close.
(register_open_file): Clear new member.
(mark_as_fclose_failed): Use new member to avoid double fclose.
(do_ck_fclose): Call mark_as_fclose_failed upon fclose failure.
---
sed/utils.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/sed/utils.c b/sed/utils.c
index 699fd85..98b6333 100644
--- a/sed/utils.c
+++ b/sed/utils.c
@@ -47,6 +47,7 @@ struct open_file
char *name;
struct open_file *link;
unsigned temp : 1;
+ unsigned fclose_failed : 1;
};
static struct open_file *open_files = NULL;
@@ -70,7 +71,8 @@ panic (const char *str, ...)
{
if (open_files->temp)
{
- fclose (open_files->fp);
+ if (!open_files->fclose_failed)
+ fclose (open_files->fp);
errno = 0;
unlink (open_files->name);
if (errno != 0)
@@ -131,6 +133,7 @@ register_open_file (FILE *fp, const char *name)
p->name = xstrdup (name);
p->fp = fp;
p->temp = false;
+ p->fclose_failed = false;
}
/* Panic on failing fopen */
@@ -252,6 +255,21 @@ ck_fflush (FILE *stream)
panic ("couldn't flush %s: %s", utils_fp_name (stream), strerror (errno));
}
+/* If we've failed to close a file in open_files whose "fp" member
+ is the same as FP, mark its entry as fclose_failed. */
+static void
+mark_as_fclose_failed (FILE *fp)
+{
+ for (struct open_file *p = open_files; p; p = p->link)
+ {
+ if (p->fp == fp)
+ {
+ p->fclose_failed = true;
+ break;
+ }
+ }
+}
+
/* Panic on failing fclose */
void
ck_fclose (FILE *stream)
@@ -293,7 +311,13 @@ do_ck_fclose (FILE *fp)
clearerr (fp);
if (fclose (fp) == EOF)
- panic ("couldn't close %s: %s", utils_fp_name (fp), strerror (errno));
+ {
+ /* Mark as already fclose-failed, so we don't attempt to fclose it
+ a second time via panic. */
+ mark_as_fclose_failed (fp);
+
+ panic ("couldn't close %s: %s", utils_fp_name (fp), strerror (errno));
+ }
}
/* Follow symlink and panic if something fails. Return the ultimate
--
2.27.0