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.
This commit is contained in:
Alan Modra
2021-02-01 02:04:41 +10:30
parent 6955136728
commit 95b91a043a
4 changed files with 50 additions and 28 deletions

View File

@ -1,3 +1,19 @@
2021-02-03 Alan Modra <amodra@gmail.com>
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.
2021-02-02 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/27281

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;