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.
This commit is contained in:
Alan Modra
2021-02-23 12:10:58 +10:30
parent cca8873dd5
commit c42c71a152
6 changed files with 83 additions and 35 deletions

View File

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