2007-05-28 22:30:32

by Crispin Cowan

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSM hook

Cliffe wrote:
> The following would be used in conjunction with a pathname based
> confinement to try to provide some assurances about what a path refers
> to.
>
> "/etc/shadow" is a name to a sensitive resource. There is no guarantee
> that there are not other ways to access this resource. For example a
> link "/etc/shadowlink" or a rename to "/etc/shadownewname"
>
> Pathname based security has various advantages (such as the ability to
> have more readable and centralised policies by describing resources in
> terms of their pathnames) but the above is clearly a problem (if
> confidentiality or integrity of a specific resource is important).
>
> Could we find a way to make paths a more reliable mechanism by
> labeling the file data with a simple description of names it is
> allowed to be accessed with?
>
> If we want "/etc/shadow" to be the only way to access the shadow file
> we could label the data with "/etc/shadow". Any attempts to access
> this data using a renamed file or link would be denied (attempts to
> link or rename could also be denied).
Eloquently put.

AppArmor actually does something similar to this, by mediating all of
the ways that you can make an alias to a file. These are:

* Symbolic links: these actually don't work for making aliases with
respect to LSM-based security systems such as AppArmor, SELinux,
and TOMOYO Linux, because the symbolic link is resolved before the
access request is presented to the LSM hooks. So if you create the
symbolic link /tmp/harmless -> /etc/shadow and then the confined
victim tries to access /tmp/harmless, what the LSM sees is an
attempt to access /etc/shadow.
* Hard links: AppArmor explicitly mediates permission to make a hard
link to a file. To be able to make a hard link /tmp/harmless ->
/etc/shadow you have to have explicit permission to do so, or the
attempt to make the link is blocked. This mediation is kept
relatively simple by the fact that you can only hard link to
files, and not to directories.
* Multiple mounts: Linux lets you mount the same file system
multiple times at multiple mount points, so the same file could
appear at two different places. AppArmor has very coarse mediation
here, and simply prohibits all calls to mount() without special
permission. So only highly privileged processes can create such an
alias.
* Name spaces: Linux name spaces present a similar issue, and
AppArmor's coarse blocking of mount() serves the same function;
only highly privileged processes are permitted to create name spaces.


> We could label a document with "/home/me/documents/*". Then the
> document could be linked or renamed within that specified directory.
We are thinking about something kind of like this for finer-grained
mediation of mount(). Currently it is all-or-nothing; we either totally
block the ability to create aliases with multiple mount points or name
spaces, or we totally trust the process with permission to do what it
likes with multiple mount point and name space aliases.

What we want is a more nuanced mediation of mount point and name space
manipulation, so that you can write a spec that says "/tmp/* can be
aliased any way you like, but /etc/shadow cannot be aliased at all" or
something like that.

However, not much work has been done on this, because at the moment the
AppArmor team is concentrating on making the code for current
functionality acceptable for upstreaming.

> Obvious problems with this solution:
> * it seems hard to determine what the label should be set to (setting
> it to "*" would be tempting and completely negate the whole thing,
> while setting it to the current filename would often be too restrictive).
This is equivalent to the question of what kind of access to grant to
the data. I don't see it as really difficult. What is harder is that the
specification has to specify what you can alias, and where it can
appear, and dealing with the two factors tends to make one's head hurt.

I am reminded of the pithy quote "Noalias must go. This is not
negotiable" -- Dennis Ritchie, referring to a proposed 'noalias' type
qualifier in ANSI C http://www.lysator.liu.se/c/dmr-on-noalias.html

Mediating permission to make aliases is complicated :(

> * when files are created these labels need to be created, and they may
> need to be changed.
.. if you use the approach of labeling the files :) In fact this
problem is general: label-based security has a hard time dealing with
new files in general, not just with respect to permission to create
aliases. The security policy for a newly created file is determined by
the label on the file, and so labeling new files is critical. SELinux
uses a variety of smart heuristics to decide the label of a new file:

* the label of the parent directory
* the label of the creating process
* the domain for the creating process can do conditional things
based on the label of the parent directory and the creating process
* applications that link to libselinux can overtly set the label
according to application logic

AppArmor, not using labels, doesn't have this problem. You can write an
AA profile with respect to files and directories that don't exist at all.

> * if this type of solution requires significant additional management
> (as it seems to) it is probably not a suitable addition to a pathname
> based confinement mechanism.
As I explained above, a lot of it is already in place with our mediation
of hard links. Our mediation of multiple mount points and name spaces is
lame, but the extent to which this needs to be improved will largely be
determined by how application developers choose to use these features.
Because AppArmor is intended primarily to confine applications, an
administrative approach of just using unconfined (completely trusted)
shells to manipulate name spaces and multiple mount points suffices, and
application manipulation of name spaces and multiple mount points is the
only concern.

> * A program creating a new file and copying the contents of the file
> is outside of the scope of this solution.
That is the information flow problem. While important, it is fairly
separate from the alias problem. The information flow problem is general
to all access control systems, while the alias problem is special to
name-based access control systems.

This is one of the name/label trade-offs. Aliasing is problematic in
name based systems, while new file creation is problematic in label
based systems. This follows directly from the semantics each system is
using:

* Names are references. Name based systems are really mediating
access to references. Thus creating new references and who can
access these new references is problematic.
* Labels are equivalence classes of objects. Label based systems are
really mediating access to objects, regardless of the reference.
Thus creating new objects and who can access these new objects is
problematic.


> * Stoping a path from pointing to arbitrary data is also outside the
> scope of this solution (for example "/etc/shadow" could be replaced
> with another file).
This depends on where you place the "may alias" access control. You can
put it on the source (/tmp/harmless -> somewhere) on the target
(somewhere -> /etc/shadow) or somewhere else (what AppArmor does,
associating the policy with confined processes).

> Could a name based policy include the pathname as well as an inode
> number or some (more secure) identifying attribute (which could be
> calculated based on the supplied pathname)? A one-way-hash would
> identify but could not be used for each file a program accesses as
> they can change...
It could be done, but that has implications. That would mean that you
get the "belt and suspenders" effect of all of the security benefits of
(say) AppArmor and SELinux. But the non-overlapping security benefits
are relatively small (SELinux advocates may dispute this, but whatever,
it is some magnitude). On the other hand, you would get the management
problems of both AppArmor and SELinux; you would have to solve both the
new file problem, and the file alias problem. Think about what you would
have to do to accommodate (say) a text editor's file save procedure of
"write new file.tmp, rename oldfile to oldfile.old, rename newfile.tmp
to oldfile, delete oldfile.old".

So it could be done, but AFAICT, with small benefit and large cost. More
security may be more secure, but it isn't necessarily better.

Crispin

--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering http://novell.com
Security: It's not linear


2007-05-29 11:27:25

by Tetsuo Handa

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook

Hello.

Crispin Cowan wrote:
> AppArmor actually does something similar to this, by mediating all of
> the ways that you can make an alias to a file. These are:
>
> * Symbolic links: these actually don't work for making aliases with
> respect to LSM-based security systems such as AppArmor, SELinux,
> and TOMOYO Linux, because the symbolic link is resolved before the
> access request is presented to the LSM hooks. So if you create the
> symbolic link /tmp/harmless -> /etc/shadow and then the confined
> victim tries to access /tmp/harmless, what the LSM sees is an
> attempt to access /etc/shadow.
Yes, TOMOYO does so too.

Although TOMOYO is not using LSM, TOMOYO checks it by manually inserted hooks
that are called after resolving the symbolic links.

> * Hard links: AppArmor explicitly mediates permission to make a hard
> link to a file. To be able to make a hard link /tmp/harmless ->
> /etc/shadow you have to have explicit permission to do so, or the
> attempt to make the link is blocked. This mediation is kept
> relatively simple by the fact that you can only hard link to
> files, and not to directories.
Yes, TOMOYO does so too.

Conventional UNIX's access control can't restrict
which path_to_file can link with which another_path_to_file
because UNIX's access control is a label-based access control.
Therefore "ln /etc/shadow /tmp/harmless" becomes a problem
when introducing pathname-based access control.

TOMOYO checks the combination of both link source and destination,
using "allow_link path_to_link_source path_to_link_destination" syntax.
Therefore "ln /etc/shadow /tmp/harmless" is impossible as long as
"allow_link /etc/shadow /tmp/harmless" (or something like "allow_link /etc/\* /tmp/\*")
is not given. TOMOYO checks rename operation as well using
"allow_rename path_to_oldname path_to_newname" syntax.

> * Multiple mounts: Linux lets you mount the same file system
> multiple times at multiple mount points, so the same file could
> appear at two different places. AppArmor has very coarse mediation
> here, and simply prohibits all calls to mount() without special
> permission. So only highly privileged processes can create such an
> alias.
Yes, TOMOYO does so too.

But TOMOYO checks not only the capability to call mount() system call
but also the combination of "path_to_device" "path_to_mountpoint" and "filesystem_type"
using "allow_mount path_to_device path_to_mountpoint filesystem_type"
("allow_mount --bind path_to_bind_source path_to_bind_destionation" for bind mounts) syntax.

And, this is why this very long long thread began.
One of the reasons that TOMOYO doesn't use LSM is that
it is impossible to obtain "struct vfsmount" parameter inside some of LSM hook functions.
From the label-based access control's point of view,
bind mount interferes nothing with label based access control
and passing "struct vfsmount" parameter looks redundant.
But, from the pathname-based access control's point of view,
bind mount interferes severely with pathname-based access control
because it is impossible to determine which pathname was requested.
Although both pathnames point to the same object,
TOMOYO focuses on the PROCEDURE FOR REACHING AN OBJECT
and being able to know the procedure is very important.
(In contrast, SELinux focuses on the ATTRIBUTE OF THE REQUESTED OBJECT, doesn't it?)

> So it could be done, but AFAICT, with small benefit and large cost. More
> security may be more secure, but it isn't necessarily better.
I don't think so.
I think the pathname-based access control and the label-based access control are
complementarity relation. TOMOYO can coexist with SELinux and AppArmor.
What is sad, it becomes impossible to coexist with SELinux and AppArmor if TOMOYO uses LSM.

Thanks.

2007-05-29 14:49:09

by Pavel Machek

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSM hook

Hi!

> > If we want "/etc/shadow" to be the only way to access the shadow file
> > we could label the data with "/etc/shadow". Any attempts to access
> > this data using a renamed file or link would be denied (attempts to
> > link or rename could also be denied).
> Eloquently put.
>
> AppArmor actually does something similar to this, by mediating all of
> the ways that you can make an alias to a file. These are:
...
> * Hard links: AppArmor explicitly mediates permission to make a hard

Unfortunately, aparmor is by design limited to subset of distro
(network daemons). Unfortunately, some other programs (passwd, vi)
routinely make hardlinks. So AA mediating hardlink is not enough, as
vi will happily hardlink /etc/shadow into /etc/.vi-shadow-1234.

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

2007-05-29 15:52:24

by Casey Schaufler

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook


--- Tetsuo Handa <[email protected]> wrote:


> Conventional UNIX's access control can't restrict
> which path_to_file can link with which another_path_to_file
> because UNIX's access control is a label-based access control.

UNIX access control is attribute based, not label based. The
distinction may be hair splitting in the current context, but
could be significant later if the thread continues.




Casey Schaufler
[email protected]

2007-05-29 17:08:21

by Andreas Gruenbacher

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook

On Tuesday 29 May 2007 12:46, Tetsuo Handa wrote:
> But, from the pathname-based access control's point of view,
> bind mount interferes severely with pathname-based access control
> because it is impossible to determine which pathname was requested.

Wrong. It is very well possible to determine the path of a particular dentry
(+ vfsmount) with bind mounts.

> Although both pathnames point to the same object, TOMOYO focuses on the
> PROCEDURE FOR REACHING AN OBJECT and being able to know the procedure is
> very important.

This doesn't make sense, either. With the following sequence of syscalls of
processes A and B (both of them in the namespace root),

A: B:
mkdir("/tmp/a")
chdir("/tmp/a")
rename("/tmp/a", "/tmp/b")
creat("f")

the path being checked for the creat call must be "/tmp/b/f", even though
process A never explicitly used "b". If that's not what TOMOYO is doing, then
that's badly broken.

Andreas

2007-05-29 19:58:33

by James Morris

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook

On Tue, 29 May 2007, Casey Schaufler wrote:

> > Conventional UNIX's access control can't restrict
> > which path_to_file can link with which another_path_to_file
> > because UNIX's access control is a label-based access control.
>
> UNIX access control is attribute based, not label based. The
> distinction may be hair splitting in the current context, but
> could be significant later if the thread continues.

What's important is that traditional DAC stores the security attributes
of the object with the object. Call them what you want, it matters not.


- James
--
James Morris
<[email protected]>

2007-05-29 20:47:43

by Tetsuo Handa

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook

Hello.

Andreas Gruenbacher wrote:
> > But, from the pathname-based access control's point of view,
> > bind mount interferes severely with pathname-based access control
> > because it is impossible to determine which pathname was requested.
> Wrong. It is very well possible to determine the path of a particular dentry
> (+ vfsmount) with bind mounts.
AppArmor can't determine which pathname (/tmp/public/file or /tmp/secret/file)
was requested by touch command if bound mount is used in the following way

# mkdir /tmp/public /tmp/secret
# mount -t tmpfs none /tmp/public
# mount --bind /tmp/public /tmp/secret
# touch /tmp/public/file

because security_inode_create() doesn't receive vfsmount, can it?
It is possible to determine that the requested pathname is either
/tmp/public/file or /tmp/secret/file by comparing address of vfsmount
available from current->namespace, but it is impossible to determine which one.

> the path being checked for the creat call must be "/tmp/b/f", even though
> process A never explicitly used "b". If that's not what TOMOYO is doing, then
> that's badly broken.
Yes, of course, TOMOYO checks "/tmp/b/f". What I meant PROCEDURE FOR REACHING is
"which directory does the process need to go through to reach the requested file
if the process's current directory is the root of the process's namespace".
And in this case, it is "/tmp/b/f".

Thanks.

2007-05-29 22:11:20

by Andreas Gruenbacher

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook

On Tuesday 29 May 2007 22:47, Tetsuo Handa wrote:
> AppArmor can't determine which pathname (/tmp/public/file or
> /tmp/secret/file) was requested by touch command if bound mount is used in
> the following way
>
> # mkdir /tmp/public /tmp/secret
> # mount -t tmpfs none /tmp/public
> # mount --bind /tmp/public /tmp/secret
> # touch /tmp/public/file
>
> because security_inode_create() doesn't receive vfsmount, can it?

I don't know what you are talking about -- the very first patch in the
AppArmor series adds the vfsmount parameter to security_inode_create().

Andreas

2007-05-29 23:25:53

by David Lang

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSM hook

On Tue, 29 May 2007, Pavel Machek wrote:

> Hi!
>
>>> If we want "/etc/shadow" to be the only way to access the shadow file
>>> we could label the data with "/etc/shadow". Any attempts to access
>>> this data using a renamed file or link would be denied (attempts to
>>> link or rename could also be denied).
>> Eloquently put.
>>
>> AppArmor actually does something similar to this, by mediating all of
>> the ways that you can make an alias to a file. These are:
> ...
>> * Hard links: AppArmor explicitly mediates permission to make a hard
>
> Unfortunately, aparmor is by design limited to subset of distro
> (network daemons). Unfortunately, some other programs (passwd, vi)
> routinely make hardlinks. So AA mediating hardlink is not enough, as
> vi will happily hardlink /etc/shadow into /etc/.vi-shadow-1234.

but with the AA design of default deny this isn't a big problem unless you
specificly allow some network daemon to access /etc/.vi-shadow-1234

in this context passwd and vi are considered trusted processes, they are
used _after_ you authenticate onto the box.

no, this won't help you much against local users, but there are a _lot_ of
boxes out there with few, if any, local users who don't also have the root
password. AA helps the admin be safer when configuring netwrok daemons.

David Lang

2007-05-29 23:30:54

by Pavel Machek

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSM hook

Hi!

> >>>If we want "/etc/shadow" to be the only way to access the shadow file
> >>>we could label the data with "/etc/shadow". Any attempts to access
> >>>this data using a renamed file or link would be denied (attempts to
> >>>link or rename could also be denied).
> >>Eloquently put.
> >>
> >>AppArmor actually does something similar to this, by mediating all of
> >>the ways that you can make an alias to a file. These are:
> >...
> >> * Hard links: AppArmor explicitly mediates permission to make a hard
> >
> >Unfortunately, aparmor is by design limited to subset of distro
> >(network daemons). Unfortunately, some other programs (passwd, vi)
> >routinely make hardlinks. So AA mediating hardlink is not enough, as
> >vi will happily hardlink /etc/shadow into /etc/.vi-shadow-1234.
>
> but with the AA design of default deny this isn't a big problem unless you
> specificly allow some network daemon to access /etc/.vi-shadow-1234

...or unless vi decides to hardlink into /tmp or something.

> no, this won't help you much against local users, but there are a _lot_ of
> boxes out there with few, if any, local users who don't also have the root
> password. AA helps the admin be safer when configuring netwrok daemons.

Hmm, I guess I'd love "it is useless on multiuser boxes" to become
standard part of AA advertising.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2007-05-30 05:43:18

by Crispin Cowan

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSM hook

Pavel Machek wrote:
>> * Hard links: AppArmor explicitly mediates permission to make a hard
>>
> Unfortunately, aparmor is by design limited to subset of distro
> (network daemons).
That is not true. AppArmor is designed to confine any application you do
not want to trust completely. This includes network daemons (Apache,
Sendmail, BIND, etc.) network clients (Firefox, Thunderbird,
GAIM/Pidgin, etc.) and any other application that mediates trust: where
data on one side of the application is higher privilege than potential
attackers on the other side of the application.

> Unfortunately, some other programs (passwd, vi)
> routinely make hardlinks. So AA mediating hardlink is not enough, as
> vi will happily hardlink /etc/shadow into /etc/.vi-shadow-1234.
>
I have no idea what you are talking about. I routinely profile vim on
stage in AppArmor presentations, and it presents no such problems.

Caveat: the circumstances under which you would actually want to profile
vi are rather limited, most users would not want to do that.

In another post Pavel Machek wrote:
> Hmm, I guess I'd love "it is useless on multiuser boxes" to become
> standard part of AA advertising.
That is usually around slide 7 of the standard AppArmor presentation,
right next to the remarks about how mulituser boxes are nearly extinct
dinosaurs. AppArmor gets some of its simplicity and ease of use by not
considering that vanishing use case. Even so, AppArmor does have uses on
multiuser boxes, just not the uses Pavel wishes for. Fine, use a
different tool for a different task, AppArmor has plenty of use cases.

The limitation Pavel is referring to is that AppArmor does not secure
processes that are not profiled by AppArmor. We know, this is
intentional, and contributes to AppArmor's ease of use, and does not
generate a hole if you consider every process exposed to (say) network
attack and confine it.

Crispin

--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering http://novell.com
Security: It's not linear

2007-05-30 11:39:00

by Tetsuo Handa

[permalink] [raw]
Subject: Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSMhook

Hello.

Andreas Gruenbacher wrote:
> I don't know what you are talking about -- the very first patch in the
> AppArmor series adds the vfsmount parameter to security_inode_create().
I'm talking about "the current version" of AppArmor (I mean AppArmor available for
OpenSuSE 10.1/10.2, but I should call "the previous version" of AppArmor
if you call AppArmor in this series of patch "the current version") can't handle bind mounts.
I know "the next version" of AppArmor (I mean AppArmor in this series of patch)
will be able to handle bind mounts better if these vfsmount patches are adopted.

Thanks.