The install command deleted libc when it should not have. Running the install command with '-fschg -S' deletes the install target when security.jail.chflags_allowed=0 inside a jail. I observed this during installworld. The problem can be avoided by setting security.jail.chflags_allowed=1 before running make installworld. How-To-Repeat: (outside the jail) ~$ chflags noschg /usr/jails/cr/lib/libc.so.6 (inside the jail) [root@s4cr /usr/src/lib/libc]# ls -lao /lib/libc.so.6 -rwxr-xr-x 1 root wheel - 981331 Sep 21 15:57 /lib/libc.so.6 [root@s4cr /usr/src/lib/libc]# sysctl -a | grep secur kern.securelevel: -1 security.jail.chflags_allowed: 0 [root@s4cr /usr/src/lib/libc]# make install install -C -o root -g wheel -m 444 libc.a /usr/lib install -C -o root -g wheel -m 444 libc_p.a /usr/lib install -s -o root -g wheel -m 444 -fschg -S libc.so.6 /lib install: /lib/libc.so.6: chflags: Operation not permitted *** Error code 71 Stop in /usr/src/lib/libc. [root@s4cr /usr/src/lib/libc]# ls -lao /lib/libc.so.6 /libexec/ld-elf.so.1: Shared object "libc.so.6" not found, required by "ls" [root@s4cr /usr/src/lib/libc]#
On 2008-09-22, Jason C. Wells wrote: > The install command deleted libc when it should not have. Running the > install command with '-fschg -S' deletes the install target when > security.jail.chflags_allowed=0 inside a jail. I observed this during > installworld. The problem can be avoided by setting > security.jail.chflags_allowed=1 before running make installworld. This is a bug in install(1). Here's a stripped down way to reproduce it: (in a jail) # sysctl security.jail.jailed security.jail.chflags_allowed security.jail.jailed: 1 security.jail.chflags_allowed: 0 # touch target # ls -lo target -rw-r--r-- 1 root wheel - 0 Sep 29 09:54 target # install -fschg -S /bin/cat target install: target: chflags: Operation not permitted # ls -lo target ls: target: No such file or directory The problem is that install(1) unlinks the target file if fchflags(2) fails. This is not good especially with -S which is supposed to be safe. There are also three more unsafe unlink(2) calls in install() function. fstat(2) and fchown(2) and fchmod(2) are performed for the file after rename. Failure on those calls causes the target to be unlinked. This is how to reproduce the fchown(2) problem without jail: (use a non-root user) $ touch target $ ls target target $ install -S -o root /bin/cat target install: target: chown/chgrp: Operation not permitted $ ls target ls: target: No such file or directory Attached patch does following changes: * If safe copy is used perform fstat(2) and fchown(2) and fchmod(2) _before_ rename and on failure unlink the temporary copy instead of the target. * On fchlags(2) failure don't unlink the target. We still exit with error status. fchflags(2) can't be performed before rename because immutable flags may prevent renaming. -- Jaakko
The patch works but introduces a new problem: install -S -m 0 src dst (installing to an unreadable destination, probably as non-root) no longer works. I have fixed this particular issue (attachment and http://www.stack.nl/~jilles/unix/install-S-safe.patch ), but I think the code is too hard to understand. The install() function was already fairly twisted and the patch has not improved it. -- Jilles Tjoelker
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
Keyword: patch or patch-ready – in lieu of summary line prefix: [patch] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>