Re: [dev] why avoid install?

From: Markus Wichmann <nullplan_AT_gmx.net>
Date: Thu, 20 Nov 2014 20:40:24 +0100

On Wed, Nov 19, 2014 at 11:12:43AM -0500, random832_AT_fastmail.us wrote:
> On Wed, Nov 19, 2014, at 09:55, Dimitris Papastamos wrote:
> > Regarding your question on cp -f then the answer is not quite.
> >
> > cp -f will try to unlink the destination if it fails to open it for
> > whatever
> > reason.
>
> And if the target is running and writing to a running binary is a
> problem, opening it will fail with [ETXTBSY], meaning it will be
> unlinked. You can argue about whether that is the purpose or something
> else (permission errors within a directory you own) is the purpose, but
> it will certainly solve that problem.
>

Not always. One thing that reliably gets on people's nerves here is
shared libraries. And those aren't protected with that ETXTBSY thing.

The reason is that the MAP_DENYWRITE flag became the irrecoverable
source of a DoS attack and had to be removed from the syscall. It can
still be used in the kernel, which is why overwriting a running binary
will fail, but it can't be used in userspace (or rather, is ignored), so
opening a shared library that's in use for writing and truncating is
possible. That means that cp -f on a used shared library will destroy
all programs using it.

Also, if you unlink the target file, that means that the file system
gets into the state where the target file does not exist. If you then
start the copy loop, the file system gets into the state where the file
does exist, but has the wrong mode, wrong owner and probably wrong
content. If anything happens to go wrong during that, the target file
will be corrupted. If anything is looking for the target file in the
meantime, they'll see it in the wrong state, which may cause surprise.
After all, every single one of my programs failing at once would
certainly surprise me!

The correct solution is to copy the file to a temporary name in the same
directory (or something else that guarentees it being on the same device
as the target file), then change its mode and owner, and then move it
into place. If anything goes wrong, just delete the temporary file. That
way, you can even update /lib/libc.so with a shell script. But that only
works for musl, of course. For most other libcs, you have to figure out
in what order to update the different library files without breaking
programs. That, or create a compiled program that does all the moving in
one invocation, because a half-updated libc will probably mean that
nothing can run until it's fixed.

Ciao,
Markus
Received on Thu Nov 20 2014 - 20:40:24 CET

This archive was generated by hypermail 2.3.0 : Thu Nov 20 2014 - 20:48:08 CET