!114 update to 2.37 and fix CVE-2021-42574

Merge pull request !114 from panxh_purple/master
This commit is contained in:
openeuler-ci-bot 2022-01-21 03:42:52 +00:00 committed by Gitee
commit 23db8c88f5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
17 changed files with 2229 additions and 2206 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
From 795588aec4f894206863c938bd6d716895886009 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pekka=20Sepp=C3=A4nen?= <pexu@sourceware.mail.kapsi.fi>
Date: Wed, 10 Nov 2021 20:15:19 +1030
Subject: [PATCH] PR28575, readelf.c and strings.c use undefined type uint
Since --unicode support (commit b3aa80b45c4) both binutils/readelf.c
and binutils/strings.c use 'uint' in a few locations. It likely
should be 'unsigned int' since there isn't anything defining 'uint'
within binutils (besides zlib) and AFAIK it isn't a standard type.
* readelf.c (print_symbol): Replace uint with unsigned int.
* strings.c (string_min, display_utf8_char): Likewise.
(print_unicode_stream_body, print_unicode_stream): Likewise.
(print_strings): Likewise.
(get_unicode_byte): Wrap long line.
Conflict:Context adaptation
---
binutils/readelf.c | 4 ++--
binutils/strings.c | 41 ++++++++++++++++++++++-------------------
2 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index dd8660c..cc9023a 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -678,7 +678,7 @@ print_symbol (signed int width, const char * symbol)
/* Display unicode characters as something else. */
unsigned char bytes[4];
bool is_utf8;
- uint nbytes;
+ unsigned int nbytes;
bytes[0] = c;
@@ -743,7 +743,7 @@ print_symbol (signed int width, const char * symbol)
if (unicode_display == unicode_hex || ! is_utf8)
{
- uint i;
+ unsigned int i;
if (width_remaining < (nbytes * 2) + 2)
break;
diff --git a/binutils/strings.c b/binutils/strings.c
index f50badf..e7dd534 100644
--- a/binutils/strings.c
+++ b/binutils/strings.c
@@ -57,7 +57,7 @@
--unicode={default|locale|invalid|hex|escape|highlight}
-u {d|l|i|x|e|h}
- Determine how to handle UTF-8 unicode characters. The default
+ Determine how to handle UTF-8 unicode characters. The default
is no special treatment. All other versions of this option
only apply if the encoding is valid and enabling the option
implies --encoding=S.
@@ -123,7 +123,7 @@ extern int errno;
static int address_radix;
/* Minimum length of sequence of graphic chars to trigger output. */
-static uint string_min;
+static unsigned int string_min;
/* Whether or not we include all whitespace as a graphic char. */
static bool include_all_whitespace;
@@ -272,7 +272,7 @@ main (int argc, char **argv)
case 's':
output_separator = optarg;
- break;
+ break;
case 'U':
if (streq (optarg, "default") || streq (optarg, "d"))
@@ -677,7 +677,7 @@ is_valid_utf8 (const unsigned char * buffer, unsigned long buflen)
if ((buffer[2] & 0xc0) != 0x80)
return 0;
-
+
if ((buffer[0] & 0x10) == 0)
return 3;
@@ -694,11 +694,11 @@ is_valid_utf8 (const unsigned char * buffer, unsigned long buflen)
of unicode_display. The character is known to be valid.
Returns the number of bytes consumed. */
-static uint
+static unsigned int
display_utf8_char (const unsigned char * buffer)
{
- uint j;
- uint utf8_len;
+ unsigned int j;
+ unsigned int utf8_len;
switch (buffer[0] & 0x30)
{
@@ -712,7 +712,7 @@ display_utf8_char (const unsigned char * buffer)
default:
utf8_len = 4;
}
-
+
switch (unicode_display)
{
default:
@@ -728,7 +728,7 @@ display_utf8_char (const unsigned char * buffer)
{
case 2:
printf ("\\u%02x%02x",
- ((buffer[0] & 0x1c) >> 2),
+ ((buffer[0] & 0x1c) >> 2),
((buffer[0] & 0x03) << 6) | (buffer[1] & 0x3f));
break;
@@ -857,7 +857,7 @@ print_unicode_buffer (const char * filename,
return;
print_filename_and_address (filename, address + start_point);
-
+
/* We have found string_min characters. Display them and any
more that follow. */
for (i = start_point; i < buflen; i += char_len)
@@ -888,7 +888,10 @@ print_unicode_buffer (const char * filename,
}
static int
-get_unicode_byte (FILE * stream, unsigned char * putback, uint * num_putback, uint * num_read)
+get_unicode_byte (FILE * stream,
+ unsigned char * putback,
+ unsigned int * num_putback,
+ unsigned int * num_read)
{
if (* num_putback > 0)
{
@@ -912,7 +915,7 @@ print_unicode_stream_body (const char * filename,
file_ptr address,
FILE * stream,
unsigned char * putback_buf,
- uint num_putback,
+ unsigned int num_putback,
unsigned char * print_buf)
{
/* It would be nice if we could just read the stream into a buffer
@@ -921,9 +924,9 @@ print_unicode_stream_body (const char * filename,
we go one byte at a time... */
file_ptr start_point = 0;
- uint num_read = 0;
- uint num_chars = 0;
- uint num_print = 0;
+ unsigned int num_read = 0;
+ unsigned int num_chars = 0;
+ unsigned int num_print = 0;
int c = 0;
/* Find a series of string_min characters. Put them into print_buf. */
@@ -1064,7 +1067,7 @@ print_unicode_stream_body (const char * filename,
print_filename_and_address (filename, address + start_point);
- uint i;
+ unsigned int i;
for (i = 0; i < num_print;)
{
if (print_buf[i] < 127)
@@ -1075,7 +1078,7 @@ print_unicode_stream_body (const char * filename,
/* OK so now we have to start read unchecked bytes. */
- /* Find a series of string_min characters. Put them into print_buf. */
+ /* Find a series of string_min characters. Put them into print_buf. */
do
{
c = get_unicode_byte (stream, putback_buf, & num_putback, & num_read);
@@ -1213,7 +1216,7 @@ print_unicode_stream (const char * filename,
unsigned char * print_buf = xmalloc ((4 * string_min) + 1);
/* We should never have to put back more than 4 bytes. */
unsigned char putback_buf[5];
- uint num_putback = 0;
+ unsigned int num_putback = 0;
print_unicode_stream_body (filename, address, stream, putback_buf, num_putback, print_buf);
free (print_buf);
@@ -1250,7 +1253,7 @@ print_strings (const char *filename, FILE *stream, file_ptr address,
while (1)
{
file_ptr start;
- uint i;
+ unsigned int i;
long c;
/* See if the next `string_min' chars are all graphic chars. */
--
1.8.3.1

View File

@ -1,368 +0,0 @@
From 014cc7f849e8209623fc99264814bce7b3b6faf2 Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@gotplt.org>
Date: Mon, 7 Dec 2020 20:48:33 +0530
Subject: [PATCH] binutils: Make smart_rename safe too
smart_rename is capable of handling symlinks by copying and it also
tries to preserve ownership and permissions of files when they're
overwritten during the rename. This is useful in objcopy where the
file properties need to be preserved.
However because smart_rename does this using file names, it leaves a
race window between renames and permission fixes. This change removes
this race window by using file descriptors from the original BFDs that
were used to manipulate these files wherever possible.
The file that is to be renamed is also passed as a file descriptor so
that we use fchown/fchmod on the file descriptor, thus making sure
that we only modify the file we have opened to write. Further, in
case the file is to be overwritten (as is the case in ar or objcopy),
the permissions that need to be restored are taken from the file
descriptor that was opened for input so that integrity of the file
status is maintained all the way through to the rename.
binutils/
* rename.c
* ar.c
(write_archive) [!defined (_WIN32) || defined (__CYGWIN32__)]:
Initialize TARGET_STAT and OFD to pass to SMART_RENAME.
* arsup.c
(ar_save) [defined (_WIN32) || defined (__CYGWIN32__)]:
Likewise.
* bucomm.h (smart_rename): Add new arguments to declaration.
* objcopy.c
(strip_main)[defined (_WIN32) || defined (__CYGWIN32__)]:
Initialize COPYFD and pass to SMART_RENAME.
(copy_main) [defined (_WIN32) || defined (__CYGWIN32__)]:
Likewise.
* rename.c (try_preserve_permissions): New function.
(smart_rename): Use it and add new arguments.
---
binutils/ChangeLog | 18 ++++++++++
binutils/ar.c | 12 ++++++-
binutils/arsup.c | 14 +++++++-
binutils/bucomm.h | 3 +-
binutils/objcopy.c | 42 +++++++++++++++++-----
binutils/rename.c | 101 +++++++++++++++++++++++++++++++++++++----------------
6 files changed, 148 insertions(+), 42 deletions(-)
diff --git a/binutils/ar.c b/binutils/ar.c
index 2253242..6598dd9 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1254,6 +1254,8 @@ write_archive (bfd *iarch)
char *old_name, *new_name;
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));
@@ -1299,6 +1301,14 @@ write_archive (bfd *iarch)
if (!bfd_set_archive_head (obfd, contents_head))
bfd_fatal (old_name);
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+ ofd = dup (ofd);
+ if (iarch == NULL || iarch->iostream == NULL)
+ skip_stat = TRUE;
+ else if (ofd == -1 || fstat (fileno (iarch->iostream), &target_stat) != 0)
+ bfd_fatal (old_name);
+#endif
+
if (!bfd_close (obfd))
bfd_fatal (old_name);
@@ -1308,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, 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 a668f27..8b4437f 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -345,13 +345,25 @@ ar_save (void)
else
{
char *ofilename = xstrdup (bfd_get_filename (obfd));
+ bfd_boolean skip_stat = FALSE;
+ struct stat target_stat;
+ int ofd = -1;
if (deterministic > 0)
obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
+#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 (obfd->iostream));
+ if (lstat (real_name, &target_stat) != 0)
+ skip_stat = TRUE;
+#endif
+
bfd_close (obfd);
- smart_rename (ofilename, real_name, 0);
+ smart_rename (ofilename, real_name, ofd,
+ skip_stat ? NULL : &target_stat, 0);
obfd = 0;
free (ofilename);
}
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
index afb8e09..9613b92 100644
--- a/binutils/bucomm.h
+++ b/binutils/bucomm.h
@@ -71,7 +71,8 @@ extern void print_version (const char *);
/* In rename.c. */
extern void set_times (const char *, const struct stat *);
-extern int smart_rename (const char *, const char *, int);
+extern int smart_rename (const char *, const char *, int, struct stat *, int);
+
/* In libiberty. */
void *xmalloc (size_t);
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index b6cf6ea..04ba95e 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -4815,6 +4815,7 @@ strip_main (int argc, char *argv[])
struct stat statbuf;
char *tmpname;
int tmpfd = -1;
+ int copyfd = -1;
if (get_file_size (argv[i]) < 1)
{
@@ -4828,7 +4829,12 @@ strip_main (int argc, char *argv[])
else
tmpname = output_file;
- if (tmpname == NULL)
+ if (tmpname == NULL
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+ /* Retain a copy of TMPFD since we will need it for SMART_RENAME. */
+ || (tmpfd >= 0 && (copyfd = dup (tmpfd)) == -1)
+#endif
+ )
{
bfd_nonfatal_message (argv[i], NULL, NULL,
_("could not create temporary file to hold stripped copy"));
@@ -4846,12 +4852,18 @@ strip_main (int argc, char *argv[])
if (output_file != tmpname)
status = (smart_rename (tmpname,
output_file ? output_file : argv[i],
- preserve_dates) != 0);
+ copyfd, &statbuf, preserve_dates) != 0);
if (status == 0)
status = hold_status;
}
else
- unlink_if_ordinary (tmpname);
+ {
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+ if (copyfd >= 0)
+ close (copyfd);
+#endif
+ unlink_if_ordinary (tmpname);
+ }
if (output_file != tmpname)
free (tmpname);
}
@@ -5059,6 +5071,7 @@ copy_main (int argc, char *argv[])
bfd_boolean use_globalize = FALSE;
bfd_boolean use_keep_global = FALSE;
int c, tmpfd = -1;
+ int copyfd = -1;
struct stat statbuf;
const bfd_arch_info_type *input_arch = NULL;
@@ -5903,9 +5916,16 @@ copy_main (int argc, char *argv[])
else
tmpname = output_filename;
- if (tmpname == NULL)
- fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
- input_filename, strerror (errno));
+ if (tmpname == NULL
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+ /* Retain a copy of TMPFD since we will need it for SMART_RENAME. */
+ || (tmpfd >= 0 && (copyfd = dup (tmpfd)) == -1)
+#endif
+ )
+ {
+ fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
+ input_filename, strerror (errno));
+ }
copy_file (input_filename, tmpname, tmpfd, &statbuf, input_target,
output_target, input_arch);
@@ -5914,11 +5934,17 @@ copy_main (int argc, char *argv[])
if (preserve_dates)
set_times (tmpname, &statbuf);
if (tmpname != output_filename)
- status = (smart_rename (tmpname, input_filename,
+ status = (smart_rename (tmpname, input_filename, copyfd, &statbuf,
preserve_dates) != 0);
}
else
- unlink_if_ordinary (tmpname);
+ {
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+ if (copyfd >= 0)
+ close (copyfd);
+#endif
+ unlink_if_ordinary (tmpname);
+ }
if (tmpname != output_filename)
free (tmpname);
diff --git a/binutils/rename.c b/binutils/rename.c
index bf3b68d..6b9165e 100644
--- a/binutils/rename.c
+++ b/binutils/rename.c
@@ -131,17 +131,55 @@ set_times (const char *destination, const struct stat *statbuf)
#endif
#endif
-/* Rename FROM to TO, copying if TO is a link.
- Return 0 if ok, -1 if error. */
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+/* Try to preserve the permission bits and ownership of an existing file when
+ rename overwrites it. FD is the file being renamed and TARGET_STAT has the
+ status of the file that was overwritten. */
+static void
+try_preserve_permissions (int fd, struct stat *target_stat)
+{
+ struct stat from_stat;
+ int ret = 0;
+
+ if (fstat (fd, &from_stat) != 0)
+ return;
+
+ int from_mode = from_stat.st_mode & 0777;
+ int to_mode = target_stat->st_mode & 0777;
+
+ /* Fix up permissions before we potentially lose ownership with fchown.
+ Clear the setxid bits because in case the fchown below fails then we don't
+ want to end up with a sxid file owned by the invoking user. If the user
+ hasn't changed or if fchown succeeded, we add back the sxid bits at the
+ end. */
+ if (from_mode != to_mode)
+ fchmod (fd, to_mode);
+
+ /* Fix up ownership, this will clear the setxid bits. */
+ if (from_stat.st_uid != target_stat->st_uid
+ || from_stat.st_gid != target_stat->st_gid)
+ ret = fchown (fd, target_stat->st_uid, target_stat->st_gid);
+
+ /* Fix up the sxid bits if either the fchown wasn't needed or it
+ succeeded. */
+ if (ret == 0)
+ fchmod (fd, target_stat->st_mode & 07777);
+}
+#endif
+
+/* Rename FROM to TO, copying if TO is either a link or is not a regular file.
+ FD is an open file descriptor pointing to FROM that we can use to safely fix
+ up permissions of the file after renaming. TARGET_STAT has the file status
+ that is used to fix up permissions and timestamps after rename. Return 0 if
+ ok, -1 if error and FD is closed before returning. */
int
-smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED)
+smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
+ struct stat *target_stat ATTRIBUTE_UNUSED,
+ int preserve_dates ATTRIBUTE_UNUSED)
{
- bfd_boolean exists;
- struct stat s;
int ret = 0;
-
- exists = lstat (to, &s) == 0;
+ bfd_boolean exists = target_stat != NULL;
#if defined (_WIN32) && !defined (__CYGWIN32__)
/* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
@@ -158,36 +196,35 @@ smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNU
unlink (from);
}
#else
- /* Use rename only if TO is not a symbolic link and has
- only one hard link, and we have permission to write to it. */
+ /* Avoid a full copy and use rename if we can fix up permissions of the
+ file after renaming, i.e.:
+
+ - TO is not a symbolic link
+ - TO is a regular file with only one hard link
+ - We have permission to write to TO
+ - FD is available to safely fix up permissions to be the same as the file
+ we overwrote with the rename.
+
+ Note though that the actual file on disk that TARGET_STAT describes may
+ have changed and we're only trying to preserve the status we know about.
+ At no point do we try to interact with the new file changes, so there can
+ only be two outcomes, i.e. either the external file change survives
+ without knowledge of our change (if it happens after the rename syscall)
+ or our rename and permissions fixup survive without any knowledge of the
+ external change. */
if (! exists
- || (!S_ISLNK (s.st_mode)
- && S_ISREG (s.st_mode)
- && (s.st_mode & S_IWUSR)
- && s.st_nlink == 1)
+ || (fd >= 0
+ && !S_ISLNK (target_stat->st_mode)
+ && S_ISREG (target_stat->st_mode)
+ && (target_stat->st_mode & S_IWUSR)
+ && target_stat->st_nlink == 1)
)
{
ret = rename (from, to);
if (ret == 0)
{
if (exists)
- {
- /* Try to preserve the permission bits and ownership of
- TO. First get the mode right except for the setuid
- bit. Then change the ownership. Then fix the setuid
- bit. We do the chmod before the chown because if the
- chown succeeds, and we are a normal user, we won't be
- able to do the chmod afterward. We don't bother to
- fix the setuid bit first because that might introduce
- a fleeting security problem, and because the chown
- will clear the setuid bit anyhow. We only fix the
- setuid bit if the chown succeeds, because we don't
- want to introduce an unexpected setuid file owned by
- the user running objcopy. */
- chmod (to, s.st_mode & 0777);
- if (chown (to, s.st_uid, s.st_gid) >= 0)
- chmod (to, s.st_mode & 07777);
- }
+ try_preserve_permissions (fd, target_stat);
}
else
{
@@ -203,9 +240,11 @@ smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNU
non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
if (preserve_dates)
- set_times (to, &s);
+ set_times (to, target_stat);
unlink (from);
}
+ if (fd >= 0)
+ close (fd);
#endif /* _WIN32 && !__CYGWIN32__ */
return ret;
--
1.8.3.1

View File

@ -0,0 +1,33 @@
From 584294c4066d0101161e4e04744a46cce7a7863e Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Mon, 29 Nov 2021 15:37:24 +0000
Subject: [PATCH] strings: Replace references to -u option with references to
-U.
PR 28632
---
binutils/strings.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/binutils/strings.c b/binutils/strings.c
index f594299939f9..f85cb03406c9 100644
--- a/binutils/strings.c
+++ b/binutils/strings.c
@@ -57,7 +57,7 @@
Specify a non-default object file format.
--unicode={default|locale|invalid|hex|escape|highlight}
- -u {d|l|i|x|e|h}
+ -U {d|l|i|x|e|h}
Determine how to handle UTF-8 unicode characters. The default
is no special treatment. All other versions of this option
only apply if the encoding is valid and enabling the option
@@ -1333,7 +1333,7 @@ usage (FILE *stream, int status)
-e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
--unicode={default|show|invalid|hex|escape|highlight}\n\
- -u {d|s|i|x|e|h} Specify how to treat UTF-8 encoded unicode characters\n\
+ -U {d|s|i|x|e|h} Specify how to treat UTF-8 encoded unicode characters\n\
-s --output-separator=<string> String used to separate strings in output.\n\
@<file> Read options from <file>\n\
-h --help Display this information\n\

View File

@ -1,193 +0,0 @@
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

View File

@ -1,162 +0,0 @@
From 1cfcf3004e1830f8fe9112cfcd15285508d2c2b7 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Thu, 11 Feb 2021 16:56:42 +1030
Subject: [PATCH] PR27290, PR27293, PR27295, various avr objdump fixes
Adds missing sanity checks for avr device info note, to avoid
potential buffer overflows. Uses bfd_malloc_and_get_section for
sanity checking section size.
PR 27290
PR 27293
PR 27295
* od-elf32_avr.c (elf32_avr_get_note_section_contents): Formatting.
Use bfd_malloc_and_get_section.
(elf32_avr_get_note_desc): Formatting. Return descsz. Sanity
check namesz. Return NULL if descsz is too small. Ensure
string table is terminated.
(elf32_avr_get_device_info): Formatting. Add note_size param.
Sanity check note.
(elf32_avr_dump_mem_usage): Adjust to suit.
---
binutils/od-elf32_avr.c | 66 +++++++++++++++++++++++++++++++------------------
1 files changed, 56 insertions(+), 24 deletions(-)
diff --git a/binutils/od-elf32_avr.c b/binutils/od-elf32_avr.c
index 11800e7..4377a7c 100644
--- a/binutils/od-elf32_avr.c
+++ b/binutils/od-elf32_avr.c
@@ -77,23 +77,29 @@ elf32_avr_filter (bfd *abfd)
return bfd_get_flavour (abfd) == bfd_target_elf_flavour;
}
-static char*
+static char *
elf32_avr_get_note_section_contents (bfd *abfd, bfd_size_type *size)
{
asection *section;
+ bfd_byte *contents;
- if ((section = bfd_get_section_by_name (abfd, ".note.gnu.avr.deviceinfo")) == NULL)
+ section = bfd_get_section_by_name (abfd, ".note.gnu.avr.deviceinfo");
+ if (section == NULL)
return NULL;
- *size = bfd_section_size (section);
- char *contents = (char *) xmalloc (*size);
- bfd_get_section_contents (abfd, section, contents, 0, *size);
+ if (!bfd_malloc_and_get_section (abfd, section, &contents))
+ {
+ free (contents);
+ contents = NULL;
+ }
- return contents;
+ *size = bfd_section_size (section);
+ return (char *) contents;
}
-static char* elf32_avr_get_note_desc (bfd *abfd, char *contents,
- bfd_size_type size)
+static char *
+elf32_avr_get_note_desc (bfd *abfd, char *contents, bfd_size_type size,
+ bfd_size_type *descsz)
{
Elf_External_Note *xnp = (Elf_External_Note *) contents;
Elf_Internal_Note in;
@@ -107,42 +113,54 @@ static char* elf32_avr_get_note_desc (bfd *abfd, char *contents,
if (in.namesz > contents - in.namedata + size)
return NULL;
+ if (in.namesz != 4 || strcmp (in.namedata, "AVR") != 0)
+ return NULL;
+
in.descsz = bfd_get_32 (abfd, xnp->descsz);
in.descdata = in.namedata + align_power (in.namesz, 2);
- if (in.descsz != 0
- && (in.descdata >= contents + size
- || in.descsz > contents - in.descdata + size))
+ if (in.descsz < 6 * sizeof (uint32_t)
+ || in.descdata >= contents + size
+ || in.descsz > contents - in.descdata + size)
return NULL;
- if (strcmp (in.namedata, "AVR") != 0)
- return NULL;
+ /* If the note has a string table, ensure it is 0 terminated. */
+ if (in.descsz > 8 * sizeof (uint32_t))
+ in.descdata[in.descsz - 1] = 0;
+ *descsz = in.descsz;
return in.descdata;
}
static void
elf32_avr_get_device_info (bfd *abfd, char *description,
- deviceinfo *device)
+ bfd_size_type desc_size, deviceinfo *device)
{
if (description == NULL)
return;
const bfd_size_type memory_sizes = 6;
- memcpy (device, description, memory_sizes * sizeof(uint32_t));
- device->name = NULL;
+ memcpy (device, description, memory_sizes * sizeof (uint32_t));
+ desc_size -= memory_sizes * sizeof (uint32_t);
+ if (desc_size < 8)
+ return;
- uint32_t *stroffset_table = ((uint32_t *) description) + memory_sizes;
+ uint32_t *stroffset_table = (uint32_t *) description + memory_sizes;
bfd_size_type stroffset_table_size = bfd_get_32 (abfd, stroffset_table);
- char *str_table = ((char *) stroffset_table) + stroffset_table_size;
/* If the only content is the size itself, there's nothing in the table */
- if (stroffset_table_size == 4)
+ if (stroffset_table_size < 8)
return;
+ if (desc_size <= stroffset_table_size)
+ return;
+ desc_size -= stroffset_table_size;
/* First entry is the device name index. */
uint32_t device_name_index = bfd_get_32 (abfd, stroffset_table + 1);
+ if (device_name_index >= desc_size)
+ return;
+ char *str_table = (char *) stroffset_table + stroffset_table_size;
device->name = str_table + device_name_index;
}
@@ -183,7 +201,7 @@ static void
elf32_avr_dump_mem_usage (bfd *abfd)
{
char *description = NULL;
- bfd_size_type note_section_size = 0;
+ bfd_size_type sec_size, desc_size;
deviceinfo device = { 0, 0, 0, 0, 0, 0, NULL };
device.name = "Unknown";
@@ -192,13 +210,13 @@ elf32_avr_dump_mem_usage (bfd *abfd)
bfd_size_type text_usage = 0;
bfd_size_type eeprom_usage = 0;
- char *contents = elf32_avr_get_note_section_contents (abfd,
- &note_section_size);
+ char *contents = elf32_avr_get_note_section_contents (abfd, &sec_size);
if (contents != NULL)
{
- description = elf32_avr_get_note_desc (abfd, contents, note_section_size);
- elf32_avr_get_device_info (abfd, description, &device);
+ description = elf32_avr_get_note_desc (abfd, contents, sec_size,
+ &desc_size);
+ elf32_avr_get_device_info (abfd, description, desc_size, &device);
}
elf32_avr_get_memory_usage (abfd, &text_usage, &data_usage,
--
1.8.3.1

View File

@ -12,11 +12,11 @@ Subject: [PATCH] PR28694, Out-of-bounds write in stab_xcoff_builtin_type
1 file changed, 43 insertions(+), 44 deletions(-)
diff --git a/binutils/stabs.c b/binutils/stabs.c
index 90254fd..d430d4a 100644
index 274bfb0e7fa..83ee3ea5fa4 100644
--- a/binutils/stabs.c
+++ b/binutils/stabs.c
@@ -202,7 +202,7 @@ static debug_type stab_find_type (void *, struct stab_handle *, const int *);
static bfd_boolean stab_record_type
static bool stab_record_type
(void *, struct stab_handle *, const int *, debug_type);
static debug_type stab_xcoff_builtin_type
- (void *, struct stab_handle *, int);
@ -55,52 +55,52 @@ index 90254fd..d430d4a 100644
/* The size of this and all the other types are fixed, defined
by the debugging format. */
name = "int";
rettype = debug_make_int_type (dhandle, 4, FALSE);
rettype = debug_make_int_type (dhandle, 4, false);
break;
- case 2:
+ case 1:
name = "char";
rettype = debug_make_int_type (dhandle, 1, FALSE);
rettype = debug_make_int_type (dhandle, 1, false);
break;
- case 3:
+ case 2:
name = "short";
rettype = debug_make_int_type (dhandle, 2, FALSE);
rettype = debug_make_int_type (dhandle, 2, false);
break;
- case 4:
+ case 3:
name = "long";
rettype = debug_make_int_type (dhandle, 4, FALSE);
rettype = debug_make_int_type (dhandle, 4, false);
break;
- case 5:
+ case 4:
name = "unsigned char";
rettype = debug_make_int_type (dhandle, 1, TRUE);
rettype = debug_make_int_type (dhandle, 1, true);
break;
- case 6:
+ case 5:
name = "signed char";
rettype = debug_make_int_type (dhandle, 1, FALSE);
rettype = debug_make_int_type (dhandle, 1, false);
break;
- case 7:
+ case 6:
name = "unsigned short";
rettype = debug_make_int_type (dhandle, 2, TRUE);
rettype = debug_make_int_type (dhandle, 2, true);
break;
- case 8:
+ case 7:
name = "unsigned int";
rettype = debug_make_int_type (dhandle, 4, TRUE);
rettype = debug_make_int_type (dhandle, 4, true);
break;
- case 9:
+ case 8:
name = "unsigned";
rettype = debug_make_int_type (dhandle, 4, TRUE);
rettype = debug_make_int_type (dhandle, 4, true);
break;
- case 10:
+ case 9:
name = "unsigned long";
rettype = debug_make_int_type (dhandle, 4, TRUE);
rettype = debug_make_int_type (dhandle, 4, true);
break;
- case 11:
+ case 10:
@ -130,7 +130,7 @@ index 90254fd..d430d4a 100644
- case 15:
+ case 14:
name = "integer";
rettype = debug_make_int_type (dhandle, 4, FALSE);
rettype = debug_make_int_type (dhandle, 4, false);
break;
- case 16:
+ case 15:
@ -157,7 +157,7 @@ index 90254fd..d430d4a 100644
+ case 19:
/* FIXME */
name = "character";
rettype = debug_make_int_type (dhandle, 1, TRUE);
rettype = debug_make_int_type (dhandle, 1, true);
break;
- case 21:
+ case 20:
@ -194,33 +194,33 @@ index 90254fd..d430d4a 100644
- case 27:
+ case 26:
name = "integer*1";
rettype = debug_make_int_type (dhandle, 1, FALSE);
rettype = debug_make_int_type (dhandle, 1, false);
break;
- case 28:
+ case 27:
name = "integer*2";
rettype = debug_make_int_type (dhandle, 2, FALSE);
rettype = debug_make_int_type (dhandle, 2, false);
break;
- case 29:
+ case 28:
name = "integer*4";
rettype = debug_make_int_type (dhandle, 4, FALSE);
rettype = debug_make_int_type (dhandle, 4, false);
break;
- case 30:
+ case 29:
/* FIXME */
name = "wchar";
rettype = debug_make_int_type (dhandle, 2, FALSE);
rettype = debug_make_int_type (dhandle, 2, false);
break;
- case 31:
+ case 30:
name = "long long";
rettype = debug_make_int_type (dhandle, 8, FALSE);
rettype = debug_make_int_type (dhandle, 8, false);
break;
- case 32:
+ case 31:
name = "unsigned long long";
rettype = debug_make_int_type (dhandle, 8, TRUE);
rettype = debug_make_int_type (dhandle, 8, true);
break;
- case 33:
+ case 32:
@ -230,7 +230,7 @@ index 90254fd..d430d4a 100644
- case 34:
+ case 33:
name = "integer*8";
rettype = debug_make_int_type (dhandle, 8, FALSE);
rettype = debug_make_int_type (dhandle, 8, false);
break;
@@ -3664,9 +3665,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
}
@ -243,6 +243,3 @@ index 90254fd..d430d4a 100644
return rettype;
}
--
1.8.3.1

View File

@ -1,57 +0,0 @@
From b143e2d506bee1020752597f979d5af174edc36d Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
Date: Fri, 11 Dec 2020 13:27:45 +0000
Subject: [PATCH] Fix a build problem when using FreeBSD 12.
* ar.c (write_archive): Cast iostream pointer to FILE *.
* arsup.c (ar_save): Likewise.
* objcopy.c (copy_file): Likewise.
---
binutils/ChangeLog | 6 ++++++
binutils/ar.c | 2 +-
binutils/arsup.c | 2 +-
binutils/objcopy.c | 2 +-
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/binutils/ar.c b/binutils/ar.c
index 6598dd9..8329223 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1305,7 +1305,7 @@ write_archive (bfd *iarch)
ofd = dup (ofd);
if (iarch == NULL || iarch->iostream == NULL)
skip_stat = TRUE;
- else if (ofd == -1 || fstat (fileno (iarch->iostream), &target_stat) != 0)
+ else if (ofd == -1 || fstat (fileno ((FILE *) iarch->iostream), &target_stat) != 0)
bfd_fatal (old_name);
#endif
diff --git a/binutils/arsup.c b/binutils/arsup.c
index 8b4437f..dad4174 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -355,7 +355,7 @@ 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 (obfd->iostream));
+ ofd = dup (fileno ((FILE *) obfd->iostream));
if (lstat (real_name, &target_stat) != 0)
skip_stat = TRUE;
#endif
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 06ecf3e..0ea3ea1 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -3745,7 +3745,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 (ibfd->iostream), in_stat) != 0)
+ if (ibfd == NULL || fstat (fileno ((FILE *) ibfd->iostream), in_stat) != 0)
{
bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
status = 1;
--
1.8.3.1

View File

@ -1,463 +0,0 @@
From 0d64622696e02ad649d048f4af3a3f293481f89f Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Thu, 11 Nov 2021 20:21:32 +1030
Subject: [PATCH] Fix demangle style usage info
Extract allowed styles from libiberty, so we don't have to worry about
our help messages getting out of date. The function probably belongs
in libiberty/cplus-dem.c but it can be here for a while to iron out
bugs.
PR 28581
* demanguse.c: New file.
* demanguse.h: New file.
* nm.c (usage): Break up output. Use display_demangler_styles.
* objdump.c (usage): Use display_demangler_styles.
* readelf.c (usage): Likewise.
* Makefile.am: Add demanguse.c and demanguse.h.
* Makefile.in: Regenerate.
* po/POTFILESin: Regenerate.
---
binutils/Makefile.am | 10 ++--
binutils/Makefile.in | 19 ++++---
binutils/demanguse.c | 54 +++++++++++++++++++
binutils/demanguse.h | 34 ++++++++++++
binutils/nm.c | 113 ++++++++++++++++++++++++++--------------
binutils/objdump.c | 8 +--
binutils/po/POTFILES.in | 2 +
binutils/readelf.c | 8 +--
8 files changed, 188 insertions(+), 60 deletions(-)
create mode 100644 binutils/demanguse.c
create mode 100644 binutils/demanguse.h
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index 00416cb635e..7f4c24c213b 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -122,7 +122,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \
HFILES = \
arsup.h binemul.h bucomm.h budbg.h \
- coffgrok.h debug.h dlltool.h dwarf.h elfcomm.h \
+ coffgrok.h debug.h demanguse.h dlltool.h dwarf.h elfcomm.h \
objdump.h sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
windmc.h
@@ -132,7 +132,7 @@ BUILT_SOURCES = $(GENERATED_HFILES)
CFILES = \
addr2line.c ar.c arsup.c bin2c.c binemul.c bucomm.c \
coffdump.c coffgrok.c cxxfilt.c \
- dwarf.c debug.c dlltool.c dllwrap.c \
+ dwarf.c debug.c demanguse.c dlltool.c dllwrap.c \
elfcomm.c emul_aix.c emul_vanilla.c filemode.c \
is-ranlib.c is-strip.c maybe-ranlib.c maybe-strip.c \
nm.c not-ranlib.c not-strip.c \
@@ -252,7 +252,7 @@ objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
strings_SOURCES = strings.c $(BULIBS)
-readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c $(ELFLIBS)
+readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS)
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
@@ -260,9 +260,9 @@ elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
-nm_new_SOURCES = nm.c $(BULIBS)
+nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
-objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
+objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
EXTRA_objdump_SOURCES = od-xcoff.c
objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS)
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index bed8fef64d8..5252ef18b5c 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -212,7 +212,7 @@ am__objects_2 = elfcomm.$(OBJEXT)
am_elfedit_OBJECTS = elfedit.$(OBJEXT) version.$(OBJEXT) \
$(am__objects_2)
elfedit_OBJECTS = $(am_elfedit_OBJECTS)
-am_nm_new_OBJECTS = nm.$(OBJEXT) $(am__objects_1)
+am_nm_new_OBJECTS = nm.$(OBJEXT) demanguse.$(OBJEXT) $(am__objects_1)
nm_new_OBJECTS = $(am_nm_new_OBJECTS)
nm_new_LDADD = $(LDADD)
am__objects_3 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \
@@ -223,7 +223,8 @@ am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \
objcopy_OBJECTS = $(am_objcopy_OBJECTS)
objcopy_LDADD = $(LDADD)
am_objdump_OBJECTS = objdump.$(OBJEXT) dwarf.$(OBJEXT) prdbg.$(OBJEXT) \
- $(am__objects_3) $(am__objects_1) $(am__objects_2)
+ demanguse.$(OBJEXT) $(am__objects_3) $(am__objects_1) \
+ $(am__objects_2)
objdump_OBJECTS = $(am_objdump_OBJECTS)
@ENABLE_LIBCTF_TRUE@am__DEPENDENCIES_2 = ../libctf/libctf.la
am_ranlib_OBJECTS = ar.$(OBJEXT) is-ranlib.$(OBJEXT) arparse.$(OBJEXT) \
@@ -231,7 +232,8 @@ am_ranlib_OBJECTS = ar.$(OBJEXT) is-ranlib.$(OBJEXT) arparse.$(OBJEXT) \
binemul.$(OBJEXT) emul_$(EMULATION).$(OBJEXT) $(am__objects_1)
ranlib_OBJECTS = $(am_ranlib_OBJECTS)
am_readelf_OBJECTS = readelf.$(OBJEXT) version.$(OBJEXT) \
- unwind-ia64.$(OBJEXT) dwarf.$(OBJEXT) $(am__objects_2)
+ unwind-ia64.$(OBJEXT) dwarf.$(OBJEXT) demanguse.$(OBJEXT) \
+ $(am__objects_2)
readelf_OBJECTS = $(am_readelf_OBJECTS)
@ENABLE_LIBCTF_TRUE@am__DEPENDENCIES_3 = ../libctf/libctf-nobfd.la
am_size_OBJECTS = size.$(OBJEXT) $(am__objects_1)
@@ -632,7 +634,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \
HFILES = \
arsup.h binemul.h bucomm.h budbg.h \
- coffgrok.h debug.h dlltool.h dwarf.h elfcomm.h \
+ coffgrok.h debug.h demanguse.h dlltool.h dwarf.h elfcomm.h \
objdump.h sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
windmc.h
@@ -641,7 +643,7 @@ BUILT_SOURCES = $(GENERATED_HFILES)
CFILES = \
addr2line.c ar.c arsup.c bin2c.c binemul.c bucomm.c \
coffdump.c coffgrok.c cxxfilt.c \
- dwarf.c debug.c dlltool.c dllwrap.c \
+ dwarf.c debug.c demanguse.c dlltool.c dllwrap.c \
elfcomm.c emul_aix.c emul_vanilla.c filemode.c \
is-ranlib.c is-strip.c maybe-ranlib.c maybe-strip.c \
nm.c not-ranlib.c not-strip.c \
@@ -720,13 +722,13 @@ LDADD = $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
size_SOURCES = size.c $(BULIBS)
objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
strings_SOURCES = strings.c $(BULIBS)
-readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c $(ELFLIBS)
+readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS)
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
-nm_new_SOURCES = nm.c $(BULIBS)
-objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
+nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
+objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
EXTRA_objdump_SOURCES = od-xcoff.c
objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS)
cxxfilt_SOURCES = cxxfilt.c $(BULIBS)
@@ -1049,6 +1051,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deflex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defparse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demanguse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlltool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dllwrap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf.Po@am__quote@
diff --git a/binutils/demanguse.c b/binutils/demanguse.c
new file mode 100644
index 00000000000..578a3ef56fe
--- /dev/null
+++ b/binutils/demanguse.c
@@ -0,0 +1,54 @@
+/* demanguse.c -- libiberty demangler usage
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <stdio.h>
+#include <string.h>
+#include "demangle.h"
+#include "demanguse.h"
+
+/* Print the list of demangling styles to STREAM. A one line MSG is
+ printed before the styles. Output is limited to 80 columns, with
+ continuation lines being indented by leading spaces in MSG. */
+
+void
+display_demangler_styles (FILE *stream, const char *msg)
+{
+ const struct demangler_engine *info = libiberty_demanglers;
+ int col;
+ int lead_spaces = 0;
+ const char *cont = "";
+
+ while (msg[lead_spaces] == ' ')
+ ++lead_spaces;
+ col = fprintf (stream, "%s", msg);
+ while (info->demangling_style_name)
+ {
+ if (col + strlen (info->demangling_style_name) >= 75)
+ {
+ fprintf (stream, "%.1s\n", cont);
+ col = fprintf (stream, "%.*s", lead_spaces, msg);
+ cont = "";
+ }
+ col += fprintf (stream, "%s\"%s\"", cont, info->demangling_style_name);
+ cont = ", ";
+ ++info;
+ }
+ fprintf (stream, "\n");
+}
diff --git a/binutils/demanguse.h b/binutils/demanguse.h
new file mode 100644
index 00000000000..965f116682d
--- /dev/null
+++ b/binutils/demanguse.h
@@ -0,0 +1,34 @@
+/* demanguse.h -- libiberty demangler usage
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef DEMANGUSE_H
+#define DEMANGUSE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void display_demangler_styles (FILE *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DEMANGUSE_H */
diff --git a/binutils/nm.c b/binutils/nm.c
index acfdf665..854aafd6 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -36,6 +36,7 @@
#include "coff/internal.h"
#include "libcoff.h"
#include "bucomm.h"
+#include "demanguse.h"
#include "plugin-api.h"
#include "plugin.h"
@@ -247,50 +248,87 @@ usage (FILE *stream, int status)
{
fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
fprintf (stream, _(" List symbols in [file(s)] (a.out by default).\n"));
- fprintf (stream, _(" The options are:\n\
- -a, --debug-syms Display debugger-only symbols\n\
- -A, --print-file-name Print name of the input file before every symbol\n\
- -B Same as --format=bsd\n\
- -C, --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
- The STYLE, if specified, can be `auto' (the default),\n\
- `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
- or `gnat'\n\
- --no-demangle Do not demangle low-level symbol names\n\
- --recurse-limit Enable a demangling recursion limit. This is the default.\n\
- --no-recurse-limit Disable a demangling recursion limit.\n\
- -D, --dynamic Display dynamic symbols instead of normal symbols\n\
- --defined-only Display only defined symbols\n\
- -e (ignored)\n\
+ fprintf (stream, _(" The options are:\n"));
+ fprintf (stream, _("\
+ -a, --debug-syms Display debugger-only symbols\n"));
+ fprintf (stream, _("\
+ -A, --print-file-name Print name of the input file before every symbol\n"));
+ fprintf (stream, _("\
+ -B Same as --format=bsd\n"));
+ fprintf (stream, _("\
+ -C, --demangle[=STYLE] Decode mangled/processed symbol names\n"));
+ display_demangler_styles (stream, _("\
+ STYLE can be "));
+ fprintf (stream, _("\
+ --no-demangle Do not demangle low-level symbol names\n"));
+ fprintf (stream, _("\
+ --recurse-limit Enable a demangling recursion limit. (default)\n"));
+ fprintf (stream, _("\
+ --no-recurse-limit Disable a demangling recursion limit.\n"));
+ fprintf (stream, _("\
+ -D, --dynamic Display dynamic symbols instead of normal symbols\n"));
+ fprintf (stream, _("\
+ --defined-only Display only defined symbols\n"));
+ fprintf (stream, _("\
+ -e (ignored)\n"));
+ fprintf (stream, _("\
-f, --format=FORMAT Use the output format FORMAT. FORMAT can be `bsd',\n\
- `sysv' or `posix'. The default is `bsd'\n\
- -g, --extern-only Display only external symbols\n\
- --ifunc-chars=CHARS Characters to use when displaying ifunc symbols\n\
+ `sysv', `posix' or 'just-symbols'.\n\
+ The default is `bsd'\n"));
+ fprintf (stream, _("\
+ -g, --extern-only Display only external symbols\n"));
+ fprintf (stream, _("\
+ --ifunc-chars=CHARS Characters to use when displaying ifunc symbols\n"));
+ fprintf (stream, _("\
+ -j, --just-symbols Same as --format=just-symbols\n"));
+ fprintf (stream, _("\
-l, --line-numbers Use debugging information to find a filename and\n\
- line number for each symbol\n\
- -n, --numeric-sort Sort symbols numerically by address\n\
- -o Same as -A\n\
- -p, --no-sort Do not sort the symbols\n\
- -P, --portability Same as --format=posix\n\
+ line number for each symbol\n"));
+ fprintf (stream, _("\
+ -n, --numeric-sort Sort symbols numerically by address\n"));
+ fprintf (stream, _("\
+ -o Same as -A\n"));
+ fprintf (stream, _("\
+ -p, --no-sort Do not sort the symbols\n"));
+ fprintf (stream, _("\
+ -P, --portability Same as --format=posix\n"));
+ fprintf (stream, _("\
-r, --reverse-sort Reverse the sense of the sort\n"));
#if BFD_SUPPORTS_PLUGINS
fprintf (stream, _("\
--plugin NAME Load the specified plugin\n"));
#endif
fprintf (stream, _("\
- -S, --print-size Print size of defined symbols\n\
- -s, --print-armap Include index for symbols from archive members\n\
- --size-sort Sort symbols by size\n\
- --special-syms Include special symbols in the output\n\
- --synthetic Display synthetic symbols as well\n\
- -t, --radix=RADIX Use RADIX for printing symbol values\n\
- --target=BFDNAME Specify the target object format as BFDNAME\n\
- -u, --undefined-only Display only undefined symbols\n\
- --with-symbol-versions Display version strings after symbol names\n\
- -X 32_64 (ignored)\n\
- @FILE Read options from FILE\n\
- -h, --help Display this information\n\
- -V, --version Display this program's version number\n\
-\n"));
+ -S, --print-size Print size of defined symbols\n"));
+ fprintf (stream, _("\
+ -s, --print-armap Include index for symbols from archive members\n"));
+ fprintf (stream, _("\
+ --quiet Suppress \"no symbols\" diagnostic\n"));
+ fprintf (stream, _("\
+ --size-sort Sort symbols by size\n"));
+ fprintf (stream, _("\
+ --special-syms Include special symbols in the output\n"));
+ fprintf (stream, _("\
+ --synthetic Display synthetic symbols as well\n"));
+ fprintf (stream, _("\
+ -t, --radix=RADIX Use RADIX for printing symbol values\n"));
+ fprintf (stream, _("\
+ --target=BFDNAME Specify the target object format as BFDNAME\n"));
+ fprintf (stream, _("\
+ -u, --undefined-only Display only undefined symbols\n"));
+ fprintf (stream, _("\
+ --unicode={default|show|invalid|hex|escape|highlight}\n"));
+ fprintf (stream, _("\
+ --with-symbol-versions Display version strings after symbol names\n"));
+ fprintf (stream, _("\
+ -X 32_64 (ignored)\n"));
+ fprintf (stream, _("\
+ @FILE Read options from FILE\n"));
+ fprintf (stream, _("\
+ -h, --help Display this information\n"));
+ fprintf (stream, _("\
+ -V, --version Display this program's version number\n"));
+
list_supported_targets (program_name, stream);
if (REPORT_BUGS_TO[0] && status == 0)
fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 2cd0d84c..09a91c04 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -55,6 +55,7 @@
#include "progress.h"
#include "bucomm.h"
#include "elfcomm.h"
+#include "demanguse.h"
#include "dwarf.h"
#include "ctf-api.h"
#include "getopt.h"
@@ -266,11 +267,12 @@ usage (FILE *stream, int status)
--file-start-context Include context from start of file (with -S)\n\
-I, --include=DIR Add DIR to search list for source files\n\
-l, --line-numbers Include line numbers and filenames in output\n\
- -F, --file-offsets Include file offsets when displaying information\n\
- -C, --demangle[=STYLE] Decode mangled/processed symbol names\n\
- The STYLE, if specified, can be `auto', `gnu',\n\
- `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
- or `gnat'\n\
+ -F, --file-offsets Include file offsets when displaying information\n"));
+ fprintf (stream, _("\
+ -C, --demangle[=STYLE] Decode mangled/processed symbol names\n"));
+ display_demangler_styles (stream, _("\
+ STYLE can be "));
+ fprintf (stream, _("\
--recurse-limit Enable a limit on recursion whilst demangling. [Default]\n\
--no-recurse-limit Disable a limit on recursion whilst demangling\n\
-w, --wide Format output for more than 80 columns\n\
diff --git a/binutils/po/POTFILES.in b/binutils/po/POTFILES.in
index 9a1443fbf19..376f1340c3f 100644
--- a/binutils/po/POTFILES.in
+++ b/binutils/po/POTFILES.in
@@ -15,6 +15,8 @@ cxxfilt.c
debug.c
debug.c
debug.h
+demanguse.c
+demanguse.h
dlltool.c
dlltool.h
dllwrap.c
diff --git a/binutils/readelf.c b/binutils/readelf.c
index ad16b457..4c5351d9 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -59,6 +59,7 @@
#include "bfd.h"
#include "bucomm.h"
#include "elfcomm.h"
+#include "demanguse.h"
#include "dwarf.h"
#include "ctf-api.h"
#include "demangle.h"
@@ -4600,11 +4601,12 @@ usage (FILE * stream)
-s --syms Display the symbol table\n\
--symbols An alias for --syms\n\
--dyn-syms Display the dynamic symbol table\n\
- --lto-syms Display LTO symbol tables\n\
- -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
- The STYLE, if specified, can be `auto' (the default),\n\
- `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
- or `gnat'\n\
+ --lto-syms Display LTO symbol tables\n"));
+ fprintf (stream, _("\
+ -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
+ display_demangler_styles (stream, _("\
+ STYLE can be "));
+ fprintf (stream, _("\
--no-demangle Do not demangle low-level symbol names. (This is the default)\n\
--recurse-limit Enable a demangling recursion limit. (This is the default)\n\
--no-recurse-limit Disable a demangling recursion limit\n\
--
2.27.0

View File

@ -1,27 +0,0 @@
From c180f095f32ca62f138da9bc7fb96cac0365fb5d Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Fri, 5 Feb 2021 12:59:16 +1030
Subject: [PATCH] PR27345, binutils/arsup.c: lstat() not available on all
targets
We can just use stat here, the same as is done in ar.c:open_inarch.
PR 27345
* arsup.c (ar_save): Use stat rather than lstat.
---
binutils/arsup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/binutils/arsup.c b/binutils/arsup.c
index a60629f67618..fa7706f79e50 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -357,7 +357,7 @@ ar_save (void)
#endif
bfd_close (obfd);
- if (lstat (real_name, &target_stat) != 0)
+ if (stat (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

View File

@ -1,59 +0,0 @@
From 51a25252814f8b6f88ff5999a091e47ca1dbdeb9 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Fri, 5 Feb 2021 22:33:08 +1030
Subject: [PATCH] PR27349, ar breaks symlinks
PR 27349
* rename.c (smart_rename): Test for existence and type of output
file with lstat.
---
binutils/rename.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/binutils/rename.c b/binutils/rename.c
index fece31179153..e36b75132ded 100644
--- a/binutils/rename.c
+++ b/binutils/rename.c
@@ -179,7 +179,10 @@ smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
int preserve_dates ATTRIBUTE_UNUSED)
{
int ret = 0;
- bfd_boolean exists = target_stat != NULL;
+ struct stat to_stat;
+ bfd_boolean exists;
+
+ exists = lstat (to, &to_stat) == 0;
#if defined (_WIN32) && !defined (__CYGWIN32__)
/* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
@@ -214,16 +217,16 @@ smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
external change. */
if (! exists
|| (fd >= 0
- && !S_ISLNK (target_stat->st_mode)
- && S_ISREG (target_stat->st_mode)
- && (target_stat->st_mode & S_IWUSR)
- && target_stat->st_nlink == 1)
+ && !S_ISLNK (to_stat.st_mode)
+ && S_ISREG (to_stat.st_mode)
+ && (to_stat.st_mode & S_IWUSR)
+ && to_stat.st_nlink == 1)
)
{
ret = rename (from, to);
if (ret == 0)
{
- if (exists)
+ if (exists && target_stat != NULL)
try_preserve_permissions (fd, target_stat);
}
else
@@ -239,7 +242,7 @@ smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
if (ret != 0)
non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
- if (preserve_dates)
+ if (preserve_dates && target_stat != NULL)
set_times (to, target_stat);
unlink (from);
}

View File

@ -1,162 +0,0 @@
From cca8873dd5a6015d5557ea44bc1ea9c252435a29 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Tue, 23 Feb 2021 09:37:39 +1030
Subject: [PATCH] PR27456, lstat in rename.c on MinGW
PR 27456
* rename.c: Tidy throughout.
(smart_rename): Always copy. Remove windows specific code.
---
binutils/rename.c | 111 ++++++++++++++-------------------------------
1 file changed, 35 insertions(+), 76 deletions(-)
diff --git a/binutils/rename.c b/binutils/rename.c
index 2ff092ee22b5..72a9323d72c4 100644
--- a/binutils/rename.c
+++ b/binutils/rename.c
@@ -24,14 +24,9 @@
#ifdef HAVE_GOOD_UTIME_H
#include <utime.h>
-#else /* ! HAVE_GOOD_UTIME_H */
-#ifdef HAVE_UTIMES
+#elif defined HAVE_UTIMES
#include <sys/time.h>
-#endif /* HAVE_UTIMES */
-#endif /* ! HAVE_GOOD_UTIME_H */
-
-#if ! defined (_WIN32) || defined (__CYGWIN32__)
-static int simple_copy (const char *, const char *);
+#endif
/* The number of bytes to copy at once. */
#define COPY_BUF 8192
@@ -82,7 +77,6 @@ simple_copy (const char *from, const char *to)
}
return 0;
}
-#endif /* __CYGWIN32__ or not _WIN32 */
/* Set the times of the file DESTINATION to be the same as those in
STATBUF. */
@@ -91,87 +85,52 @@ void
set_times (const char *destination, const struct stat *statbuf)
{
int result;
-
- {
#ifdef HAVE_GOOD_UTIME_H
- struct utimbuf tb;
-
- tb.actime = statbuf->st_atime;
- tb.modtime = statbuf->st_mtime;
- result = utime (destination, &tb);
-#else /* ! HAVE_GOOD_UTIME_H */
-#ifndef HAVE_UTIMES
- long tb[2];
-
- tb[0] = statbuf->st_atime;
- tb[1] = statbuf->st_mtime;
- result = utime (destination, tb);
-#else /* HAVE_UTIMES */
- struct timeval tv[2];
-
- tv[0].tv_sec = statbuf->st_atime;
- tv[0].tv_usec = 0;
- tv[1].tv_sec = statbuf->st_mtime;
- tv[1].tv_usec = 0;
- result = utimes (destination, tv);
-#endif /* HAVE_UTIMES */
-#endif /* ! HAVE_GOOD_UTIME_H */
- }
+ struct utimbuf tb;
+
+ tb.actime = statbuf->st_atime;
+ tb.modtime = statbuf->st_mtime;
+ result = utime (destination, &tb);
+#elif defined HAVE_UTIMES
+ struct timeval tv[2];
+
+ tv[0].tv_sec = statbuf->st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = statbuf->st_mtime;
+ tv[1].tv_usec = 0;
+ result = utimes (destination, tv);
+#else
+ long tb[2];
+
+ tb[0] = statbuf->st_atime;
+ tb[1] = statbuf->st_mtime;
+ result = utime (destination, tb);
+#endif
if (result != 0)
non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
}
-/* Rename FROM to TO, copying if TO exists. TARGET_STAT has the file status
- that, if non-NULL, is used to fix up timestamps after rename. Return 0 if
- ok, -1 if error. */
+/* Copy FROM to TO. TARGET_STAT has the file status that, if non-NULL,
+ is used to fix up timestamps. Return 0 if ok, -1 if error.
+ At one time this function renamed files, but file permissions are
+ tricky to update given the number of different schemes used by
+ various systems. So now we just copy. */
int
smart_rename (const char *from, const char *to,
- struct stat *target_stat ATTRIBUTE_UNUSED)
+ struct stat *target_stat)
{
- int ret = 0;
- struct stat to_stat;
- bfd_boolean exists;
-
- exists = lstat (to, &to_stat) == 0;
-
-#if defined (_WIN32) && !defined (__CYGWIN32__)
- /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
- fail instead. Also, chown is not present. */
-
- if (exists)
- remove (to);
+ int ret;
- ret = rename (from, to);
+ ret = simple_copy (from, to);
if (ret != 0)
- {
- /* We have to clean up here. */
- non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
- unlink (from);
- }
-#else
- /* Avoid a full copy and use rename if TO does not exist. */
- if (!exists)
- {
- if ((ret = rename (from, to)) != 0)
- {
- /* We have to clean up here. */
- non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
- unlink (from);
- }
- }
- else
- {
- ret = simple_copy (from, to);
- if (ret != 0)
- non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
+ non_fatal (_("unable to copy file '%s'; reason: %s"),
+ to, strerror (errno));
- if (target_stat != NULL)
- set_times (to, target_stat);
- unlink (from);
- }
-#endif /* _WIN32 && !__CYGWIN32__ */
+ if (target_stat != NULL)
+ set_times (to, target_stat);
+ unlink (from);
return ret;
}

View File

@ -1,320 +0,0 @@
From c42c71a1527dd70417d3966dce7ba9edbcf4bdb4 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Tue, 23 Feb 2021 12:10:58 +1030
Subject: [PATCH] Use make_tempname file descriptor in smart_rename
This patch makes use of the temp file descriptor in smart_rename
rather than reopening the file. I don't believe there is a security
issue in reopening the file, but this way is one less directory
operation. The patch also attempts to preserve S_ISUID and S_ISGID.
PR 27456
* bucomm.h (smart_rename): Update prototype.
* rename.c (smart_rename): Add fromfd and preserve_dates params.
Pass fromfd and target_stat to simple_copy. Call set_times
when preserve_dates.
(simple_copy): Accept fromfd rather than from filename. Add
target_stat param. Rewind fromfd rather than opening. Open
"to" file without O_CREAT. Try to preserve S_ISUID and S_ISGID.
* ar.c (write_archive): Rename ofd to tmpfd. Dup tmpfd before
closing output temp file, and pass tmpfd to smart_rename.
* arsup.c (temp_fd): Rename from real_fd.
(ar_save): Dup temp_fd and pass to smart_rename.
* objcopy.c (strip_main, copy_main): Likewise, and pass
preserve_dates.
---
binutils/ar.c | 11 ++++++-----
binutils/arsup.c | 9 +++++----
binutils/bucomm.h | 3 ++-
binutils/objcopy.c | 42 +++++++++++++++++++++++++++++++-----------
binutils/rename.c | 35 +++++++++++++++++++++--------------
5 files changed, 65 insertions(+), 35 deletions(-)
diff --git a/binutils/ar.c b/binutils/ar.c
index 44df48c5c677..fb19b14fec57 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1252,21 +1252,21 @@ write_archive (bfd *iarch)
bfd *obfd;
char *old_name, *new_name;
bfd *contents_head = iarch->archive_next;
- int ofd = -1;
+ int tmpfd = -1;
old_name = xstrdup (bfd_get_filename (iarch));
- new_name = make_tempname (old_name, &ofd);
+ new_name = make_tempname (old_name, &tmpfd);
if (new_name == NULL)
bfd_fatal (_("could not create temporary file whilst writing archive"));
output_filename = new_name;
- obfd = bfd_fdopenw (new_name, bfd_get_target (iarch), ofd);
+ obfd = bfd_fdopenw (new_name, bfd_get_target (iarch), tmpfd);
if (obfd == NULL)
{
- close (ofd);
+ close (tmpfd);
bfd_fatal (old_name);
}
@@ -1297,6 +1297,7 @@ write_archive (bfd *iarch)
if (!bfd_set_archive_head (obfd, contents_head))
bfd_fatal (old_name);
+ tmpfd = dup (tmpfd);
if (!bfd_close (obfd))
bfd_fatal (old_name);
@@ -1306,7 +1307,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, NULL) != 0)
+ if (smart_rename (new_name, old_name, tmpfd, NULL, FALSE) != 0)
xexit (1);
free (old_name);
free (new_name);
diff --git a/binutils/arsup.c b/binutils/arsup.c
index f7ce8f0bc820..9982484dbe0c 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -43,7 +43,7 @@ extern int deterministic;
static bfd *obfd;
static char *real_name;
static char *temp_name;
-static int real_ofd;
+static int temp_fd;
static FILE *outfile;
static void
@@ -152,7 +152,7 @@ void
ar_open (char *name, int t)
{
real_name = xstrdup (name);
- temp_name = make_tempname (real_name, &real_ofd);
+ temp_name = make_tempname (real_name, &temp_fd);
if (temp_name == NULL)
{
@@ -162,7 +162,7 @@ ar_open (char *name, int t)
return;
}
- obfd = bfd_fdopenw (temp_name, NULL, real_ofd);
+ obfd = bfd_fdopenw (temp_name, NULL, temp_fd);
if (!obfd)
{
@@ -348,6 +348,7 @@ ar_save (void)
if (deterministic > 0)
obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
+ temp_fd = dup (temp_fd);
bfd_close (obfd);
if (stat (real_name, &target_stat) != 0)
@@ -363,7 +364,7 @@ ar_save (void)
}
}
- smart_rename (temp_name, real_name, NULL);
+ smart_rename (temp_name, real_name, temp_fd, NULL, FALSE);
obfd = 0;
free (temp_name);
free (real_name);
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
index aa7e33d8cd15..f1ae47fa1b56 100644
--- a/binutils/bucomm.h
+++ b/binutils/bucomm.h
@@ -71,7 +71,8 @@ extern void print_version (const char *);
/* In rename.c. */
extern void set_times (const char *, const struct stat *);
-extern int smart_rename (const char *, const char *, struct stat *);
+extern int smart_rename (const char *, const char *, int,
+ struct stat *, bfd_boolean);
/* In libiberty. */
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index abbcb7c51907..90ae0bd46bd0 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -4837,6 +4837,7 @@ strip_main (int argc, char *argv[])
struct stat statbuf;
char *tmpname;
int tmpfd = -1;
+ int copyfd = -1;
if (get_file_size (argv[i]) < 1)
{
@@ -4846,7 +4847,11 @@ strip_main (int argc, char *argv[])
if (output_file == NULL
|| filename_cmp (argv[i], output_file) == 0)
- tmpname = make_tempname (argv[i], &tmpfd);
+ {
+ tmpname = make_tempname (argv[i], &tmpfd);
+ if (tmpfd >= 0)
+ copyfd = dup (tmpfd);
+ }
else
tmpname = output_file;
@@ -4864,14 +4869,18 @@ strip_main (int argc, char *argv[])
if (status == 0)
{
if (output_file != tmpname)
- status = (smart_rename (tmpname,
- output_file ? output_file : argv[i],
- preserve_dates ? &statbuf : NULL) != 0);
+ status = smart_rename (tmpname,
+ output_file ? output_file : argv[i],
+ copyfd, &statbuf, preserve_dates) != 0;
if (status == 0)
status = hold_status;
}
else
- unlink_if_ordinary (tmpname);
+ {
+ if (copyfd >= 0)
+ close (copyfd);
+ unlink_if_ordinary (tmpname);
+ }
if (output_file != tmpname)
free (tmpname);
}
@@ -5078,7 +5087,9 @@ copy_main (int argc, char *argv[])
bfd_boolean formats_info = FALSE;
bfd_boolean use_globalize = FALSE;
bfd_boolean use_keep_global = FALSE;
- int c, tmpfd = -1;
+ int c;
+ int tmpfd = -1;
+ int copyfd;
struct stat statbuf;
const bfd_arch_info_type *input_arch = NULL;
@@ -5916,10 +5927,15 @@ copy_main (int argc, char *argv[])
}
/* If there is no destination file, or the source and destination files
- are the same, then create a temp and rename the result into the input. */
+ are the same, then create a temp and copy the result into the input. */
+ copyfd = -1;
if (output_filename == NULL
|| filename_cmp (input_filename, output_filename) == 0)
- tmpname = make_tempname (input_filename, &tmpfd);
+ {
+ tmpname = make_tempname (input_filename, &tmpfd);
+ if (tmpfd >= 0)
+ copyfd = dup (tmpfd);
+ }
else
tmpname = output_filename;
@@ -5934,11 +5950,15 @@ copy_main (int argc, char *argv[])
if (status == 0)
{
if (tmpname != output_filename)
- status = (smart_rename (tmpname, input_filename,
- preserve_dates ? &statbuf : NULL) != 0);
+ status = smart_rename (tmpname, input_filename, copyfd,
+ &statbuf, preserve_dates) != 0;
}
else
- unlink_if_ordinary (tmpname);
+ {
+ if (copyfd >= 0)
+ close (copyfd);
+ unlink_if_ordinary (tmpname);
+ }
if (tmpname != output_filename)
free (tmpname);
diff --git a/binutils/rename.c b/binutils/rename.c
index 72a9323d72c4..f688f350d51f 100644
--- a/binutils/rename.c
+++ b/binutils/rename.c
@@ -31,24 +31,21 @@
/* The number of bytes to copy at once. */
#define COPY_BUF 8192
-/* Copy file FROM to file TO, performing no translations.
+/* Copy file FROMFD to file TO, performing no translations.
Return 0 if ok, -1 if error. */
static int
-simple_copy (const char *from, const char *to)
+simple_copy (int fromfd, const char *to, struct stat *target_stat)
{
- int fromfd, tofd, nread;
+ int tofd, nread;
int saved;
char buf[COPY_BUF];
- fromfd = open (from, O_RDONLY | O_BINARY);
- if (fromfd < 0)
+ if (fromfd < 0
+ || lseek (fromfd, 0, SEEK_SET) != 0)
return -1;
-#ifdef O_CREAT
- tofd = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0777);
-#else
- tofd = creat (to, 0777);
-#endif
+
+ tofd = open (to, O_WRONLY | O_TRUNC | O_BINARY);
if (tofd < 0)
{
saved = errno;
@@ -56,6 +53,7 @@ simple_copy (const char *from, const char *to)
errno = saved;
return -1;
}
+
while ((nread = read (fromfd, buf, sizeof buf)) > 0)
{
if (write (tofd, buf, nread) != nread)
@@ -67,7 +65,16 @@ simple_copy (const char *from, const char *to)
return -1;
}
}
+
saved = errno;
+
+#if !defined (_WIN32) || defined (__CYGWIN32__)
+ /* Writing to a setuid/setgid file may clear S_ISUID and S_ISGID.
+ Try to restore them, ignoring failure. */
+ if (target_stat != NULL)
+ fchmod (tofd, target_stat->st_mode);
+#endif
+
close (fromfd);
close (tofd);
if (nread < 0)
@@ -118,17 +125,17 @@ set_times (const char *destination, const struct stat *statbuf)
various systems. So now we just copy. */
int
-smart_rename (const char *from, const char *to,
- struct stat *target_stat)
+smart_rename (const char *from, const char *to, int fromfd,
+ struct stat *target_stat, bfd_boolean preserve_dates)
{
int ret;
- ret = simple_copy (from, to);
+ ret = simple_copy (fromfd, to, target_stat);
if (ret != 0)
non_fatal (_("unable to copy file '%s'; reason: %s"),
to, strerror (errno));
- if (target_stat != NULL)
+ if (preserve_dates)
set_times (to, target_stat);
unlink (from);

View File

@ -1,353 +0,0 @@
From 3685de750e6a091663a0abe42528cad29e960e35 Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@gotplt.org>
Date: Fri, 19 Feb 2021 08:05:33 +0530
Subject: [PATCH] binutils: Avoid renaming over existing files
Renaming over existing files needs additional care to restore
permissions and ownership, which may not always succeed.
Additionally, other properties of the file such as extended attributes
may be lost, making the operation flaky.
For predictable results, resort to rename() only if the file does not
exist, otherwise copy the file contents into the existing file. This
ensures that no additional tricks are needed to retain file
properties.
This also allows dropping of the redundant set_times on the tmpfile in
objcopy/strip since now we no longer rename over existing files.
binutils/
* ar.c (write_archive): Remove TARGET_STAT. Adjust call to
SMART_RENAME.
* arsup.c (ar_save): Likewise.
* objcopy (strip_main): Don't copy TMPFD. Don't set times on
temporary file and adjust call to SMART_RENAME.
(copy_main): Likewise.
* rename.c [!S_ISLNK]: Remove definitions.
(try_preserve_permissions): Remove function.
(smart_rename): Remove FD, PRESERVE_DATES arguments. Use
rename system call only if TO does not exist.
* bucomm.h (smart_rename): Adjust declaration.
---
binutils/ar.c | 9 +----
binutils/arsup.c | 13 +------
binutils/bucomm.h | 2 +-
binutils/objcopy.c | 42 ++++----------------
binutils/rename.c | 95 +++++-----------------------------------------
5 files changed, 19 insertions(+), 142 deletions(-)
diff --git a/binutils/ar.c b/binutils/ar.c
index 0ecfa3372281..44df48c5c677 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1253,7 +1253,6 @@ write_archive (bfd *iarch)
char *old_name, *new_name;
bfd *contents_head = iarch->archive_next;
int ofd = -1;
- struct stat target_stat;
old_name = xstrdup (bfd_get_filename (iarch));
new_name = make_tempname (old_name, &ofd);
@@ -1298,12 +1297,6 @@ write_archive (bfd *iarch)
if (!bfd_set_archive_head (obfd, contents_head))
bfd_fatal (old_name);
-#if !defined (_WIN32) || defined (__CYGWIN32__)
- ofd = dup (ofd);
-#endif
- if (ofd == -1 || bfd_stat (iarch, &target_stat) != 0)
- bfd_fatal (old_name);
-
if (!bfd_close (obfd))
bfd_fatal (old_name);
@@ -1313,7 +1306,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, NULL) != 0)
xexit (1);
free (old_name);
free (new_name);
diff --git a/binutils/arsup.c b/binutils/arsup.c
index fa7706f79e50..f7ce8f0bc820 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -343,18 +343,11 @@ ar_save (void)
}
else
{
- bfd_boolean skip_stat = FALSE;
struct stat target_stat;
- int ofd = real_ofd;
if (deterministic > 0)
obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
-#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);
-#endif
bfd_close (obfd);
if (stat (real_name, &target_stat) != 0)
@@ -363,9 +356,6 @@ ar_save (void)
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);
@@ -373,8 +363,7 @@ ar_save (void)
}
}
- smart_rename (temp_name, real_name, ofd,
- skip_stat ? NULL : &target_stat, 0);
+ smart_rename (temp_name, real_name, NULL);
obfd = 0;
free (temp_name);
free (real_name);
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
index 7a0adfae5659..aa7e33d8cd15 100644
--- a/binutils/bucomm.h
+++ b/binutils/bucomm.h
@@ -71,7 +71,7 @@ extern void print_version (const char *);
/* In rename.c. */
extern void set_times (const char *, const struct stat *);
-extern int smart_rename (const char *, const char *, int, struct stat *, int);
+extern int smart_rename (const char *, const char *, struct stat *);
/* In libiberty. */
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 54a59430f1b4..abbcb7c51907 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -4837,7 +4837,6 @@ strip_main (int argc, char *argv[])
struct stat statbuf;
char *tmpname;
int tmpfd = -1;
- int copyfd = -1;
if (get_file_size (argv[i]) < 1)
{
@@ -4851,12 +4850,7 @@ strip_main (int argc, char *argv[])
else
tmpname = output_file;
- if (tmpname == NULL
-#if !defined (_WIN32) || defined (__CYGWIN32__)
- /* Retain a copy of TMPFD since we will need it for SMART_RENAME. */
- || (tmpfd >= 0 && (copyfd = dup (tmpfd)) == -1)
-#endif
- )
+ if (tmpname == NULL)
{
bfd_nonfatal_message (argv[i], NULL, NULL,
_("could not create temporary file to hold stripped copy"));
@@ -4869,23 +4863,15 @@ strip_main (int argc, char *argv[])
output_target, NULL);
if (status == 0)
{
- if (preserve_dates)
- set_times (tmpname, &statbuf);
if (output_file != tmpname)
status = (smart_rename (tmpname,
output_file ? output_file : argv[i],
- copyfd, &statbuf, preserve_dates) != 0);
+ preserve_dates ? &statbuf : NULL) != 0);
if (status == 0)
status = hold_status;
}
else
- {
-#if !defined (_WIN32) || defined (__CYGWIN32__)
- if (copyfd >= 0)
- close (copyfd);
-#endif
- unlink_if_ordinary (tmpname);
- }
+ unlink_if_ordinary (tmpname);
if (output_file != tmpname)
free (tmpname);
}
@@ -5093,7 +5079,6 @@ copy_main (int argc, char *argv[])
bfd_boolean use_globalize = FALSE;
bfd_boolean use_keep_global = FALSE;
int c, tmpfd = -1;
- int copyfd = -1;
struct stat statbuf;
const bfd_arch_info_type *input_arch = NULL;
@@ -5938,12 +5923,7 @@ copy_main (int argc, char *argv[])
else
tmpname = output_filename;
- if (tmpname == NULL
-#if !defined (_WIN32) || defined (__CYGWIN32__)
- /* Retain a copy of TMPFD since we will need it for SMART_RENAME. */
- || (tmpfd >= 0 && (copyfd = dup (tmpfd)) == -1)
-#endif
- )
+ if (tmpname == NULL)
{
fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
input_filename, strerror (errno));
@@ -5953,20 +5933,12 @@ copy_main (int argc, char *argv[])
output_target, input_arch);
if (status == 0)
{
- if (preserve_dates)
- set_times (tmpname, &statbuf);
if (tmpname != output_filename)
- status = (smart_rename (tmpname, input_filename, copyfd, &statbuf,
- preserve_dates) != 0);
+ status = (smart_rename (tmpname, input_filename,
+ preserve_dates ? &statbuf : NULL) != 0);
}
else
- {
-#if !defined (_WIN32) || defined (__CYGWIN32__)
- if (copyfd >= 0)
- close (copyfd);
-#endif
- unlink_if_ordinary (tmpname);
- }
+ unlink_if_ordinary (tmpname);
if (tmpname != output_filename)
free (tmpname);
diff --git a/binutils/rename.c b/binutils/rename.c
index e36b75132ded..2ff092ee22b5 100644
--- a/binutils/rename.c
+++ b/binutils/rename.c
@@ -122,61 +122,13 @@ set_times (const char *destination, const struct stat *statbuf)
non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
}
-#ifndef S_ISLNK
-#ifdef S_IFLNK
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#else
-#define S_ISLNK(m) 0
-#define lstat stat
-#endif
-#endif
-
-#if !defined (_WIN32) || defined (__CYGWIN32__)
-/* Try to preserve the permission bits and ownership of an existing file when
- rename overwrites it. FD is the file being renamed and TARGET_STAT has the
- status of the file that was overwritten. */
-static void
-try_preserve_permissions (int fd, struct stat *target_stat)
-{
- struct stat from_stat;
- int ret = 0;
-
- if (fstat (fd, &from_stat) != 0)
- return;
-
- int from_mode = from_stat.st_mode & 0777;
- int to_mode = target_stat->st_mode & 0777;
-
- /* Fix up permissions before we potentially lose ownership with fchown.
- Clear the setxid bits because in case the fchown below fails then we don't
- want to end up with a sxid file owned by the invoking user. If the user
- hasn't changed or if fchown succeeded, we add back the sxid bits at the
- end. */
- if (from_mode != to_mode)
- fchmod (fd, to_mode);
-
- /* Fix up ownership, this will clear the setxid bits. */
- if (from_stat.st_uid != target_stat->st_uid
- || from_stat.st_gid != target_stat->st_gid)
- ret = fchown (fd, target_stat->st_uid, target_stat->st_gid);
-
- /* Fix up the sxid bits if either the fchown wasn't needed or it
- succeeded. */
- if (ret == 0)
- fchmod (fd, target_stat->st_mode & 07777);
-}
-#endif
-
-/* Rename FROM to TO, copying if TO is either a link or is not a regular file.
- FD is an open file descriptor pointing to FROM that we can use to safely fix
- up permissions of the file after renaming. TARGET_STAT has the file status
- that is used to fix up permissions and timestamps after rename. Return 0 if
- ok, -1 if error and FD is closed before returning. */
+/* Rename FROM to TO, copying if TO exists. TARGET_STAT has the file status
+ that, if non-NULL, is used to fix up timestamps after rename. Return 0 if
+ ok, -1 if error. */
int
-smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
- struct stat *target_stat ATTRIBUTE_UNUSED,
- int preserve_dates ATTRIBUTE_UNUSED)
+smart_rename (const char *from, const char *to,
+ struct stat *target_stat ATTRIBUTE_UNUSED)
{
int ret = 0;
struct stat to_stat;
@@ -199,37 +151,10 @@ smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
unlink (from);
}
#else
- /* Avoid a full copy and use rename if we can fix up permissions of the
- file after renaming, i.e.:
-
- - TO is not a symbolic link
- - TO is a regular file with only one hard link
- - We have permission to write to TO
- - FD is available to safely fix up permissions to be the same as the file
- we overwrote with the rename.
-
- Note though that the actual file on disk that TARGET_STAT describes may
- have changed and we're only trying to preserve the status we know about.
- At no point do we try to interact with the new file changes, so there can
- only be two outcomes, i.e. either the external file change survives
- without knowledge of our change (if it happens after the rename syscall)
- or our rename and permissions fixup survive without any knowledge of the
- external change. */
- if (! exists
- || (fd >= 0
- && !S_ISLNK (to_stat.st_mode)
- && S_ISREG (to_stat.st_mode)
- && (to_stat.st_mode & S_IWUSR)
- && to_stat.st_nlink == 1)
- )
+ /* Avoid a full copy and use rename if TO does not exist. */
+ if (!exists)
{
- ret = rename (from, to);
- if (ret == 0)
- {
- if (exists && target_stat != NULL)
- try_preserve_permissions (fd, target_stat);
- }
- else
+ if ((ret = rename (from, to)) != 0)
{
/* We have to clean up here. */
non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
@@ -242,12 +167,10 @@ smart_rename (const char *from, const char *to, int fd ATTRIBUTE_UNUSED,
if (ret != 0)
non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
- if (preserve_dates && target_stat != NULL)
+ if (target_stat != NULL)
set_times (to, target_stat);
unlink (from);
}
- if (fd >= 0)
- close (fd);
#endif /* _WIN32 && !__CYGWIN32__ */
return ret;

View File

@ -1,7 +1,7 @@
Summary: Binary utilities
Name: binutils
Version: 2.36.1
Release: 4
Version: 2.37
Release: 1
License: GPLv3+
URL: https://sourceware.org/binutils
@ -25,17 +25,10 @@ Patch3: binutils-2.27-aarch64-ifunc.patch
Patch4: CVE-2019-1010204.patch
Patch5: Fix-a-potential-use-of-an-uninitialised-value-in-the.patch
Patch6: backport-0003-CVE-2021-20197.patch
Patch7: backport-Fix-a-build-problem-when-using-FreeBSD-12.patch
Patch8: backport-0004-CVE-2021-20197.patch
Patch9: backport-CVE-2021-3549.patch
Patch10: backport-PR27345-binutils-arsup.c-lstat-not-available-on-all.patch
Patch11: backport-PR27349-ar-breaks-symlinks.patch
Patch12: backport-binutils-Avoid-renaming-over-existing-files.patch
Patch13: backport-PR27456-lstat-in-rename.c-on-MinGW.patch
Patch14: backport-Use-make_tempname-file-descriptor-in-smart_rename.patch
Patch15: backport-Fix-demangle-style-usage-info.patch
Patch16: backport-CVE-2021-45078.patch
Patch6: backport-CVE-2021-45078.patch
Patch7: backport-0001-CVE-2021-42574.patch
Patch8: backport-0002-CVE-2021-42574.patch
Patch9: backport-0003-CVE-2021-42574.patch
Provides: bundled(libiberty)
@ -349,6 +342,12 @@ fi
%{_infodir}/bfd*info*
%changelog
* Wed Jan 19 2022 panxiaohe <panxiaohe@huawei.com> - 2.37-1
- Type:enhancement
- ID:CVE-2021-42574
- SUG:NA
- DESC:update to 2.37 and fix CVE-2021-42574
* Fri Dec 24 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 2.36.1-4
- Type:CVE
- ID:CVE-2021-45078

View File

@ -16,8 +16,8 @@ index 6a39ef5..ddc3b54 100644
bfdincludedir = @bfdincludedir@
bfdlib_LTLIBRARIES = libbfd.la
bfdinclude_HEADERS = $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \
- bfd_stdint.h $(INCDIR)/diagnostics.h $(INCDIR)/bfdlink.h
+ bfd_stdint.h $(INCDIR)/diagnostics.h $(INCDIR)/bfdlink.h $(INCDIR)/demangle.h
- $(INCDIR)/diagnostics.h $(INCDIR)/bfdlink.h
+ $(INCDIR)/diagnostics.h $(INCDIR)/bfdlink.h $(INCDIR)/demangle.h
else !INSTALL_LIBBFD
# Empty these so that the respective installation directories will not be created.
bfdlibdir =
@ -28,7 +28,7 @@ index 80499d6..09a93b9 100644
@@ -249,7 +249,7 @@ am__can_run_installinfo = \
esac
am__bfdinclude_HEADERS_DIST = $(INCDIR)/plugin-api.h bfd.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h bfd_stdint.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \
- $(INCDIR)/diagnostics.h $(INCDIR)/bfdlink.h
+ $(INCDIR)/diagnostics.h $(INCDIR)/bfdlink.h $(INCDIR)/demangle.h
HEADERS = $(bfdinclude_HEADERS)
@ -38,8 +38,8 @@ index 80499d6..09a93b9 100644
@INSTALL_LIBBFD_FALSE@bfdinclude_HEADERS = $(am__append_2)
@INSTALL_LIBBFD_TRUE@bfdinclude_HEADERS = $(BFD_H) \
@INSTALL_LIBBFD_TRUE@ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \
-@INSTALL_LIBBFD_TRUE@ bfd_stdint.h $(INCDIR)/diagnostics.h \
+@INSTALL_LIBBFD_TRUE@ bfd_stdint.h $(INCDIR)/diagnostics.h $(INCDIR)/demangle.h \
-@INSTALL_LIBBFD_TRUE@ $(INCDIR)/diagnostics.h \
+@INSTALL_LIBBFD_TRUE@ $(INCDIR)/diagnostics.h $(INCDIR)/demangle.h \
@INSTALL_LIBBFD_TRUE@ $(INCDIR)/bfdlink.h $(am__append_2)
@INSTALL_LIBBFD_FALSE@rpath_bfdlibdir = @bfdlibdir@
@INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libbfd.la