diff options
author | Nick Clifton <nickc@redhat.com> | 2021-02-05 14:10:21 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2021-02-05 14:10:21 +0000 |
commit | 97c8a8cc3f72ffadec511013d9a2f5f853f84887 (patch) | |
tree | 5f365f8e29aa9730bf1ae6294322b15e5ab27fd5 /binutils | |
parent | 86cb5ea5639c548be39f2a1de9c8bcac45f35121 (diff) | |
download | gdb-97c8a8cc3f72ffadec511013d9a2f5f853f84887.zip gdb-97c8a8cc3f72ffadec511013d9a2f5f853f84887.tar.gz gdb-97c8a8cc3f72ffadec511013d9a2f5f853f84887.tar.bz2 |
Revert "pr27270 and pr27284, ar segfaults and wrong file mode"
This reverts commit 95b91a043aeaeb546d2fea556d84a2de1e917770.
Given the problems associated with this patch and the others intended to fix the smart_rename CVE, the decision has been taken to$
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 16 | ||||
-rw-r--r-- | binutils/ar.c | 13 | ||||
-rw-r--r-- | binutils/arsup.c | 46 | ||||
-rw-r--r-- | binutils/objcopy.c | 3 |
4 files changed, 28 insertions, 50 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c53a4b5..c7ad374 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,19 +1,3 @@ -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-01-26 Frederic Cambus <fred@statdns.com> * objcopy.c (copy_main): Fix a double free happening when both diff --git a/binutils/ar.c b/binutils/ar.c index 0ecfa33..24ff092 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -25,6 +25,7 @@ #include "sysdep.h" #include "bfd.h" +#include "libbfd.h" #include "libiberty.h" #include "progress.h" #include "getopt.h" @@ -1254,8 +1255,10 @@ write_archive (bfd *iarch) bfd *contents_head = iarch->archive_next; int ofd = -1; struct stat target_stat; + bfd_boolean skip_stat = FALSE; - old_name = xstrdup (bfd_get_filename (iarch)); + old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1); + strcpy (old_name, bfd_get_filename (iarch)); new_name = make_tempname (old_name, &ofd); if (new_name == NULL) @@ -1300,9 +1303,11 @@ write_archive (bfd *iarch) #if !defined (_WIN32) || defined (__CYGWIN32__) ofd = dup (ofd); -#endif - if (ofd == -1 || bfd_stat (iarch, &target_stat) != 0) + 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 (!bfd_close (obfd)) bfd_fatal (old_name); @@ -1313,7 +1318,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, &target_stat, 0) != 0) + if (smart_rename (new_name, old_name, ofd, skip_stat ? NULL : &target_stat, 0) != 0) xexit (1); free (old_name); free (new_name); diff --git a/binutils/arsup.c b/binutils/arsup.c index a60629f..837011b 100644 --- a/binutils/arsup.c +++ b/binutils/arsup.c @@ -42,8 +42,6 @@ extern int deterministic; static bfd *obfd; static char *real_name; -static char *temp_name; -static int real_ofd; static FILE *outfile; static void @@ -151,24 +149,27 @@ maybequit (void) void ar_open (char *name, int t) { - real_name = xstrdup (name); - temp_name = make_tempname (real_name, &real_ofd); + char *tname; + const char *bname = lbasename (name); + real_name = name; - if (temp_name == NULL) + /* 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) { - fprintf (stderr, _("%s: Can't open temporary file (%s)\n"), + fprintf (stderr, _("%s: Can't allocate memory for temp name (%s)\n"), program_name, strerror(errno)); maybequit (); return; } - obfd = bfd_fdopenw (temp_name, NULL, real_ofd); + obfd = bfd_openw (tname, NULL); if (!obfd) { fprintf (stderr, _("%s: Can't open output archive %s\n"), - program_name, temp_name); + program_name, tname); maybequit (); } @@ -343,9 +344,10 @@ ar_save (void) } else { + char *ofilename = xstrdup (bfd_get_filename (obfd)); bfd_boolean skip_stat = FALSE; struct stat target_stat; - int ofd = real_ofd; + int ofd = -1; if (deterministic > 0) obfd->flags |= BFD_DETERMINISTIC_OUTPUT; @@ -353,31 +355,17 @@ 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 (ofd); + ofd = dup (fileno ((FILE *) obfd->iostream)); + if (lstat (real_name, &target_stat) != 0) + skip_stat = TRUE; #endif - bfd_close (obfd); - 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); - } - } + bfd_close (obfd); - smart_rename (temp_name, real_name, ofd, + smart_rename (ofilename, real_name, ofd, skip_stat ? NULL : &target_stat, 0); obfd = 0; - free (temp_name); - free (real_name); + free (ofilename); } } diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 19eb436..a5cead1 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -20,6 +20,7 @@ #include "sysdep.h" #include "bfd.h" +#include "libbfd.h" #include "progress.h" #include "getopt.h" #include "libiberty.h" @@ -3768,7 +3769,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 || bfd_stat (ibfd, in_stat) != 0) + if (ibfd == NULL || fstat (fileno ((FILE *) ibfd->iostream), in_stat) != 0) { bfd_nonfatal_message (input_filename, NULL, NULL, NULL); status = 1; |