194 lines
5.8 KiB
Diff
194 lines
5.8 KiB
Diff
|
|
From 95b91a043aeaeb546d2fea556d84a2de1e917770 Mon Sep 17 00:00:00 2001
|
|||
|
|
From: Alan Modra <amodra@gmail.com>
|
|||
|
|
Date: Mon, 1 Feb 2021 02:04:41 +1030
|
|||
|
|
Subject: [PATCH] pr27270 and pr27284, ar segfaults and wrong file mode
|
|||
|
|
|
|||
|
|
PR 27270
|
|||
|
|
PR 27284
|
|||
|
|
PR 26945
|
|||
|
|
* ar.c: Don't include libbfd.h.
|
|||
|
|
(write_archive): Replace xmalloc+strcpy with xstrdup. Use
|
|||
|
|
bfd_stat rather than fstat on iostream. Move stat and fd tests
|
|||
|
|
outside of _WIN32 ifdef. Delete skip_stat variable.
|
|||
|
|
* arsup.c (temp_name, real_ofd): New static variables.
|
|||
|
|
(ar_open): Use make_tempname and bfd_fdopenw.
|
|||
|
|
(ar_save): Adjust to suit ar_open changes. Move stat output
|
|||
|
|
of _WIN32 ifdef.
|
|||
|
|
* objcopy.c: Don't include libbfd.h.
|
|||
|
|
(copy_file): Use bfd_stat.
|
|||
|
|
---
|
|||
|
|
binutils/ChangeLog | 16 ++++++++++++++++
|
|||
|
|
binutils/ar.c | 13 ++++---------
|
|||
|
|
binutils/arsup.c | 46 +++++++++++++++++++++++++++++-----------------
|
|||
|
|
binutils/objcopy.c | 3 +--
|
|||
|
|
4 files changed, 50 insertions(+), 28 deletions(-)
|
|||
|
|
|
|||
|
|
diff --git a/binutils/ar.c b/binutils/ar.c
|
|||
|
|
index 24ff092..0ecfa33 100644
|
|||
|
|
--- a/binutils/ar.c
|
|||
|
|
+++ b/binutils/ar.c
|
|||
|
|
@@ -25,7 +25,6 @@
|
|||
|
|
|
|||
|
|
#include "sysdep.h"
|
|||
|
|
#include "bfd.h"
|
|||
|
|
-#include "libbfd.h"
|
|||
|
|
#include "libiberty.h"
|
|||
|
|
#include "progress.h"
|
|||
|
|
#include "getopt.h"
|
|||
|
|
@@ -1255,10 +1254,8 @@ write_archive (bfd *iarch)
|
|||
|
|
bfd *contents_head = iarch->archive_next;
|
|||
|
|
int ofd = -1;
|
|||
|
|
struct stat target_stat;
|
|||
|
|
- bfd_boolean skip_stat = FALSE;
|
|||
|
|
|
|||
|
|
- old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
|
|||
|
|
- strcpy (old_name, bfd_get_filename (iarch));
|
|||
|
|
+ old_name = xstrdup (bfd_get_filename (iarch));
|
|||
|
|
new_name = make_tempname (old_name, &ofd);
|
|||
|
|
|
|||
|
|
if (new_name == NULL)
|
|||
|
|
@@ -1303,11 +1300,9 @@ write_archive (bfd *iarch)
|
|||
|
|
|
|||
|
|
#if !defined (_WIN32) || defined (__CYGWIN32__)
|
|||
|
|
ofd = dup (ofd);
|
|||
|
|
- if (iarch == NULL || iarch->iostream == NULL)
|
|||
|
|
- skip_stat = TRUE;
|
|||
|
|
- else if (ofd == -1 || fstat (fileno ((FILE *) iarch->iostream), &target_stat) != 0)
|
|||
|
|
- bfd_fatal (old_name);
|
|||
|
|
#endif
|
|||
|
|
+ if (ofd == -1 || bfd_stat (iarch, &target_stat) != 0)
|
|||
|
|
+ bfd_fatal (old_name);
|
|||
|
|
|
|||
|
|
if (!bfd_close (obfd))
|
|||
|
|
bfd_fatal (old_name);
|
|||
|
|
@@ -1318,7 +1313,7 @@ write_archive (bfd *iarch)
|
|||
|
|
/* We don't care if this fails; we might be creating the archive. */
|
|||
|
|
bfd_close (iarch);
|
|||
|
|
|
|||
|
|
- if (smart_rename (new_name, old_name, ofd, skip_stat ? NULL : &target_stat, 0) != 0)
|
|||
|
|
+ if (smart_rename (new_name, old_name, ofd, &target_stat, 0) != 0)
|
|||
|
|
xexit (1);
|
|||
|
|
free (old_name);
|
|||
|
|
free (new_name);
|
|||
|
|
diff --git a/binutils/arsup.c b/binutils/arsup.c
|
|||
|
|
index 837011b..a60629f 100644
|
|||
|
|
--- a/binutils/arsup.c
|
|||
|
|
+++ b/binutils/arsup.c
|
|||
|
|
@@ -42,6 +42,8 @@ extern int deterministic;
|
|||
|
|
|
|||
|
|
static bfd *obfd;
|
|||
|
|
static char *real_name;
|
|||
|
|
+static char *temp_name;
|
|||
|
|
+static int real_ofd;
|
|||
|
|
static FILE *outfile;
|
|||
|
|
|
|||
|
|
static void
|
|||
|
|
@@ -149,27 +151,24 @@ maybequit (void)
|
|||
|
|
void
|
|||
|
|
ar_open (char *name, int t)
|
|||
|
|
{
|
|||
|
|
- char *tname;
|
|||
|
|
- const char *bname = lbasename (name);
|
|||
|
|
- real_name = name;
|
|||
|
|
+ real_name = xstrdup (name);
|
|||
|
|
+ temp_name = make_tempname (real_name, &real_ofd);
|
|||
|
|
|
|||
|
|
- /* Prepend tmp- to the beginning, to avoid file-name clashes after
|
|||
|
|
- truncation on filesystems with limited namespaces (DOS). */
|
|||
|
|
- if (asprintf (&tname, "%.*stmp-%s", (int) (bname - name), name, bname) == -1)
|
|||
|
|
+ if (temp_name == NULL)
|
|||
|
|
{
|
|||
|
|
- fprintf (stderr, _("%s: Can't allocate memory for temp name (%s)\n"),
|
|||
|
|
+ fprintf (stderr, _("%s: Can't open temporary file (%s)\n"),
|
|||
|
|
program_name, strerror(errno));
|
|||
|
|
maybequit ();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
- obfd = bfd_openw (tname, NULL);
|
|||
|
|
+ obfd = bfd_fdopenw (temp_name, NULL, real_ofd);
|
|||
|
|
|
|||
|
|
if (!obfd)
|
|||
|
|
{
|
|||
|
|
fprintf (stderr,
|
|||
|
|
_("%s: Can't open output archive %s\n"),
|
|||
|
|
- program_name, tname);
|
|||
|
|
+ program_name, temp_name);
|
|||
|
|
|
|||
|
|
maybequit ();
|
|||
|
|
}
|
|||
|
|
@@ -344,10 +343,9 @@ ar_save (void)
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
- char *ofilename = xstrdup (bfd_get_filename (obfd));
|
|||
|
|
bfd_boolean skip_stat = FALSE;
|
|||
|
|
struct stat target_stat;
|
|||
|
|
- int ofd = -1;
|
|||
|
|
+ int ofd = real_ofd;
|
|||
|
|
|
|||
|
|
if (deterministic > 0)
|
|||
|
|
obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
|
|||
|
|
@@ -355,17 +353,31 @@ ar_save (void)
|
|||
|
|
#if !defined (_WIN32) || defined (__CYGWIN32__)
|
|||
|
|
/* It's OK to fail; at worst it will result in SMART_RENAME using a slow
|
|||
|
|
copy fallback to write the output. */
|
|||
|
|
- ofd = dup (fileno ((FILE *) obfd->iostream));
|
|||
|
|
- if (lstat (real_name, &target_stat) != 0)
|
|||
|
|
- skip_stat = TRUE;
|
|||
|
|
+ ofd = dup (ofd);
|
|||
|
|
#endif
|
|||
|
|
-
|
|||
|
|
bfd_close (obfd);
|
|||
|
|
|
|||
|
|
- smart_rename (ofilename, real_name, ofd,
|
|||
|
|
+ if (lstat (real_name, &target_stat) != 0)
|
|||
|
|
+ {
|
|||
|
|
+ /* The temp file created in ar_open has mode 0600 as per mkstemp.
|
|||
|
|
+ Create the real empty output file here so smart_rename will
|
|||
|
|
+ update the mode according to the process umask. */
|
|||
|
|
+ obfd = bfd_openw (real_name, NULL);
|
|||
|
|
+ if (obfd == NULL
|
|||
|
|
+ || bfd_stat (obfd, &target_stat) != 0)
|
|||
|
|
+ skip_stat = TRUE;
|
|||
|
|
+ if (obfd != NULL)
|
|||
|
|
+ {
|
|||
|
|
+ bfd_set_format (obfd, bfd_archive);
|
|||
|
|
+ bfd_close (obfd);
|
|||
|
|
+ }
|
|||
|
|
+ }
|
|||
|
|
+
|
|||
|
|
+ smart_rename (temp_name, real_name, ofd,
|
|||
|
|
skip_stat ? NULL : &target_stat, 0);
|
|||
|
|
obfd = 0;
|
|||
|
|
- free (ofilename);
|
|||
|
|
+ free (temp_name);
|
|||
|
|
+ free (real_name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
|
|||
|
|
index 39a1ccb..0e1047e 100644
|
|||
|
|
--- a/binutils/objcopy.c
|
|||
|
|
+++ b/binutils/objcopy.c
|
|||
|
|
@@ -20,7 +20,6 @@
|
|||
|
|
|
|||
|
|
#include "sysdep.h"
|
|||
|
|
#include "bfd.h"
|
|||
|
|
-#include "libbfd.h"
|
|||
|
|
#include "progress.h"
|
|||
|
|
#include "getopt.h"
|
|||
|
|
#include "libiberty.h"
|
|||
|
|
@@ -3768,7 +3767,7 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
|
|||
|
|
/* To allow us to do "strip *" without dying on the first
|
|||
|
|
non-object file, failures are nonfatal. */
|
|||
|
|
ibfd = bfd_openr (input_filename, input_target);
|
|||
|
|
- if (ibfd == NULL || fstat (fileno ((FILE *) ibfd->iostream), in_stat) != 0)
|
|||
|
|
+ if (ibfd == NULL || bfd_stat (ibfd, in_stat) != 0)
|
|||
|
|
{
|
|||
|
|
bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
|
|||
|
|
status = 1;
|
|||
|
|
--
|
|||
|
|
1.8.3.1
|
|||
|
|
|