Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[gentoo-dev] portage reliance on GNU objcopy ownership perseverance behavior in strip

94 views
Skip to first unread message

Manoj Gupta

unread,
Feb 4, 2021, 7:10:03 PM2/4/21
to
Hi gentoo devs,

This question is regarding interaction of fowners [1] and estrip functionality in portage.
fowners is used on various binaries and files to assign the ownership to specific users or group.

GNU objcopy and strip do not change the file ownership when run as root. However, llvm's versions do not preserve it and instead make root the owner of the modified file. 
e.g. 
sudo strip <file> keeps the original ownership .
sudo llvm-strip <file> will change ownership to root.

We were trying to have llvm objcopy with a patch [3] to have the same behavior as GNU but LLVM developers pointed out that GNU implementation is thought to have a security issue: https://sourceware.org/bugzilla/show_bug.cgi?id=26945 
We have modified the LLVM patch to avoid chown on the final file and rather doing it on the temporay file but I am not sure if that will be enough to placate the llvm devs.

What does everyone think of modifying usages of calls to strip and objcopy inside estrip so that file ownership is manually restored. e.g

owner=$(stat -U file)
group=$(stat -G file)
strip <file>
chown owner:group file


Thanks,
Manoj

Michael Orlitzky

unread,
Feb 4, 2021, 8:10:03 PM2/4/21
to
On Thu, 2021-02-04 at 16:09 -0800, Manoj Gupta wrote:
>
> What does everyone think of modifying usages of calls to strip and
> objcopy
> inside estrip so that file ownership is manually restored. e.g
>
> owner=$(stat -U file)
> group=$(stat -G file)
> strip <file>
> chown owner:group file
>

This is probably safe in portage because the temporary directory is no
longer user-accessible, but it seems perverse to seek feature parity by
adding the security vulnerability into the implementations that don't
have it, rather than by removing it from the ones that do. Hopefully
LLVM just accepts the patch.

Fāng-ruì Sòng

unread,
Feb 9, 2021, 9:00:02 PM2/9/21
to
(I replied via https://groups.google.com/g/linux.gentoo.dev/c/WG-OLQe3yng
"Reply all" (which only replied to the list AFAICT) but I did not
subscribe to gentoo-dev via the official
https://www.gentoo.org/get-involved/mailing-lists/ so my reply is
missing)
> This is probably safe in portage because the temporary directory is no
> longer user-accessible, but it seems perverse to seek feature parity by
> adding the security vulnerability into the implementations that don't
> have it, rather than by removing it from the ones that do. Hopefully
> LLVM just accepts the patch.

In binutils, objcopy/strip call 'smart_rename', which has a
vulnerability: https://sourceware.org/bugzilla/show_bug.cgi?id=26945
The first resolution used renameat2, which is not intercepted by
fakeroot (Arch Linux runs strip and tar under fakeroot, then
extracting the tar to the system /).
After discussion with binutils upstream, Arch Linux's resolution is to
use `strip a -o b` instead of `strip a`:
https://git.archlinux.org/pacman.git/commit/?id=88d054093c1c99a697d95b26bd9aad5bc4d8e170

For some unclear reason the first binutils resolution was reverted in
the 2.36 branch. The latest attempt is to use open(O_TRUNC)+write
instead of atomic rename
https://sourceware.org/pipermail/binutils/2021-February/115282.html
That preserves security context/xattr (not used by any distribution
package)/owner/group/mode and avoids fchmod/chown.

However, like other non-atomic operations, this approach has one
wasteful write (`strip a` writes two files) and can potentially
corrupt the output in the case of full disk situation and other
erroneous cases.

The root cause is that `sudo strip a` (or `strip a` under fakeroot)
restoring owner/group is a questionable interface and distributions
read too much from the behavior.
Personally I'd like llvm-objcopy to keep the behavior as is (no
chown/fchown). Neither https://reviews.llvm.org/D96308 nor
https://reviews.llvm.org/D93881 is appealing.

Doing this (get_owner_group; {strip,llvm-strip} file -o temp && chown
owner:group file && mv temp file) on Portage side is doing a favor to
LLVM binary utilities.
It benefits GNU binutils as well - with newer binutils, the current
`strip a` will have a wasteful write and 2x dirty pages (write a
temporary file and copy that content to the original file).

Michael Orlitzky

unread,
Feb 9, 2021, 9:10:03 PM2/9/21
to
On Tue, 2021-02-09 at 17:53 -0800, Fāng-ruì Sòng wrote:
> (I replied via https://groups.google.com/g/linux.gentoo.dev/c/WG-OLQe3yng
> "Reply all" (which only replied to the list AFAICT) but I did not
> subscribe to gentoo-dev via the official
> https://www.gentoo.org/get-involved/mailing-lists/ so my reply is
> missing)
>

Apologies for hijacking your post with a tangential question, but you
reminded me to ask: how did you notice this problem? Ultimately all
system executables (in $PATH) should be owned by (and writable only by)
root anyway; otherwise you get silly security vulnerabilities like "cat
~/virus > /usr/bin/foo" as a regular user.

Fangrui Song

unread,
Feb 9, 2021, 9:30:02 PM2/9/21
to
Context: both `strip a` and `llvm-strip a` create a temporary file.
`strip a` does additional chown(2) (instead of fchown!) with a long list
of hardening-style checks. Due to how the code is organized, passing a
file description around can be difficult for binutils.

Jian Cai reported the problem that `sudo llvm-strip a` does not restore
the original filename. I played with `strip a` and `strip a -o b` a bit
and noticed that chown(2) is only called in these cases:

* (under root) strip a
* (under root) strip a -o a

not in these cases:

* strip a -o b
* strip a -o ./a

---

From my side, I want llvm-objcopy/llvm-strip to have simple and consistent rules,
smaller platform differences. Why does strip need to behave differently
with or without root permission, when the target file has one hard link
or more, on Linux than on other OSes?

The driven reason is that distributions require such `strip a` behavior.
Arch Linux has moved away. If Gentoo Linux can move away, llvm-objcopy
can keep its current simpler behavior.

---

I think Arch Linux did this:

```
fakeroot
# create an executable owned by bin
strip exe # still owned by bin
tar cf package.tar exe # record the owner
exit

tar xf package.tar -C somewhere
```

Manoj Gupta

unread,
Feb 9, 2021, 9:30:03 PM2/9/21
to
Root is the owner but often there is also a group that has access to the files. 
After stripping with llvm-strip, new ownership is root:root instead of root:<group>. 
Therefore, the members of the group lose access to the files post stripping.

We found this issue in Chrome OS when we tried to switch the defaults to llvm's objcopy/strip.

Example of ebuilds:
$ grep -ri fowners .|grep bin|grep usr|tail -10
./net-analyzer/tcpdump/tcpdump-4.9.3-r4.ebuild: fowners root:pcap /usr/sbin/tcpdump
./net-analyzer/tcpdump/tcpdump-4.99.0.ebuild: fowners root:pcap /usr/sbin/tcpdump
./net-analyzer/netselect/netselect-9999.ebuild: fowners root:wheel /usr/bin/netselect
./net-analyzer/netselect/netselect-0.4-r1.ebuild: fowners root:wheel /usr/bin/netselect
./net-analyzer/driftnet/driftnet-1.3.0.ebuild: fowners root:wheel "/usr/bin/driftnet"
./mail-filter/procmail/procmail-3.22-r14.ebuild: fowners root:mail /usr/bin/lockfile
./sys-block/scsiadd/scsiadd-1.97-r1.ebuild: fowners root:scsi /usr/sbin/scsiadd
./x11-terms/aterm/aterm-1.0.1-r4.ebuild: fowners root:utmp /usr/bin/aterm
./x11-terms/mrxvt/mrxvt-0.5.4.ebuild: fowners root:utmp /usr/bin/mrxvt
./games-arcade/xboing/xboing-2.4-r3.ebuild: fowners root:gamestat /var/games/xboing.score /usr/bin/xboing 

Thanks,
Manoj

Michael Orlitzky

unread,
Feb 9, 2021, 9:50:02 PM2/9/21
to
On Tue, 2021-02-09 at 18:25 -0800, Manoj Gupta wrote:
> >
> > Root is the owner but often there is also a group that has access to the
> files.
> After stripping with llvm-strip, new ownership is root:root instead of
> root:<group>.
> Therefore, the members of the group lose access to the files post stripping.
>
> We found this issue in Chrome OS when we tried to switch the defaults to
> llvm's objcopy/strip.

Thanks, I still agree that some consistent behavior is needed. The only
reason I asked is because the fact that you *noticed* the problem is a
red flag to me. A suid group is a valid use case, but a few of these
examples don't set any special group permissions on the executables
whose group they change. For example...

> ./net-analyzer/netselect/netselect-9999.ebuild: fowners root:wheel
> /usr/bin/netselect

This ebuild does,

fowners root:wheel /usr/bin/netselect
fperms 4711 /usr/bin/netselect

which makes you wonder why it changed the group in the first place. The
ebuilds for mail-filter/procmail and games-arcade/xboing are also
suspect.

Michael Orlitzky

unread,
Feb 9, 2021, 11:50:03 PM2/9/21
to
On Tue, 2021-02-09 at 21:44 -0500, Michael Orlitzky wrote:
>
> ... games-arcade/xboing are also suspect.
>

(This one's fine, that's the documented way to do things now. Although
I don't see why we couldn't use a separate group for each game's score
file.)

Manoj Gupta

unread,
Feb 10, 2021, 12:00:03 AM2/10/21
to
This was not an exhaustive list, just the last 10 occurrences.
Similar to fowners, I counted 161 usages of fperms though the grep below is not necessarily correct or exhaustive.

$ grep -ri fperms .|grep bin|grep usr|wc -l
161

In Chrome OS, the switch to llvm-strip/objcopy broke some things like reboot/shutdown (and more) etc. 
as this functionality relied on group ownership for the power management tools.

I could imagine that different tools similarly may need group ownership etc. for the tasks they need to perform.

-Manoj 
0 new messages