Skip to content

Commit 6184480

Browse files
committed
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. (cherry picked from commit 95b91a0)
1 parent d2ea9f3 commit 6184480

File tree

4 files changed

+50
-28
lines changed

4 files changed

+50
-28
lines changed

binutils/ChangeLog

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
2021-02-03 Alan Modra <amodra@gmail.com>
2+
3+
PR 27270
4+
PR 27284
5+
PR 26945
6+
* ar.c: Don't include libbfd.h.
7+
(write_archive): Replace xmalloc+strcpy with xstrdup. Use
8+
bfd_stat rather than fstat on iostream. Move stat and fd tests
9+
outside of _WIN32 ifdef. Delete skip_stat variable.
10+
* arsup.c (temp_name, real_ofd): New static variables.
11+
(ar_open): Use make_tempname and bfd_fdopenw.
12+
(ar_save): Adjust to suit ar_open changes. Move stat output
13+
of _WIN32 ifdef.
14+
* objcopy.c: Don't include libbfd.h.
15+
(copy_file): Use bfd_stat.
16+
117
2021-01-26 Frederic Cambus <fred@statdns.com>
218

319
* objcopy.c (copy_main): Fix a double free happening when both

binutils/ar.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
#include "sysdep.h"
2727
#include "bfd.h"
28-
#include "libbfd.h"
2928
#include "libiberty.h"
3029
#include "progress.h"
3130
#include "getopt.h"
@@ -1255,10 +1254,8 @@ write_archive (bfd *iarch)
12551254
bfd *contents_head = iarch->archive_next;
12561255
int ofd = -1;
12571256
struct stat target_stat;
1258-
bfd_boolean skip_stat = FALSE;
12591257

1260-
old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1261-
strcpy (old_name, bfd_get_filename (iarch));
1258+
old_name = xstrdup (bfd_get_filename (iarch));
12621259
new_name = make_tempname (old_name, &ofd);
12631260

12641261
if (new_name == NULL)
@@ -1303,11 +1300,9 @@ write_archive (bfd *iarch)
13031300

13041301
#if !defined (_WIN32) || defined (__CYGWIN32__)
13051302
ofd = dup (ofd);
1306-
if (iarch == NULL || iarch->iostream == NULL)
1307-
skip_stat = TRUE;
1308-
else if (ofd == -1 || fstat (fileno ((FILE *) iarch->iostream), &target_stat) != 0)
1309-
bfd_fatal (old_name);
13101303
#endif
1304+
if (ofd == -1 || bfd_stat (iarch, &target_stat) != 0)
1305+
bfd_fatal (old_name);
13111306

13121307
if (!bfd_close (obfd))
13131308
bfd_fatal (old_name);
@@ -1318,7 +1313,7 @@ write_archive (bfd *iarch)
13181313
/* We don't care if this fails; we might be creating the archive. */
13191314
bfd_close (iarch);
13201315

1321-
if (smart_rename (new_name, old_name, ofd, skip_stat ? NULL : &target_stat, 0) != 0)
1316+
if (smart_rename (new_name, old_name, ofd, &target_stat, 0) != 0)
13221317
xexit (1);
13231318
free (old_name);
13241319
free (new_name);

binutils/arsup.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ extern int deterministic;
4242

4343
static bfd *obfd;
4444
static char *real_name;
45+
static char *temp_name;
46+
static int real_ofd;
4547
static FILE *outfile;
4648

4749
static void
@@ -149,27 +151,24 @@ maybequit (void)
149151
void
150152
ar_open (char *name, int t)
151153
{
152-
char *tname;
153-
const char *bname = lbasename (name);
154-
real_name = name;
154+
real_name = xstrdup (name);
155+
temp_name = make_tempname (real_name, &real_ofd);
155156

156-
/* Prepend tmp- to the beginning, to avoid file-name clashes after
157-
truncation on filesystems with limited namespaces (DOS). */
158-
if (asprintf (&tname, "%.*stmp-%s", (int) (bname - name), name, bname) == -1)
157+
if (temp_name == NULL)
159158
{
160-
fprintf (stderr, _("%s: Can't allocate memory for temp name (%s)\n"),
159+
fprintf (stderr, _("%s: Can't open temporary file (%s)\n"),
161160
program_name, strerror(errno));
162161
maybequit ();
163162
return;
164163
}
165164

166-
obfd = bfd_openw (tname, NULL);
165+
obfd = bfd_fdopenw (temp_name, NULL, real_ofd);
167166

168167
if (!obfd)
169168
{
170169
fprintf (stderr,
171170
_("%s: Can't open output archive %s\n"),
172-
program_name, tname);
171+
program_name, temp_name);
173172

174173
maybequit ();
175174
}
@@ -344,28 +343,41 @@ ar_save (void)
344343
}
345344
else
346345
{
347-
char *ofilename = xstrdup (bfd_get_filename (obfd));
348346
bfd_boolean skip_stat = FALSE;
349347
struct stat target_stat;
350-
int ofd = -1;
348+
int ofd = real_ofd;
351349

352350
if (deterministic > 0)
353351
obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
354352

355353
#if !defined (_WIN32) || defined (__CYGWIN32__)
356354
/* It's OK to fail; at worst it will result in SMART_RENAME using a slow
357355
copy fallback to write the output. */
358-
ofd = dup (fileno ((FILE *) obfd->iostream));
359-
if (lstat (real_name, &target_stat) != 0)
360-
skip_stat = TRUE;
356+
ofd = dup (ofd);
361357
#endif
362-
363358
bfd_close (obfd);
364359

365-
smart_rename (ofilename, real_name, ofd,
360+
if (lstat (real_name, &target_stat) != 0)
361+
{
362+
/* The temp file created in ar_open has mode 0600 as per mkstemp.
363+
Create the real empty output file here so smart_rename will
364+
update the mode according to the process umask. */
365+
obfd = bfd_openw (real_name, NULL);
366+
if (obfd == NULL
367+
|| bfd_stat (obfd, &target_stat) != 0)
368+
skip_stat = TRUE;
369+
if (obfd != NULL)
370+
{
371+
bfd_set_format (obfd, bfd_archive);
372+
bfd_close (obfd);
373+
}
374+
}
375+
376+
smart_rename (temp_name, real_name, ofd,
366377
skip_stat ? NULL : &target_stat, 0);
367378
obfd = 0;
368-
free (ofilename);
379+
free (temp_name);
380+
free (real_name);
369381
}
370382
}
371383

binutils/objcopy.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
#include "sysdep.h"
2222
#include "bfd.h"
23-
#include "libbfd.h"
2423
#include "progress.h"
2524
#include "getopt.h"
2625
#include "libiberty.h"
@@ -3769,7 +3768,7 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
37693768
/* To allow us to do "strip *" without dying on the first
37703769
non-object file, failures are nonfatal. */
37713770
ibfd = bfd_openr (input_filename, input_target);
3772-
if (ibfd == NULL || fstat (fileno ((FILE *) ibfd->iostream), in_stat) != 0)
3771+
if (ibfd == NULL || bfd_stat (ibfd, in_stat) != 0)
37733772
{
37743773
bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
37753774
status = 1;

0 commit comments

Comments
 (0)