[Apparmor-dev] AA3 - file rules

John Johansen jjohansen at suse.de
Thu Jan 1 17:38:30 MST 2009


Christian Boltz wrote:
> Hello,
> 
> Am Donnerstag, 1. Januar 2009 schrieb John Johansen:
>> 3. Pathnames with using regular expressions
> 
>>   - . will match any character except '\0'
> 
> Including '/'?
that was the idea, the translation for globbing would be

* -> [^/]*
** -> .*

> 
>> 4. Special kernel variables
> 
>>     @{tid} - task id
> 
> I never heard of a "task id" - what is it used/useful for?
> 
This is more of a better through it in, in case someone wants it.
In the linux kernel it is actually the tid that is the unique identifier
while pid can be shared.

Currently change_hat actually uses the tid to /proc/<pid>/attr/current,
which allows a thread in a process to be in a different hat.  How useful
this is depends on how this is used.  Basically if the thread is an
interpreter then it has some value, but if the confined thread has
direct memory access it is much less so as it can search memory for the
token and break out of the hat.

>> 5. Extended owner rules
> 
>>     #specify an owner uid instead of an owner
>>     owner=(#101) /some/file rw,
> 
> I'm not really happy with using the '#' char because it is also used for 
> comments (and might make syntax highlighting more difficult).
> 
hrmmm, actually me neither, I had meant to change that.

> useradd(8) says:
> 
>     The account name must begin with an alphabetic character and the 
>     rest of the string should be from the POSIX portable character class 
>     ([A-Za-z_][A-Za-z0-9_-.]*[A-Za-z0-9_-.$]).
> 
> This means that usernames _have to_ start with [a-z] and are therefore 
> easy to distinguish from uids. No need to add '#' ;-)
> 
yep, that was a point I was unsure of when I initially wrote that and
then I meant to change that after checking.

>>     #specifying the owners in a variable
>>     owner=(@{foo_users})  /some/file  rw,
> 
> What about allowing users that are members of a specific group, like 
> everybody in "users"?
> 
It a feature that has been considered but was left out, as I wanted to
focus on getting the user portion done.

there are two ways to go about it.
- doing a user side walk of the groups users so the expansion user side
- doing it in the kernel, but there might be some issues with this.

The syntax question becomes whether it is represented as
group=(blah) /some/file  rw,

or whether it stays with owner syntax
owner=(?group_name)  /some/file  rw,   # where ? represents some special
                                         character indicating a group

allowing for something like

group /some/file rw,

is a little trickier, it has to be done in the kernel and just what is
meant by group has to be carefully defined.  Basically is it only the
primary group or is it all groups the user belongs to.  My inclination
is to go with primary group only but that may be different that some
users would expect.


>>   One of the open questions is if the negative case is needed and if
>>   so, what syntax should be used.
>>
>>     owner!=(tom, dick)  /some/file  rw,  # allow access to /some/file
>> if # not owned by tom or dick
>>
>>     !owner /some/file rw,                # allow access to /some/file
>> if # not owned by the current # fsuid
> 
> This could be useful - for example, you could forbid wwwrun to read 
> files owned by wwwrun to prevent reading/executing code that has been 
> uploaded via webapps. (Well, file/directory permissions can be used to 
> prevent uploads at all, but having it as apparmor rules allows more 
> detailed access rules. And in several cases, uploads are needed in 
> general.)
> 
> The idea I have: Force all *.php files into a subprofile that forbids 
> reading of wwwrun-owned files (aka files uploaded using web apps), 
> while the main profile (for all static files) allows uploaded images 
> etc. to be delivered to web browsers.
> 
> Real life example: a customer had a forum which allowed upload of avatar 
> images - for example files like "myphoto.php"...
> 
hrmm not quite what I meant but I worded this very poorly.  I was
specifically asking about a rule adding permission for users that
weren't the current owner.

So in your example someone who wasn't wwwrun would be allowed rw access
to this.  I specifically dislike this idea because it is moving towards
a default allow syntax, ie. allowing to specify a black list instead of
white listing.

What you propose should in fact already be possible.

deny owner /some/file  r,

The deny rules are a form of black listing but they never add
permissions, they only are way of explicitly removing permissions.


deny rules will also work with the extended owner test, eg.
deny owner=(foo) /some/file r,

>>   One of the open questions is if a full profile reload is necessary
>> or whether a special table for user information should be loaded.  So
>> that updates to the user database rely only on loading the current
>> user database.
> 
> Depends on the time needed for a full reload IMHO ;-)
> 
Yes, this is a big issue, and while we have made progress with this and
there is still room for improvement, there will always be some policies
that are slow to compute and load.

Caching could possibly help but it is really going to come down to
implementation issues.  The first pass at this (DR1) will use policy
reload, and then we will see what happens from there.

>> 5.1 change of owner syntax?
>>   The current owner rule syntax is not as explicit as it could by
>> that the rule is conditional on ownership.  I am unsure if the
>> current syntax is sufficient or whether tweaking the syntax would be
>> helpful for the average user.
>>
>>    eg.
>>      owner /foo/bar rw,
>>
>>    could be rewritten as
>>      if owner /foo/bar rw,
>>
>>    It is a small change but does emphasize that the rule is
>> conditional on file ownership.
> 
> I think "owner" is sufficient.
> (And people who start reading or modyfying their profiles by hand should 
> have some basic knownledge about them - some of the letters used for 
> file permissions are less self-explaining than "owner" ;-)
> 
true enough, I think the current syntax is sufficient but I wanted to
hear what others thought of it.

>> 6. Attrs and xattr permissions
> 
>>   6.1 chown
>>   File chown could be limited by either a per profile mask of uid or
>>   it could be done per file.
>>
>>     chown (tom, jane),			# profile level mask
> 
> aka
>     /** chown(tom,jane),
> ;-) - no need to allow chown per profile *g*
> 
hehe, yes it is very easy to make a path rule that does the global case.
 The question really is do we want to allow specifying anything more,
which means another small step in complexity.   I think it is worth it
but, I tend to like expressiveness over simplicity, and simplicity is
something we really need to strive to maintain.

>>    vs. file level
>>      /some/file chown=(tom, jane),
>>    or
>>      chown=(tom, jane) /some/file,
> 
> Both variants look good.
> 
>>    or
>>      chown /some/file (tom, jane),
> 
> Not this syntax, please. The chown keyword and the list of usernames 
> should be kept together.
> 
yes that is my feeling as well, I think it becomes really important when
chown gets combined with owner conditions

>>   If done at a per file level, it will allowed to be conditional on
>> file ownership and allow for chowning to any user.
>>
>>     owner /some/file chown=(tom, jane),
>>     owner /some/file chown=(*), #allow chown to any user if file owner
> 
> Checking the current file owner is a very good idea - and IMHO more 
> imporant than checking/restricting the new owner. That's one of the 
> examples where the proposed new owner=... syntax is really useful :-)
> 
>>   7.1 Mount rules
> 
>>     mount permissions type device -> /path,
>>
>>   or more closely adhere to the mount command form of
>>
>>     mount permissions [-t type] [-o options] device -> /path,
>>
>>   The mount permissions will cover bind mounting, suid, etc.  And
>>   pattern matching will be allowed in each part of the rule (type,
>>   option, device, /path).
> 
> How would an example rule look like?
> 
> How are you planning to handle different mount options, for example "ro" 
> vs. "rw"? Will "rw" also allow to use "ro" instead?
> 
> To make things interesting: Which keywords/options would a * in the 
> option part allow? Would * include things like suid, dev and bind?
> 
I had envisioned something along the lines of

mount r /dev/hd0 -> /media/*,    #read only mount

where we can use the same syntax as file perms as much as possible.  So
basically permissions map to some very well defined options, and the
options portion is used for all the other options that a mount can have.

But perhaps it is best to just drop permissions and go with straight
mount syntax.

mount -o {ro,user} /dev/hd* -> /media/*,

mount -o * /dev/hd* -> /media/*,   # allow all mount options


>>   It is currently undecided on how best to make mount rules
>> conditional. On the euid, the fsuid and /path, device owner?
> 
> Device owner might be a good idea ("owner mount ..."). And of course the 
> path of the device and the mountpoint.
> 
Yes we could do it on device owner, or make the rule conditional on the
current euid, or even both.  The question being what is best, my current
thinking is that both is overly complex, and that if you want to select
mount rules based on euid then put those users in a different profile.


>> 9. Symlink permission
> ...
>>   My current inclination is to go with what I think is the least
>> complex solution which is mapping it to the r permission and having
>> it always enabled.
> 
> Please keep interesting ;-) disk layouts in mind when deciding this.
> For example, my /var is a symlink to /home/var (which is on my encrypted 
> home partition).
> 
> Currently I can "update" all profiles by adding a simple alias rule to 
> tunables/global:
>     alias /var -> /home/var,
> 
> I don't want to change each profile just because I moved /var around, so 
> I'd like to have this easy way also in future versions of apparmor.
> 
Yes this is a real problem, and I had actually planned to address it
with improving alias rules.  I just didn't get to finish writing that up
and I had put off this email way to long.

john


More information about the Apparmor-dev mailing list