Mariusz Zaborski oshogbo at FreeBSD.org
Fri Mar 2 18:35:13 UTC 2018


Today I would like to propose a new syscall called unlinkfd(2) which came up
during a discussion with Ed Maste.

Currently in UNIX we can’t remove files safely. If we will try to do so we
always end up in a race condition. For example when we open a file, and check
it with fstat, etc. then we want to unlink(2) it… but the file we are trying to
unlink could be a different one than the one we were fstating just a moment ago.

Another reason of implementing unlinkfd(2) came to us when we were trying
to sandbox some applications like: uudecode/b64decode or bspatch. It occured
to us that we don’t have a good way of removing single files. Of course we can
try to determine in which directory we are in, and then open this directory and
remove a single file.

It looks even more bizarre if we would think about a program which operates on
multiple files. If we would analyze a situation with two totally different
directories like `/tmp` and `/home/oshogbo` we would end up with pre opening
a root directory or keeping as many directories as we are working on open.
All of that effort only to remove two files. This make it totally impractical!

I think that opening directories also presents some wider attack vector because
we are keeping a single descriptor to a directory only to remove one file.
Unfortunately this means that an attacker can remove all files in that directory.

I proposed this as well on the last Capsicum call. There was a suggestion that
instead of doing a single syscall maybe we should have a Casper service that
will allow us to remove files. Another idea was that we should perhaps redesign
programs to create some subdirs work on the subdirs and then remove all files in
this subdir. I don’t feel that creating a Casper service is a good idea because
we still have exactly the same issue of race condition. In my opinion creating
subdirs is also a problem for us.

First we would need to redesign some of our tools and I think we should
simplyfiy capsicumizition of the process instead of making it harder.

Secondly we can create a temporary subdirectory but what will remove it?
We are going back to having a fd to directory in which we just created a subdir.
Another way would be to have Casper service which would remove a directory but
with the risk of RC.

In conclusion, I think we need syscall like unlinkfd(2), which turn out taht it
is easy to implement. The only downside of this implementation is that we not
only need to provide a fd but also a path file. This is because inodes nor
vnodes don’t contain filenames. We are comparing vnodes of the fd and the given
path, if they are exactly the same we remove a file. In the syscall we are using
a fd so there is no Ambient Authority because we are proving that we already
have access to that file. Thanks to that the syscall can be safely used with
Caspsicum. I have already discussed this with some people and they said
`Hey I already had that idea a while ago…` so let’s do something with that idea!
If you are intereted in patch you can find it here:

Mariusz Zaborski
oshogbo//vx		| http://oshogbo.vexillium.org
FreeBSD commiter	| https://freebsd.org
Software developer	| http://wheelsystems.com
If it's not broken, let's fix it till it is!!1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20180302/f0abd075/attachment.sig>

More information about the freebsd-hackers mailing list