On Mon, Sep 05, 2016 at 09:55:44PM -1000, Brent W. Baccala wrote:
> On Thu, Sep 1, 2016 at 12:38 PM, Richard Braun <rbr...@sceen.net> wrote:
> > This was famously shown with the example of the
> > firmlink translator used in /tmp, which would cause the removal of
> > any file targeted by the firmlink on /tmp cleanup during system
> > startup.
> I see that. It seems to still have that problem. I created a directory
> /root/baitdir, and put in it a file named 'bait'. As a non-privileged
> user, I created a firmlink in /tmp to /root/baitdir and rebooted. Voila!
> 'bait' vanished.
> I took the time to read some of this mailing list's archive on the
> subject. The consensus seems to be that you can't trust unprivileged
> translators. So "find", which is used to clean /tmp, should not, in this
> case, cross translator boundaries.
I don't know which threads you have read exactly; but there have been
pretty conclusive discussions on this issue IMHO.
The "quickfix" solution is simply by default not to follow translators
running with a different UID than the client. (Unless the translator is
running as root.) That's pretty much what FUSE does on Linux.
A more ambitious solution I came up with Carl is to change the reauth
mechanism: when crossing translator boundaries during a lookup, instead
of obtaining an new auth token associated with all of the IDs available
to the client process, we would create an auth token associated with
only the intersection of the IDs from the previous auth token, and the
IDs available to the new translator we are entering. This way, when for
example a root process follows a firmlink run by an ordinary user, it
would get an auth token associated with only that user's IDs, not the
root IDs; and when the firmlink redirects to some other FS location, the
following lookup would still be limited to that user's IDs -- so the FD
obtained from the lookup could not be used to delete a file that the
untrusted user has no permissions for.
> I was thinking at first that we should have something like the "-xdev"
> switch; "-xtrans", maybe?
Selecting how to treat translators in general is another long-standing
issue, but with a broader and somewhat different scope than the trust
issue. Backups are a pretty illustrative standard example for that.
The fundamental problem with this is that translators range from things
that behave and should be treated like traditional filesystem mounts, to
others that should be pretty much transparent -- trying to treat all of
them in the same manner is bound to create problems in one situation or
the other. We need a more fine-grained solution.
Trying to add options to handle all the possible cases to all relevant
client programs is not realistic. Thus the solution I advocate instead
is something I refer to as "namespace-based translator selection": the
user adds special suffixes to paths, which are transparent to the
clients doing the lookup, but invoke special handling in the lookup
mechanism. Thus for example "rm -r /foo,,*" would follow all
translators, while "rm -r /foo,,0" wouldn't follow any; yet other
options could be more selective, following only certain classes of
Many years ago Sergiu worked on a prototype implementation we called
"nsmux" (for lack of a more suitable name) in the context of a GSoC
project (kinda), and we got many in-depth discussion along with a
partially working implementation. It didn't get finished, because the
implementation as a proxy server turned out more involved than initially
anticipated (the other option would be implementing it in glibc); and
also because I wasn't able to keep up with the amount of mentoring
necessary I think... But the idea is still out there.
(My favourite feature of this mechanism is the ability to specify
"dynamic" translators to be applied during the lookup, without a need to
explicitly set them up first; so we could for example do something like
"vi /foo/bar.gz,,unzip" -- I believe this would really give the Hurd an
edge in convenience over other systems...)
> Yet since filesystem mounts are themselves done with translators, what does
> "-xdev" mean on Hurd? I've poked around a bit in the source, and played
> with 'stat'. It seems like several translators take an arbitrary number
> and present it as their device number. Seems like legacy support, and it's
> easy for a translator to defeat -xdev by announcing the same device as its
This is actually an interesting idea for a partial solution: we could
introduce some mechanism that would allow specifying (e.g. as an option
to settrans) whether a translator should be transparent or mount-like;
which would determine whether the translator is allowed to claim the
same device ID as its parent or not. That would require some major
interface changes in the Hurd -- but it might be worth the effort.
> On a related note, how do you find the owner of a passive translator? I
> expected either showtrans or ls to provide that information (perhaps with a
> verbose switch), but it had eluded me...
What exactly do you mean here? The translator record itself doesn't have
a distinct owner -- the record can only be set by the owner of the FS
node in question though (or root); and an active translator stared from
it is run with the UID of same user.