[PATCH 0/6] File Sealing & memfd_create()

2014-06-17 Thread Florian Weimer
On 04/10/2014 10:37 PM, Andy Lutomirski wrote:

> It occurs to me that, before going nuts with these kinds of flags, it
> may pay to just try to fix the /proc/self/fd issue for real -- we
> could just make open("/proc/self/fd/3", O_RDWR) fail if fd 3 is
> read-only.  That may be enough for the file sealing thing.

Increasing privilege on O_PATH descriptors via access through 
/proc/self/fd is part of the userspace API.  The same thing might be 
true for O_RDONLY descriptors, but it's a bit less likely that there are 
any users out there.  In any case, I'm not sure it makes sense to plug 
the O_RDONLY hole while leaving the O_PATH hole open.

-- 
Florian Weimer / Red Hat Product Security Team


[PATCH 0/6] File Sealing & memfd_create()

2014-06-17 Thread Andy Lutomirski
On Jun 17, 2014 2:48 AM, "Florian Weimer"  wrote:
>
> On 04/10/2014 10:37 PM, Andy Lutomirski wrote:
>
>> It occurs to me that, before going nuts with these kinds of flags, it
>> may pay to just try to fix the /proc/self/fd issue for real -- we
>> could just make open("/proc/self/fd/3", O_RDWR) fail if fd 3 is
>> read-only.  That may be enough for the file sealing thing.
>
>
> Increasing privilege on O_PATH descriptors via access through
/proc/self/fd is part of the userspace API.  The same thing might be true
for O_RDONLY descriptors, but it's a bit less likely that there are any
users out there.  In any case, I'm not sure it makes sense to plug the
O_RDONLY hole while leaving the O_PATH hole open.

Do you mean O_PATH fds for the directory or O_PATH fds for the file
itself?  In any event, I'm much less concerned about passing O_PATH memfds
around than O_RDONLY memfds.

I have incomplete patches for this stuff.  I need to fix them so they work
and get past Al Viro.


--Andy
-- next part --
An HTML attachment was scrubbed...
URL: 



[PATCH 0/6] File Sealing & memfd_create()

2014-04-22 Thread David Herrmann
Hi

On Tue, Apr 22, 2014 at 2:44 PM, Florian Weimer  wrote:
> I didn't find that very convincing.  But in v2, seals are monotonic, so
> checking them should be reliable enough.

Ok.

> What happens when you create a loop device on a write-sealed descriptor?

Any write-back to the loop-device will fail with EPERM as soon as the
fd gets write-sealed. See __do_lo_send_write() in
drivers/block/loop.c. It's up to the loop-device to forward the error
via bio_endio() to the caller for proper error-handling.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-04-22 Thread Florian Weimer
On 04/22/2014 01:55 PM, David Herrmann wrote:
> Hi
>
> On Tue, Apr 22, 2014 at 11:10 AM, Florian Weimer  
> wrote:
>> Ah.  What do you recommend for recipient to recognize such descriptors?
>> Would they just try to seal them and reject them if this fails?
>
> This highly depends on your use-case. Please see the initial email in
> this thread. It describes 2 example use-cases. In both cases, the
> recipients read the current set of seals and verify that a given set
> of seals is set.

I didn't find that very convincing.  But in v2, seals are monotonic, so 
checking them should be reliable enough.

What happens when you create a loop device on a write-sealed descriptor?

-- 
Florian Weimer / Red Hat Product Security Team


[PATCH 0/6] File Sealing & memfd_create()

2014-04-22 Thread David Herrmann
Hi

On Tue, Apr 22, 2014 at 11:10 AM, Florian Weimer  wrote:
> Ah.  What do you recommend for recipient to recognize such descriptors?
> Would they just try to seal them and reject them if this fails?

This highly depends on your use-case. Please see the initial email in
this thread. It describes 2 example use-cases. In both cases, the
recipients read the current set of seals and verify that a given set
of seals is set.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-04-22 Thread Florian Weimer
On 04/09/2014 11:31 PM, David Herrmann wrote:

> On Tue, Apr 8, 2014 at 3:00 PM, Florian Weimer  wrote:
>> How do you keep these promises on network and FUSE file systems?
>
> I don't. This is shmem only.

Ah.  What do you recommend for recipient to recognize such descriptors? 
  Would they just try to seal them and reject them if this fails?

-- 
Florian Weimer / Red Hat Product Security Team


[PATCH 0/6] File Sealing & memfd_create()

2014-04-20 Thread Pavel Machek
On Thu 2014-04-10 13:37:26, Andy Lutomirski wrote:
> On Thu, Apr 10, 2014 at 1:32 PM, Theodore Ts'o  wrote:
> > On Thu, Apr 10, 2014 at 12:14:27PM -0700, Andy Lutomirski wrote:
> >>
> >> This is the second time in a week that someone has asked for a way to
> >> have a struct file (or struct inode or whatever) that can't be reopened
> >> through /proc/pid/fd.  This should be quite easy to implement as a
> >> separate feature.
> >
> > What I suggested on a different thread was to add the following new
> > file descriptor flags, to join FD_CLOEXEC, which would be maniuplated
> > using the F_GETFD and F_SETFD fcntl commands:
> >
> > FD_NOPROCFS disallow being able to open the inode via /proc//fd
> >
> > FD_NOPASSFD disallow being able to pass the fd via a unix domain socket
> >
> > FD_LOCKFLAGSif this bit is set, disallow any further changes of 
> > FD_CLOEXEC,
> > FD_NOPROCFS, FD_NOPASSFD, and FD_LOCKFLAGS flags.
> >
> > Regardless of what else we might need to meet the use case for the
> > proposed File Sealing API, I think this is a useful feature that could
> > be used in many other contexts besides just the proposed
> > memfd_create() use case.
> 
> It occurs to me that, before going nuts with these kinds of flags, it
> may pay to just try to fix the /proc/self/fd issue for real -- we
> could just make open("/proc/self/fd/3", O_RDWR) fail if fd 3 is
> read-only.  That may be enough for the file sealing thing.

Yes please.

Current behaviour is very unexpected, and unexpected behaviour in
security area is normally called "security hole".

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


[PATCH 0/6] File Sealing & memfd_create()

2014-04-11 Thread David Herrmann
Hi

On Fri, Apr 11, 2014 at 1:05 AM, Andy Lutomirski  wrote:
> /proc/pid/fd is a really weird corner case in which the mode of an
> inode that doesn't have a name matters.  I suspect that almost no one
> will ever want to open one of these things out of /proc/self/fd, and
> those who do should be made to think about it.

I'm arguing in the context of memfd, and there's no security leak if
people get access to the underlying inode (at least I'm not aware of
any). As I said, context information is attached to the inode, not
file context, so I'm fine if people want to open multiple file
contexts via /proc. If someone wants to forbid open(), I want to hear
_why_. I assume the memfd object has uid==uid-of-creator and
mode==(777 & ~umask) (which usually results in X00, so no access for
non-owners). I cannot see how /proc is a security issue here.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-04-11 Thread David Herrmann
Hi

On Thu, Apr 10, 2014 at 11:16 PM, Andy Lutomirski  
wrote:
> Would it make sense for the initial mode on a memfd inode to be 000?
> Anyone who finds this to be problematic could use fchmod to fix it.

memfd_create() should be subject to umask() just like anything else.
That should solve any possible race here, right?

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-04-11 Thread Alex Elsayed
Colin Walters wrote:

> On Thu, Apr 10, 2014 at 3:15 PM, Andy Lutomirski 
> wrote:
>> 
>> 
>> COW links can do this already, I think.  Of course, you'll have to
>> use a
>> filesystem that supports them.
> 
> COW is nice if the filesystem supports them, but my userspace code
> needs to be filesystem agnostic.  Because of that, the design for
> userspace simply doesn't allow arbitrary writes.
> 
> Instead, I have to painfully audit every rpm %post/dpkg postinst type
> script to ensure they break hardlinks, and furthermore only allow
> executing scripts that are known to do so.
> 
> But I think even in a btrfs world it'd still be useful to mark files as
> content-immutable.

If you create each tree as a subvolume and when it's complete put it in 
place with btrfs subvolume snapshot -r FOO_inprogress /ostree/repo/FOO,
you get exactly that.

You can even use the new(ish) btrfs out-of-band dedup functionality to 
deduplicate read-only snapshots safely.



[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread David Herrmann
Hi

On Thu, Apr 10, 2014 at 10:37 PM, Andy Lutomirski  
wrote:
> It occurs to me that, before going nuts with these kinds of flags, it
> may pay to just try to fix the /proc/self/fd issue for real -- we
> could just make open("/proc/self/fd/3", O_RDWR) fail if fd 3 is
> read-only.  That may be enough for the file sealing thing.

For the sealing API, none of this is needed. As long as the inode is
owned by the uid who creates the memfd, you can pass it around and
no-one besides root and you can open /proc/self/fd/$fd (assuming chmod
700). If you share the fd with someone with the same uid as you,
you're screwed anyway. We don't protect users against themselves (I
mean, they can ptrace you, or kill()..). Therefore, I'm not really
convinced that we want this for memfd. At least no-one has provided a
_proper_ use-case for this so far.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Colin Walters
On Thu, Apr 10, 2014 at 3:15 PM, Andy Lutomirski  
wrote:
> 
> 
> COW links can do this already, I think.  Of course, you'll have to 
> use a
> filesystem that supports them.

COW is nice if the filesystem supports them, but my userspace code 
needs to be filesystem agnostic.  Because of that, the design for 
userspace simply doesn't allow arbitrary writes.

Instead, I have to painfully audit every rpm %post/dpkg postinst type 
script to ensure they break hardlinks, and furthermore only allow 
executing scripts that are known to do so.

But I think even in a btrfs world it'd still be useful to mark files as 
content-immutable.






[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Theodore Ts'o
On Thu, Apr 10, 2014 at 12:14:27PM -0700, Andy Lutomirski wrote:
> 
> This is the second time in a week that someone has asked for a way to
> have a struct file (or struct inode or whatever) that can't be reopened
> through /proc/pid/fd.  This should be quite easy to implement as a
> separate feature.

What I suggested on a different thread was to add the following new
file descriptor flags, to join FD_CLOEXEC, which would be maniuplated
using the F_GETFD and F_SETFD fcntl commands:

FD_NOPROCFS disallow being able to open the inode via /proc//fd

FD_NOPASSFD disallow being able to pass the fd via a unix domain socket

FD_LOCKFLAGSif this bit is set, disallow any further changes of FD_CLOEXEC,
FD_NOPROCFS, FD_NOPASSFD, and FD_LOCKFLAGS flags.

Regardless of what else we might need to meet the use case for the
proposed File Sealing API, I think this is a useful feature that could
be used in many other contexts besides just the proposed
memfd_create() use case.

Cheers,

- Ted


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On Thu, Apr 10, 2014 at 4:16 PM, David Herrmann  
wrote:
> Hi
>
> On Fri, Apr 11, 2014 at 1:05 AM, Andy Lutomirski  
> wrote:
>> /proc/pid/fd is a really weird corner case in which the mode of an
>> inode that doesn't have a name matters.  I suspect that almost no one
>> will ever want to open one of these things out of /proc/self/fd, and
>> those who do should be made to think about it.
>
> I'm arguing in the context of memfd, and there's no security leak if
> people get access to the underlying inode (at least I'm not aware of
> any).

I'm not sure what you mean.

> As I said, context information is attached to the inode, not
> file context, so I'm fine if people want to open multiple file
> contexts via /proc. If someone wants to forbid open(), I want to hear
> _why_. I assume the memfd object has uid==uid-of-creator and
> mode==(777 & ~umask) (which usually results in X00, so no access for
> non-owners). I cannot see how /proc is a security issue here.

On further reflection, my argument for 000 is crap.  As far as I can
see, the only time that the mode matters at all when playing with
/proc/pid/fd, and they only way to get a non-O_RDWR memfd is using
/proc/pid/fd, so I'll argue for 0600 instead.

Argument why 0600 is better than 0600 & ~umask: either callers don't
care because the inode mode simply doesn't matter or they're using
/proc/pid/fd to *reduce* permissions, in which case they'd probably
like to avoid having to play with umask or call fchmod.

Argument why 0600 is better than 0777 & ~umask: People /prod/pid/fd
are the only ones who care, in which case they probably prefer for the
permissions not be increased by other users if they give them a
reduced-permission fd.

Anyway, this is all mostly unimportant.  Some text in the man page is
probably sufficient, but I still think that 0600 is trivial to
implement and a little bit more friendly.

--Andy

>
> Thanks
> David



-- 
Andy Lutomirski
AMA Capital Management, LLC


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On Thu, Apr 10, 2014 at 3:57 PM, David Herrmann  
wrote:
> Hi
>
> On Thu, Apr 10, 2014 at 11:16 PM, Andy Lutomirski  
> wrote:
>> Would it make sense for the initial mode on a memfd inode to be 000?
>> Anyone who finds this to be problematic could use fchmod to fix it.
>
> memfd_create() should be subject to umask() just like anything else.
> That should solve any possible race here, right?

Yes, but how many people will actually think about umask when doing
things that don't really look like creating files?

/proc/pid/fd is a really weird corner case in which the mode of an
inode that doesn't have a name matters.  I suspect that almost no one
will ever want to open one of these things out of /proc/self/fd, and
those who do should be made to think about it.

It also avoids odd screwups where things are secure until someone runs
them with umask 000.

--Andy


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Colin Walters
On Thu, Mar 20, 2014 at 11:32 AM, tytso at mit.edu wrote:
> 
> Looking at your patches, and what files you are modifying, you are
> enforcing this in the low-level file system.

I would love for this to be implemented in the filesystem level as 
well.  Something like the ext4 immutable bit, but with the ability to 
still make hardlinks would be *very* useful for OSTree.  And anyone 
else that uses hardlinks as a data source.  The vserver people do 
something similiar:
http://linux-vserver.org/util-vserver:Vhashify

At the moment I have a read-only bind mount over /usr, but what I 
really want is to make the individual objects in the object store in 
/ostree/repo/objects be immutable, so even if a user or app navigates 
out to /sysroot they still can't mutate them (or the link targets in 
the visible /usr).






[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On Thu, Apr 10, 2014 at 1:49 PM, David Herrmann  
wrote:
> Hi
>
> On Thu, Apr 10, 2014 at 10:37 PM, Andy Lutomirski  
> wrote:
>> It occurs to me that, before going nuts with these kinds of flags, it
>> may pay to just try to fix the /proc/self/fd issue for real -- we
>> could just make open("/proc/self/fd/3", O_RDWR) fail if fd 3 is
>> read-only.  That may be enough for the file sealing thing.
>
> For the sealing API, none of this is needed. As long as the inode is
> owned by the uid who creates the memfd, you can pass it around and
> no-one besides root and you can open /proc/self/fd/$fd (assuming chmod
> 700). If you share the fd with someone with the same uid as you,
> you're screwed anyway. We don't protect users against themselves (I
> mean, they can ptrace you, or kill()..). Therefore, I'm not really
> convinced that we want this for memfd. At least no-one has provided a
> _proper_ use-case for this so far.

Hmm.  Fair enough.

Would it make sense for the initial mode on a memfd inode to be 000?
Anyone who finds this to be problematic could use fchmod to fix it.

I might even go so far as to suggest that the default uid on the inode
should be 0 (i.e. global root), since there is the odd corner case of
root setting euid != 0, creating a memfd, and setting euid back to 0.
The latter might cause resource accounting issues, though.

--Andy


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On Thu, Apr 10, 2014 at 1:32 PM, Theodore Ts'o  wrote:
> On Thu, Apr 10, 2014 at 12:14:27PM -0700, Andy Lutomirski wrote:
>>
>> This is the second time in a week that someone has asked for a way to
>> have a struct file (or struct inode or whatever) that can't be reopened
>> through /proc/pid/fd.  This should be quite easy to implement as a
>> separate feature.
>
> What I suggested on a different thread was to add the following new
> file descriptor flags, to join FD_CLOEXEC, which would be maniuplated
> using the F_GETFD and F_SETFD fcntl commands:
>
> FD_NOPROCFS disallow being able to open the inode via /proc//fd
>
> FD_NOPASSFD disallow being able to pass the fd via a unix domain socket
>
> FD_LOCKFLAGSif this bit is set, disallow any further changes of 
> FD_CLOEXEC,
> FD_NOPROCFS, FD_NOPASSFD, and FD_LOCKFLAGS flags.
>
> Regardless of what else we might need to meet the use case for the
> proposed File Sealing API, I think this is a useful feature that could
> be used in many other contexts besides just the proposed
> memfd_create() use case.

It occurs to me that, before going nuts with these kinds of flags, it
may pay to just try to fix the /proc/self/fd issue for real -- we
could just make open("/proc/self/fd/3", O_RDWR) fail if fd 3 is
read-only.  That may be enough for the file sealing thing.

--Andy


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On 04/08/2014 06:00 AM, Florian Weimer wrote:
> On 03/19/2014 08:06 PM, David Herrmann wrote:
> 
>> Unlike existing techniques that provide similar protection, sealing
>> allows
>> file-sharing without any trust-relationship. This is enforced by
>> rejecting seal
>> modifications if you don't own an exclusive reference to the given
>> file. So if
>> you own a file-descriptor, you can be sure that no-one besides you can
>> modify
>> the seals on the given file. This allows mapping shared files from
>> untrusted
>> parties without the fear of the file getting truncated or modified by an
>> attacker.
> 
> How do you keep these promises on network and FUSE file systems?  Surely
> there is still some trust involved for such descriptors?
> 
> What happens if you create a loop device on a sealed descriptor?
> 
> Why does memfd_create not create a file backed by a memory region in the
> current process?  Wouldn't this be a far more generic primitive?
> Creating aliases of memory regions would be interesting for many things
> (not just libffi bypassing SELinux-enforced NX restrictions :-).

If you write a patch to prevent selinux from enforcing NX, I will ack
that patch with all my might.  I don't know how far it would get me, but
I think that selinux has no business going anywhere near execmem.

Adding a clone mode to mremap might be a better bet.  But memfd solves
that problem, too, albeit messily.

--Andy


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On 04/10/2014 07:45 AM, Colin Walters wrote:
> On Thu, Mar 20, 2014 at 11:32 AM, tytso at mit.edu wrote:
>>
>> Looking at your patches, and what files you are modifying, you are
>> enforcing this in the low-level file system.
> 
> I would love for this to be implemented in the filesystem level as
> well.  Something like the ext4 immutable bit, but with the ability to
> still make hardlinks would be *very* useful for OSTree.  And anyone else
> that uses hardlinks as a data source.  The vserver people do something
> similiar:
> http://linux-vserver.org/util-vserver:Vhashify
> 
> At the moment I have a read-only bind mount over /usr, but what I really
> want is to make the individual objects in the object store in
> /ostree/repo/objects be immutable, so even if a user or app navigates
> out to /sysroot they still can't mutate them (or the link targets in the
> visible /usr).

COW links can do this already, I think.  Of course, you'll have to use a
filesystem that supports them.

--Andy


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread Andy Lutomirski
On 03/20/2014 09:38 AM, tytso at mit.edu wrote:
> On Thu, Mar 20, 2014 at 04:48:30PM +0100, David Herrmann wrote:
>> On Thu, Mar 20, 2014 at 4:32 PM,   wrote:
>>> Why not make sealing an attribute of the "struct file", and enforce it
>>> at the VFS layer?  That way all file system objects would have access
>>> to sealing interface, and for memfd_shmem, you can't get another
>>> struct file pointing at the object, the security properties would be
>>> identical.
>>
>> Sealing as introduced here is an inode-attribute, not "struct file".
>> This is intentional. For instance, a gfx-client can get a read-only FD
>> via /proc/self/fd/ and pass it to the compositor so it can never
>> overwrite the contents (unless the compositor has write-access to the
>> inode itself, in which case it can just re-open it read-write).
> 
> Hmm, good point.  I had forgotten about the /proc/self/fd hole.
> Hmm... what if we have a SEAL_PROC which forces the permissions of
> /proc/self/fd to be 000?

This is the second time in a week that someone has asked for a way to
have a struct file (or struct inode or whatever) that can't be reopened
through /proc/pid/fd.  This should be quite easy to implement as a
separate feature.

Actually, that feature would solve a major pet peeve of mine, I think: I
want something like memfd that allows me to keep the thing read-write
but that whomever I pass the fd to can't change.  With this feature, I
could do:

fd_rw = memfd_create (or O_TMPFILE or whatever)
fd_ro = open(/proc/self/fd/fd_ro, O_RDONLY);
fcntl(fd_ro, F_RESTRICT, F_RESTRICT_REOPEN);

send fd_ro via SCM_RIGHTS.

To really make this work well, I also want to SEAL_SHRINK the inode so
that the receiver can verify that I'm not going to truncate the file out
from under it.

Bingo, fast and secure one-way IPC.

--Andy


[PATCH 0/6] File Sealing & memfd_create()

2014-04-10 Thread David Herrmann
Hi

On Tue, Apr 8, 2014 at 3:00 PM, Florian Weimer  wrote:
> How do you keep these promises on network and FUSE file systems?

I don't. This is shmem only.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-04-08 Thread Florian Weimer
On 03/19/2014 08:06 PM, David Herrmann wrote:

> Unlike existing techniques that provide similar protection, sealing allows
> file-sharing without any trust-relationship. This is enforced by rejecting 
> seal
> modifications if you don't own an exclusive reference to the given file. So if
> you own a file-descriptor, you can be sure that no-one besides you can modify
> the seals on the given file. This allows mapping shared files from untrusted
> parties without the fear of the file getting truncated or modified by an
> attacker.

How do you keep these promises on network and FUSE file systems?  Surely 
there is still some trust involved for such descriptors?

What happens if you create a loop device on a sealed descriptor?

Why does memfd_create not create a file backed by a memory region in the 
current process?  Wouldn't this be a far more generic primitive? 
Creating aliases of memory regions would be interesting for many things 
(not just libffi bypassing SELinux-enforced NX restrictions :-).

-- 
Florian Weimer / Red Hat Product Security Team


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread David Herrmann
Hi

On Thu, Mar 20, 2014 at 4:32 PM,   wrote:
> Why not make sealing an attribute of the "struct file", and enforce it
> at the VFS layer?  That way all file system objects would have access
> to sealing interface, and for memfd_shmem, you can't get another
> struct file pointing at the object, the security properties would be
> identical.

Sealing as introduced here is an inode-attribute, not "struct file".
This is intentional. For instance, a gfx-client can get a read-only FD
via /proc/self/fd/ and pass it to the compositor so it can never
overwrite the contents (unless the compositor has write-access to the
inode itself, in which case it can just re-open it read-write).

Furthermore, I don't see any use-case besides memfd for sealing, so I
purposely avoided changing core VFS interfaces. Protecting
page-allocation/access for SEAL_WRITE like I do in shmem.c is not that
easy to do generically. So if we moved this interface to "struct
inode", all that would change is moving "u32 seals;" from one struct
to the other. Ok, some protections might get easily implemented
generically, but I without proper insight in the underlying
implemenation, I couldn't verify all paths and possible races. Isn't
keeping the API generic enough so far? Changing the underlying
implementation can be done once we know what we want.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread David Herrmann
Hi

On Thu, Mar 20, 2014 at 3:41 PM, One Thousand Gnomes
 wrote:
> I think you want two things at minimum
>
> owner to seal
> root can always override

Why should root be allowed to override?

> I would query the name too. Right now your assumption is 'shmem only' but
> that might change with other future use cases or types (eg some driver
> file handles) so SHMEM_ in the fcntl might become misleading.

I'm fine with F_SET/GET_SEALS. But given you suggested requiring
MFD_ALLOW_SEALS for sealing, I don't see why we couldn't limit this
interface entirely to memfd_create().

> Whether you want some way to undo a seal without an exclusive reference as
> the file owner is another question.

No. You are never allowed to undo a seal but with an exclusive
reference. This interface was created for situations _without_ any
trust relationship. So if the owner is allowed to undo seals, the
interface doesn't make any sense. The only options I see is to not
allow un-sealing at all (which I'm fine with) or tracking users (which
is way too much overhead).

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread One Thousand Gnomes
On Thu, 20 Mar 2014 11:32:51 -0400
tytso at mit.edu wrote:

> On Wed, Mar 19, 2014 at 08:06:45PM +0100, David Herrmann wrote:
> > 
> > This series introduces the concept of "file sealing". Sealing a file 
> > restricts
> > the set of allowed operations on the file in question. Multiple seals are
> > defined and each seal will cause a different set of operations to return 
> > EPERM
> > if it is set. The following seals are introduced:
> > 
> >  * SEAL_SHRINK: If set, the inode size cannot be reduced
> >  * SEAL_GROW: If set, the inode size cannot be increased
> >  * SEAL_WRITE: If set, the file content cannot be modified
> 
> Looking at your patches, and what files you are modifying, you are
> enforcing this in the low-level file system.
> 
> Why not make sealing an attribute of the "struct file", and enforce it
> at the VFS layer?  That way all file system objects would have access
> to sealing interface, and for memfd_shmem, you can't get another
> struct file pointing at the object, the security properties would be
> identical.

Would it be more sensible to have a "sealer" which is a "device" which
you give a file handle too and it gives you back a sealable one.

So for the memfd case you'd create a private handle, pass it to the
sealer, and then pass the sealer handles to everyone else.

You have to implicitly trust the creator of the object has
- handed you the object you expect
- sealed it

so that appears no weaker but means you can meaningfully created sealed
versions of arbitary objects and if you want have non-sealed ones around
with it being up to the creator if they want for example to simply close
the unsealed one immediately afterwards.

Alan


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread One Thousand Gnomes
On Thu, 20 Mar 2014 16:12:54 +0100
David Herrmann  wrote:

> Hi
> 
> On Thu, Mar 20, 2014 at 3:41 PM, One Thousand Gnomes
>  wrote:
> > I think you want two things at minimum
> >
> > owner to seal
> > root can always override
> 
> Why should root be allowed to override?

Because root can already override it by say mmapping the kernel memory
and patching. It also tends to be valuable for debugging horrible
problems with complex systems.

Imposing fake restrictions on root just causes annoyance when doing stuff
like debugging but doesn't actually change the security situation.
> 
> I'm fine with F_SET/GET_SEALS. But given you suggested requiring
> MFD_ALLOW_SEALS for sealing, I don't see why we couldn't limit this
> interface entirely to memfd_create().

But if someone does find a non memfd use for it then it's useful not to
have to go "this fnctl for memfd, that fnctl for the other"

Just planning ahead.


> > Whether you want some way to undo a seal without an exclusive reference as
> > the file owner is another question.
> 
> No. You are never allowed to undo a seal but with an exclusive
> reference. This interface was created for situations _without_ any
> trust relationship. So if the owner is allowed to undo seals, the
> interface doesn't make any sense. The only options I see is to not
> allow un-sealing at all (which I'm fine with) or tracking users (which
> is way too much overhead).

Ok - that makes sense


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread One Thousand Gnomes
> My first idea was to add MFD_ALLOW_SEALING as memfd_create() flag,
> which enables the sealing-API for that file. Then I looked at POSIX

This actually seems the most sensible to me. The reason being that if I
have some existing used object there is no way on earth I can be sure who
has existing references to it, and we don't have revoke() to fix that.

So it pretty much has to be a new object in a sane programming model.

> mandatory locking and noticed that it provides similar restrictions on
> _all_ files. Mandatory locks can be more easily removed, but an

The fact someone got it past a standards body doesn't make it a good idea.

> attacker could just re-apply them in a loop, so that's not really an
> argument. Furthermore, sealing requires _write_ access so I wonder
> what kind of DoS attacks are possible with sealing that are not
> already possible with write access? And sealing is only possible if no
> writable, shared mapping exists. So even if an attacker seals a file,
> all that happens is EPERM, not SIGBUS (still a possible
> denial-of-service scenario).

I think you want two things at minimum

owner to seal
root can always override

I would query the name too. Right now your assumption is 'shmem only' but
that might change with other future use cases or types (eg some driver
file handles) so SHMEM_ in the fcntl might become misleading.

Whether you want some way to undo a seal without an exclusive reference as
the file owner is another question.

Alan


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread ty...@mit.edu
On Thu, Mar 20, 2014 at 04:48:30PM +0100, David Herrmann wrote:
> On Thu, Mar 20, 2014 at 4:32 PM,   wrote:
> > Why not make sealing an attribute of the "struct file", and enforce it
> > at the VFS layer?  That way all file system objects would have access
> > to sealing interface, and for memfd_shmem, you can't get another
> > struct file pointing at the object, the security properties would be
> > identical.
> 
> Sealing as introduced here is an inode-attribute, not "struct file".
> This is intentional. For instance, a gfx-client can get a read-only FD
> via /proc/self/fd/ and pass it to the compositor so it can never
> overwrite the contents (unless the compositor has write-access to the
> inode itself, in which case it can just re-open it read-write).

Hmm, good point.  I had forgotten about the /proc/self/fd hole.
Hmm... what if we have a SEAL_PROC which forces the permissions of
/proc/self/fd to be 000?

So if it is a property of the attribute, SEAL_WRITE and SEAL_GROW is
basically equivalent to using chattr to set the immutable and
append-only attribute, except for the "you can't undo the seal unless
you have exclusive access to the inode" magic.

That does make it pretty memfd_create specific and not a very general
API, which is a little unfortunate; hence why I'm trying to explore
ways of making a bit more generic and hopefully useful for more use
cases.

Cheers,

- Ted


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread ty...@mit.edu
On Wed, Mar 19, 2014 at 08:06:45PM +0100, David Herrmann wrote:
> 
> This series introduces the concept of "file sealing". Sealing a file restricts
> the set of allowed operations on the file in question. Multiple seals are
> defined and each seal will cause a different set of operations to return EPERM
> if it is set. The following seals are introduced:
> 
>  * SEAL_SHRINK: If set, the inode size cannot be reduced
>  * SEAL_GROW: If set, the inode size cannot be increased
>  * SEAL_WRITE: If set, the file content cannot be modified

Looking at your patches, and what files you are modifying, you are
enforcing this in the low-level file system.

Why not make sealing an attribute of the "struct file", and enforce it
at the VFS layer?  That way all file system objects would have access
to sealing interface, and for memfd_shmem, you can't get another
struct file pointing at the object, the security properties would be
identical.

Cheers,

- Ted


[PATCH 0/6] File Sealing & memfd_create()

2014-03-20 Thread David Herrmann
Hi

On Thu, Mar 20, 2014 at 4:49 AM, Linus Torvalds
 wrote:
> Is there really any use-case where the sealer isn't also the same
> thing that *created* the file in the first place? Because I would be a
> ton happier with the notion that you can only seal things that you
> yourself created. At that point, the exclusive reference isn't such a
> big deal any more, but more importantly, you can't play random
> denial-of-service games on files that aren't really yours.

My first idea was to add MFD_ALLOW_SEALING as memfd_create() flag,
which enables the sealing-API for that file. Then I looked at POSIX
mandatory locking and noticed that it provides similar restrictions on
_all_ files. Mandatory locks can be more easily removed, but an
attacker could just re-apply them in a loop, so that's not really an
argument. Furthermore, sealing requires _write_ access so I wonder
what kind of DoS attacks are possible with sealing that are not
already possible with write access? And sealing is only possible if no
writable, shared mapping exists. So even if an attacker seals a file,
all that happens is EPERM, not SIGBUS (still a possible
denial-of-service scenario).

But I understand that it is quite hard to review all the possible
scenarios. So I'm fine with checking inode-ownership permissions for
SET_SEALS. We could also make sealing a one-shot operation. Given that
in a no-trust situation there is never a guarantee that the other side
drops its references, re-using a sealed file is usually not possible.
However, in sane environments, this could be a nice optimization in
case the other side plays along. The one-shot semantics would allow
dropping reference-checks entirely. The inode-ownership semantics
would still require it.

Thanks
David


[PATCH 0/6] File Sealing & memfd_create()

2014-03-19 Thread Linus Torvalds
On Wed, Mar 19, 2014 at 12:06 PM, David Herrmann  
wrote:
>
> Unlike existing techniques that provide similar protection, sealing allows
> file-sharing without any trust-relationship. This is enforced by rejecting 
> seal
> modifications if you don't own an exclusive reference to the given file.

I like the concept, but I really hate that "exclusive reference"
approach. I see why you did it, but I also worry that it means that
people can open random shm files that are *not* expected to be sealed,
and screw up applications that don't expect it.

Is there really any use-case where the sealer isn't also the same
thing that *created* the file in the first place? Because I would be a
ton happier with the notion that you can only seal things that you
yourself created. At that point, the exclusive reference isn't such a
big deal any more, but more importantly, you can't play random
denial-of-service games on files that aren't really yours.

The fact that you bring up the races involved with the exclusive
reference approach also just makes me go "Is that really the correct
security model"?

   Linus


[PATCH 0/6] File Sealing & memfd_create()

2014-03-19 Thread David Herrmann
Hi

This series introduces the concept of "file sealing". Sealing a file restricts
the set of allowed operations on the file in question. Multiple seals are
defined and each seal will cause a different set of operations to return EPERM
if it is set. The following seals are introduced:

 * SEAL_SHRINK: If set, the inode size cannot be reduced
 * SEAL_GROW: If set, the inode size cannot be increased
 * SEAL_WRITE: If set, the file content cannot be modified

Unlike existing techniques that provide similar protection, sealing allows
file-sharing without any trust-relationship. This is enforced by rejecting seal
modifications if you don't own an exclusive reference to the given file. So if
you own a file-descriptor, you can be sure that no-one besides you can modify
the seals on the given file. This allows mapping shared files from untrusted
parties without the fear of the file getting truncated or modified by an
attacker.

Several use-cases exist that could make great use of sealing:

  1) Graphics Compositors
 If a graphics client creates a memory-backed render-buffer and passes a
 file-decsriptor to it to the graphics server for display, the server
 _has_ to setup SIGBUS handlers whenever mapping the given file. Otherwise,
 the client might run ftruncate() or O_TRUNC on the on file in parallel,
 thus crashing the server.
 With sealing, a compositor can reject any incoming file-descriptor that
 does _not_ have SEAL_SHRINK set. This way, any memory-mappings are
 guaranteed to stay accessible. Furthermore, we still allow clients to
 increase the buffer-size in case they want to resize the render-buffer for
 the next frame. We also allow parallel writes so the client can render new
 frames into the same buffer (client is responsible of never rendering into
 a front-buffer if you want to avoid artifacts).

 Real use-case: Wayland wl_shm buffers can be transparently converted

  2) Geneal-purpose IPC
 IPC mechanisms that do not require a mutual trust-relationship (like dbus)
 cannot do zero-copy so far. With sealing, zero-copy can be easily done by
 sharing a file-descriptor that has SEAL_SHRINK | SEAL_GROW | SEAL_WRITE
 set. This way, the source can store sensible data in the file, seal the
 file and then pass it to the destination. The destination verifies these
 seals are set and then can parse the message in-line.
 Note that these files are usually one-shot files. Without any
 trust-relationship, a destination can notify the source that it released a
 file again, but a source can never rely on it. So unless the destination
 releases the file, a source cannot clear the seals for modification again.
 However, this is inherent to situations without any trust-relationship.

 Real use-case: kdbus messages already use a similar interface and can be
transparently converted to use these seals

Other similar use-cases exist (eg., audio), but these two I am personally
working on. Interest in this interface has been raised from several other camps
and I've put respective maintainers into CC. If more information on these
use-cases is needed, I think they can give some insights.

The API introduced by this patchset is:

 * fcntl() extension:
   Two new fcntl() commands are added that allow retrieveing (SHMEM_GET_SEALS)
   and setting (SHMEM_SET_SEALS) seals on a file. Only shmfs implements them so
   far and there is no intention to implement them on other file-systems.
   All shmfs based files support sealing.

   Patch 2/6

 * memfd_create() syscall:
   The new memfd_create() syscall is a public frontend to the shmem_file_new()
   interface in the kernel. It avoids the need of a local shmfs mount-point (as
   requested by android people) and acts more like MAP_ANON than O_TMPFILE.

   Patch 3/6

The other 4 patches are cleanups, self-tests and docs.

The commit-messages explain the API extensions in detail. Man-page proposals
are also provided. Last but not least, the extensive self-tests document the
intended behavior, in case it is still not clear.

Technically, sealing and memfd_create() are independent, but the described
use-cases would greatly benefit from the combination of both. Hence, I merged
them into the same series. Please also note that this series is based on earlier
works (ashmem, memfd, shmgetfd, ..) and unifies these attempts.

Comments welcome!

Thanks
David

David Herrmann (4):
  fs: fix i_writecount on shmem and friends
  shm: add sealing API
  shm: add memfd_create() syscall
  selftests: add memfd_create() + sealing tests

David Herrmann (2): (man-pages)
  fcntl.2: document SHMEM_SET/GET_SEALS commands
  memfd_create.2: add memfd_create() man-page

 arch/x86/syscalls/syscall_32.tbl   |   1 +
 arch/x86/syscalls/syscall_64.tbl   |   1 +
 fs/fcntl.c |  12 +-
 fs/file_table.c|  27 +-
 include/linux/shmem_fs.h  

[PATCH 0/6] File Sealing & memfd_create()

2014-03-19 Thread Greg Kroah-Hartman
On Wed, Mar 19, 2014 at 08:06:45PM +0100, David Herrmann wrote:
> Hi
> 
> This series introduces the concept of "file sealing". Sealing a file restricts
> the set of allowed operations on the file in question. Multiple seals are
> defined and each seal will cause a different set of operations to return EPERM
> if it is set. The following seals are introduced:
> 
>  * SEAL_SHRINK: If set, the inode size cannot be reduced
>  * SEAL_GROW: If set, the inode size cannot be increased
>  * SEAL_WRITE: If set, the file content cannot be modified
> 
> Unlike existing techniques that provide similar protection, sealing allows
> file-sharing without any trust-relationship. This is enforced by rejecting 
> seal
> modifications if you don't own an exclusive reference to the given file. So if
> you own a file-descriptor, you can be sure that no-one besides you can modify
> the seals on the given file. This allows mapping shared files from untrusted
> parties without the fear of the file getting truncated or modified by an
> attacker.
> 
> Several use-cases exist that could make great use of sealing:
> 
>   1) Graphics Compositors
>  If a graphics client creates a memory-backed render-buffer and passes a
>  file-decsriptor to it to the graphics server for display, the server
>  _has_ to setup SIGBUS handlers whenever mapping the given file. 
> Otherwise,
>  the client might run ftruncate() or O_TRUNC on the on file in parallel,
>  thus crashing the server.
>  With sealing, a compositor can reject any incoming file-descriptor that
>  does _not_ have SEAL_SHRINK set. This way, any memory-mappings are
>  guaranteed to stay accessible. Furthermore, we still allow clients to
>  increase the buffer-size in case they want to resize the render-buffer 
> for
>  the next frame. We also allow parallel writes so the client can render 
> new
>  frames into the same buffer (client is responsible of never rendering 
> into
>  a front-buffer if you want to avoid artifacts).
> 
>  Real use-case: Wayland wl_shm buffers can be transparently converted

Very nice, the Enlightenment developers have been asking for something
like this for a while, it should help them out a lot as well.

And thanks for the man pages and test code, if only all new apis came
with that already...

greg k-h