Bug 27284

Summary: ar: wrong permissions on output file
Product: binutils Reporter: Adam Sampson <ats-sourceware>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: mliska
Priority: P2    
Version: 2.36   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed: 2021-01-31 00:00:00
Bug Depends on:    
Bug Blocks: 26945    

Description Adam Sampson 2021-01-30 23:16:53 UTC
I've just run into an interesting problem when building plan9port with
binutils 2.36: it uses "ar rcs" to build static libraries, but one of
the libraries -- lib9.a, which has a very long list of objects -- ends
up with permission 0600 rather than the intended 0644.

Here's a script that reproduces the problem for me on amd64 GNU/Linux
with GCC 10.2.0:

-----
#!/bin/sh

echo "int x;" >t.c
gcc -c t.c
for i in $(seq 100 299); do
        cp t.o $i.o
done

rm -f libt.a
ar rcs libt.a 1*.o
ls -l libt.a

rm -f libt.a
ar rcs libt.a [12]*.o
ls -l libt.a
-----

This produces the output:

-rw-r--r-- 1 root root 101072 Jan 29 22:23 libt.a
-rw------- 1 root root 202072 Jan 29 22:23 libt.a

Tracing through the ar code, this seems to be fallout from this change:
https://lists.gnu.org/archive/html/bug-binutils/2021-01/msg00089.html

In write_archive, with the shorter argument list, iarch->iostream is
non-NULL; with the longer list, iarch->iostream is NULL, and skip_stat
is set to TRUE, so the permissions don't get set.

It looks from the libbfd code like ->iostream can legitimately be NULL
while the file is open, so I think the new test in write_archive is
incorrect.
Comment 1 Alan Modra 2021-01-31 04:08:12 UTC
pr27270 is also caused by the patch you identify
Comment 2 cvs-commit@gcc.gnu.org 2021-02-03 03:00:57 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=95b91a043aeaeb546d2fea556d84a2de1e917770

commit 95b91a043aeaeb546d2fea556d84a2de1e917770
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Feb 1 02:04:41 2021 +1030

    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.
Comment 3 Martin Liska 2021-02-03 09:17:57 UTC
@Alan: Are you planning to backport that to 2.36 branch, please?
Comment 4 cvs-commit@gcc.gnu.org 2021-02-03 11:05:01 UTC
The binutils-2_36-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6184480d7ce1bcd57669a62867efc68418d0de7c

commit 6184480d7ce1bcd57669a62867efc68418d0de7c
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Feb 1 02:04:41 2021 +1030

    pr27270 and pr27284, ar segfaults and wrong file mode
    
            PR 27270
            PR 27284
            PR 26945
            * ar.c: Don't include libbfd.h.
            (write_archive): Replace xmalloc+strcpy with xstrdup.  Use
            bfd_stat rather than fstat on iostream.  Move stat and fd tests
            outside of _WIN32 ifdef.  Delete skip_stat variable.
            * arsup.c (temp_name, real_ofd): New static variables.
            (ar_open): Use make_tempname and bfd_fdopenw.
            (ar_save): Adjust to suit ar_open changes.  Move stat output
            of _WIN32 ifdef.
            * objcopy.c: Don't include libbfd.h.
            (copy_file): Use bfd_stat.
    
    (cherry picked from commit 95b91a043aeaeb546d2fea556d84a2de1e917770)
Comment 5 Alan Modra 2021-02-03 11:06:04 UTC
Fixed