Re: [PATCH v5 2/4] fuse: Support fuse filesystems outside of init_user_ns

From: Eric W. Biederman
Date: Tue Nov 11 2014 - 10:38:19 EST


Miklos Szeredi <miklos@xxxxxxxxxx> writes:

> On Wed, Oct 22, 2014 at 04:24:18PM -0500, Seth Forshee wrote:
>> Update fuse to translate uids and gids to/from the user namspace
>> of the process servicing requests on /dev/fuse. Any ids which do
>> not map into the namespace will result in errors. inodes will
>> also be marked bad when unmappable ids are received from
>> userspace.
>
> Okay.
>
>> Due to security concerns the namespace used should be fixed,
>> otherwise a user might be able to gain elevated privileges or
>> influence processes that the user would otherwise be unable to
>> manipulate. Thus the namespace of the mounting process is used
>> for all translations, and this namespace is required to be the
>> same as the one in use when /dev/fuse was opened.
>
> Maybe I'm being dense, but can someone give a concrete example of such an
> attack?

There are two variants of things at play here.

There is the classic if you don't freeze your context at open time when
you pass that file descriptor to another process unexpected things can
happen.

An essentially harmless but extremely confusing example is what happens
to a partial read when it stops halfway through a uid value and the next
read on the same file descriptor is from a process in a different user
namespace. Which uid value should be returned to userspace.

If the kernel is just reporting values all that happens is confusion
with a correct implementation. Confusion however is a breeding ground
for little unexpected behaviors that trigger bugs in the code.

If the kernel is reading values things can get ugly. As root in a user
a namespace I am allowed to call setuid and setgid to any uid or gid
that is mapped into my user namespace but no others.

Now if I am in a nefarious mood I can create a unprivileged user
namespace, open /dev/fuse and mount a fuse filesystem. Pass the file
descriptor to /dev/fuse to a processes that is in the default user
namespace (and thus can use any uid/gid). With that file desctipor
report that there is a setuid 0 exectuable on that file system.

The version of fuse in these patches has two different defenses against
that kind of nefariousness. The first defense restrictions /dev/fuse
to speak the uids and gids that the opener of /dev/fuse has in their
user namespace. The second defense restricts who can access a fuse file
system by requiring them to be in the user namespace of the opener of
/dev/fuse and the mounter of the fuse filesystem.

I find the first defense stronger and easier to analyze. If non-sense
uids can't get past fuse into the vfs we simply don't have to worry
about them.

I hope that helps.

> That might also help me understand how exactly user/pid namespaces work...

The idea of user/pid namespaces is to translate uid, gids and pids at
the edge of userspace into a kernel internal form that can be use
everywhere. In this case we get into the subtlties of which
translations make sense.

> Patch otherwise looks okay.

Eric

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/