From 0fc0c1453c59eb8709d56f7d817caa111eb6eeb7 Mon Sep 17 00:00:00 2001
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
Date: Mon, 17 Feb 2020 17:40:07 +0100
Subject: [PATCH] Fix -save-temp leaking files in /tmp
And avoid signal handler calling signal unsafe functions,
and/or calling unlink with uninitialized memory pointer.
2020-02-18 Bernd Edlinger <bernd.edlinger@hotmail.de>
* collect2.c (c_file, o_file): Make const again.
(ldout,lderrout, dump_ld_file): Remove.
(tool_cleanup): Avoid calling not signal-safe functions.
(maybe_run_lto_and_relink): Avoid possible signal handler
access to unintialzed memory (lto_o_files).
(main): Avoid leaking temp files in $TMPDIR.
Initialize c_file/o_file with concat, which avoids exposing
uninitialized memory to signal handler, which calls unlink(!).
Avoid calling maybe_unlink when the main function returns,
since the atexit handler is already doing this.
* collect2.h (dump_ld_file, ldout, lderrout): Remove.
* lto-wrapper.c (run_gcc): Create an lto tmpdir
and use it when -save-temps is used.
---
gcc/collect2.c | 130 +++++++-----------------------------------------------
gcc/collect2.h | 4 --
gcc/lto-wrapper.c | 11 +++++
3 files changed, 27 insertions(+), 118 deletions(-)
@@ -205,14 +205,12 @@ bool helpflag; /* true if --help */
static int shared_obj; /* true if -shared */
static int static_obj; /* true if -static */
-static char *c_file; /* <xxx>.c for constructor/destructor list. */
-static char *o_file; /* <xxx>.o for constructor/destructor list. */
+static const char *c_file; /* <xxx>.c for constructor/destructor list. */
+static const char *o_file; /* <xxx>.o for constructor/destructor list. */
#ifdef COLLECT_EXPORT_LIST
static const char *export_file; /* <xxx>.x for AIX export list. */
#endif
static char **lto_o_files; /* Output files for LTO. */
-const char *ldout; /* File for ld stdout. */
-const char *lderrout; /* File for ld stderr. */
static const char *output_file; /* Output file for ld. */
static const char *nm_file_name; /* pathname of nm */
#ifdef LDD_SUFFIX
@@ -384,6 +382,10 @@ static void scan_prog_file (const char *, scanpass, scanfilter);
void
tool_cleanup (bool from_signal)
{
+ /* maybe_unlink may call notice, which is not signal safe. */
+ if (from_signal)
+ verbose = false;
+
if (c_file != 0 && c_file[0])
maybe_unlink (c_file);
@@ -397,20 +399,6 @@ tool_cleanup (bool from_signal)
if (lto_o_files)
maybe_unlink_list (lto_o_files);
-
- if (ldout != 0 && ldout[0])
- {
- if (!from_signal)
- dump_ld_file (ldout, stdout);
- maybe_unlink (ldout);
- }
-
- if (lderrout != 0 && lderrout[0])
- {
- if (!from_signal)
- dump_ld_file (lderrout, stderr);
- maybe_unlink (lderrout);
- }
}
static void
@@ -476,77 +464,6 @@ extract_string (const char **pp)
return XOBFINISH (&temporary_obstack, char *);
}
-void
-dump_ld_file (const char *name, FILE *to)
-{
- FILE *stream = fopen (name, "r");
-
- if (stream == 0)
- return;
- while (1)
- {
- int c;
- while (c = getc (stream),
- c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
- obstack_1grow (&temporary_obstack, c);
- if (obstack_object_size (&temporary_obstack) > 0)
- {
- const char *word, *p;
- char *result;
- obstack_1grow (&temporary_obstack, '\0');
- word = XOBFINISH (&temporary_obstack, const char *);
-
- if (*word == '.')
- ++word, putc ('.', to);
- p = word;
- if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
- p += strlen (USER_LABEL_PREFIX);
-
-#ifdef HAVE_LD_DEMANGLE
- result = 0;
-#else
- if (no_demangle)
- result = 0;
- else
- result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
-#endif
-
- if (result)
- {
- int diff;
- fputs (result, to);
-
- diff = strlen (word) - strlen (result);
- while (diff > 0 && c == ' ')
- --diff, putc (' ', to);
- if (diff < 0 && c == ' ')
- {
- while (diff < 0 && c == ' ')
- ++diff, c = getc (stream);
- if (!ISSPACE (c))
- {
- /* Make sure we output at least one space, or
- the demangled symbol name will run into
- whatever text follows. */
- putc (' ', to);
- }
- }
-
- free (result);
- }
- else
- fputs (word, to);
-
- fflush (to);
- obstack_free (&temporary_obstack, temporary_firstobj);
- }
- if (c == EOF)
- break;
- putc (c, to);
- }
- fclose (stream);
-}
-
/* Return the kind of symbol denoted by name S. */
static symkind
@@ -744,7 +661,10 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
++num_files;
}
- lto_o_files = XNEWVEC (char *, num_files + 1);
+ /* signal handler may access uninitialized memory
+ and delete whatever it points to, if lto_o_files
+ is not allocatted with calloc. */
+ lto_o_files = XCNEWVEC (char *, num_files + 1);
lto_o_files[num_files] = NULL;
start = XOBFINISH (&temporary_obstack, char *);
for (i = 0; i < num_files; ++i)
@@ -1262,27 +1182,19 @@ main (int argc, char **argv)
/* Make temp file names. */
if (save_temps)
{
- c_file = (char *) xmalloc (strlen (output_file)
- + sizeof (".cdtor.c") + 1);
- strcpy (c_file, output_file);
- strcat (c_file, ".cdtor.c");
- o_file = (char *) xmalloc (strlen (output_file)
- + sizeof (".cdtor.o") + 1);
- strcpy (o_file, output_file);
- strcat (o_file, ".cdtor.o");
+ c_file = concat (output_file, ".cdtor.c", NULL);
+ o_file = concat (output_file, ".cdtor.o", NULL);
+#ifdef COLLECT_EXPORT_LIST
+ export_file = concat (output_file, ".x", NULL);
+#endif
}
else
{
c_file = make_temp_file (".cdtor.c");
o_file = make_temp_file (".cdtor.o");
- }
#ifdef COLLECT_EXPORT_LIST
- export_file = make_temp_file (".x");
+ export_file = make_temp_file (".x");
#endif
- if (!debug)
- {
- ldout = make_temp_file (".ld");
- lderrout = make_temp_file (".le");
}
/* Build the command line to compile the ctor/dtor list. */
*c_ptr++ = c_file_name;
@@ -1811,9 +1723,6 @@ main (int argc, char **argv)
maybe_unlink (export_file);
#endif
post_ld_pass (/*temp_file*/false);
-
- maybe_unlink (c_file);
- maybe_unlink (o_file);
return 0;
}
@@ -1912,13 +1821,6 @@ main (int argc, char **argv)
scan_prog_file (output_file, PASS_SECOND, SCAN_ALL);
#endif
- maybe_unlink (c_file);
- maybe_unlink (o_file);
-
-#ifdef COLLECT_EXPORT_LIST
- maybe_unlink (export_file);
-#endif
-
return 0;
}
@@ -25,12 +25,8 @@ extern struct pex_obj *collect_execute (const char *, char **, const char *,
extern int collect_wait (const char *, struct pex_obj *);
-extern void dump_ld_file (const char *, FILE *);
-
extern int file_exists (const char *);
-extern const char *ldout;
-extern const char *lderrout;
extern const char *c_file_name;
extern struct obstack temporary_obstack;
extern char *temporary_firstobj;
@@ -1423,6 +1423,17 @@ run_gcc (unsigned argc, char *argv[])
fputc ('\n', stderr);
}
+ if (save_temps)
+ {
+ char *tmpdir = concat (linker_output ? linker_output : "a.out",
+ ".lto_tmpdir", NULL);
+ /* Make directory if necessary, but expect no race here. */
+ if (access (tmpdir, F_OK) == 0
+ || mkdir (tmpdir, S_IRWXU | S_IRWXG | S_IRWXO) == 0)
+ setenv ("TMPDIR", tmpdir, 1);
+ free (tmpdir);
+ }
+
if (linker_output_rel)
no_partition = true;
--
1.9.1