[apparmor] mount rules

John Johansen john.johansen at canonical.com
Sun Dec 18 09:36:47 UTC 2011


On 12/17/2011 09:23 PM, Seth Arnold wrote:
> On Tue, Dec 13, 2011 at 10:23 AM, John Johansen
> <john.johansen at canonical.com> wrote:
>> So the question is basically what should mount rules look like.  The mount
>> command is a mess and has tons of options, do we want to mimic it as its
>> what people will be used to or try for something cleaner.
>>
>> Basically what I have so far is
>>
>>  [audit] [deny] mount [options=<options>] [type=<type>] [(<device>|<src>) ->] [<dest>],
> 
> I have to admit that I haven't thought specifically what the _syntax_
> should look like -- I've just wanted the feature. Pity, since this is
> obviously far more difficult than I ever gave it credit.
> 
yes its nasty

> One _gigantic_ problem -- well, as far as I'd like to see mount rules used
> -- is that the administrator can't use the udevd-provided symbolic links
> in /dev/disk/by-{id,path,uuid}. I _really_ want whatever solution we come
> up with to support using these symbolic links in some fashion. I know that
> sounds heretical, but consider these use cases:
> 
sigh, I always hated those symlinks.  Not that I don't like persistent names
but ...

> - I want to confine some stupid automounter program to read-write mounts
>   for my camera's sd card. (/dev/disk/by-id/....) I don't want that stupid
>   automounter to _ever_ be able to mount anything else, ever.
> 
sure, you can do that without using the symlink.  You want a short cut to
say use the path in the symlink.  Is taking a snapshot of that value at
load time enough, or would you want it to be dynamic to the changing value
of the symlink?

> - I want to use pam_apparmor to confine all my users in the group "pvtfc"
>   to _read only_ USB mounts but allow users in the group "officers"
>   read-write USB mounts. Forbid all other SCSI mounts, forbid all
>   NFS/CIFS/bind mounts. (/dev/disk/by-path/....)
> 
you want extended conditional support, but that isn't going to happen
in the first pass

> - I want to confine Calibre to read-write mounts for my Sony Reader.
>   (/dev/disk/by-id/... or /dev/disk/by-uuid/....)
> 
I'm not sure I follow you?  I think you are saying you want Calibre to
only have rw access on one specific mount specified by something in
/dev/disk/by-uuid/, ie. basically the ereader?

> - I want my data center operations staff to have privileges to rotate
>   through a series of specific backup disks. (/dev/disk/by-uuid/...)
>
err okay, but I am not sure what this will by you.  A malicious operator
can change the uuid of a disk

> We don't _have_ to use the symbolic links, but they are _extremely_
> convenient (and when I found these, I lost a lot of my hatred for udevd)
> and very well known.
> 
yes, they are convenient, again the question is at what level.  Policy
compilation, load time, dynamic?

Policy compilation could be just done with a special variable assignment

Load time with kernel vars, with the value set at load

Dynamic kernel vars + daemon triggering on fanotify, or a few other more
frightening implementations I can think of

> Could this problem be solved easier if we provide an inotify-based or
> udevd-event based daemon that labels device nodes as they are added, and
> then perform the mount permissions checks based on device labels?
> 
Explicit Labeling is one potential way to go, but we are not ready to
support it yet.

> We could probably also solve this problem using kernel-side variables to
> represent different device "names" as they come and go, but the labels
> feel like they might be easier to use.
> 
Yes and no.

>>
>> eg.
>>
>>  mount,   #Grant full mount access
>>
>>  mount type=ext3,   # allow mounting ext3 filesystems anywhere
>>
>>  mount type={ext*,vfat} /dev/sda2 -> /media/**,  # allow mounting /dev/sda2 if its any ext3 or vfat anywhere in /media/
>>
>>  mount /media/**,  # allow mounting anything, anywhere in /media/
>>
>>  mount options={atime,auto} /media/**,
>>
>>  mount /foo/ -> /bar/,
>>
>>
>>
>> eg. Allow mounting anything unless it is procfs, sysfs,
>>
>>  mount,
>>  deny mount type=procfs,
>>  deny mount type=sysfs,
>>
>> or the two deny rules could be combined into a single rule
>>  deny mount type={procfs,sysfs},
> 
> There's a _lot_ of kernel-provided filesystems: sysfs, proc, cgroup,
> cpuset, devtmpfs, debugfs, securityfs, devpts, binfmt_misc, that would
> probably be wise to forbid to "most programs". Denying specific mount
> types makes some sense, but .. I fear it'd be "most of them" in practice.
> 
sure, I am not saying you would want to do the above just trying to
provide examples.

> It'd be easier to handle this case if we _also_ provided some abstraction
> for 'dev' vs 'nodev' filesystems:
> 
> deny mount type=nodev
> 
yes though perhaps not at type= as we may want to use type= and nodev at the
same time.

> Allow mounting any filesystem backed by a block device. Probably same as:
> 
> mount type=dev
> 
> (presuming the kernel doesn't re-invent the 'dev' filesystem. teehee.
> devtmpfs is probably as close as it's going to get.)
> 
> If this just sounds like rambling, cat /proc/filesystems to see what I'm
> rambling about. :)
> 
I'd rather not, its a painful reminder of how many special filesystems there
are

>> Assuming this syntax is acceptable there are still a lot of open questions
>> - do we want to cover remounts and moves with these rules, or do we want
>>  a separate flag, or rule to indicate what a move can do
> 
> options=remount is _probably_ sufficient for this, though I could probably
> be talked into seeing the viewpoint that if there were explicit mount
> rules granting options, then it wouldn't make sense to restrict those
> options from remount requests.
> 
yep, I can't decide between the two

>> - how do we want to cover umount, anything you can mount you can unmount or
>>  do we want a separate flag or permission.
> 
> Definitely separate flag or permission.
> 
Or different rule?
  unmount /blah,

> Maybe even something super-clever to provide the equivalent of the 'user'
> option in /etc/fstab to allow a process to umount _only the specific
> mounts that it mounted_. As it stands, a camera-helper-tool with some
> mount rules to allow it to mount USB-attached SD cards would have a rule
> like this:
> 
> mount type=fat /dev/sd* -> /media/**
> 
> and we wouldn't want the camera helper to _also_ be able to unmount the
> Sony Reader mounted with identical rules from the Calibre profile. (Of
> course, if we add some udev-name-aware labeling rules, this might be less
> of an issue.)
> 
> umount mounted_by=pid:$$
> umount mounted_by=profile:$$   # or some other way to refer to "this profile"?
> umount mounted_by=profile:namespace:/path/to/profile ?
> umount mounted_by=user:usernames ?
> 
  Hrmm maybe more like

  unmount label=profile,            # yes I said labeling is a ways a way but
                                    # but implicit labeling will be closer
  unmount owner /foo/bar,


> 
> 
>> - what of options like exec/noexec, ro/rw.  Do we want to stick with mount
>>  style syntax or an apparmor flags syntax.
>>  Eg.
>>    ro would map to apparmor r,
>>    exec would be apparmor x,   noexec would be the rule not having the x
>>    ...
> 
> I vote for the 'mount' rules -- admins probably type them all the time.
>
and yet they are so ugly :)

>> - how do we want to express other mount flags.
>>  Eg.
>>    --bind, --rbind, --make-shared, ...
>>
>>  Do we specify them in the same way mount does
>>     mount --bind /foo/ -> /bar/,
>>
>>  Do we reuse, the type field when an fstype can't be specified.
>>     mount type=bind  /foo/ -> /bar/,
>>
>>  Do we use an apparmor style permission flag
>>     mount /foo/ -> /bar/  (r,x,bind),
> 
> I vote for the same syntax as the mount command, if only because these are
> difficult enough to understand the first four or five times you use them,
> we certainly don't need any additional complications in translating the
> mount commands to profile syntax.
> 
Sadly I am leaning this way as well, as much as I don't like it.

> How do we handle the unshare(2) system call? I can't find _any_ mediation
> points in my kernel source for 'unshare' (not even for capable
> CAP_SYS_ADMIN) -- only in do_fork() could I find any security checks.
> 
basically we don't atm, at least not anymore than we can do with fork



More information about the AppArmor mailing list