Restricting app with custom SELinux policy
I'm wanting to lock down Virtualbox and since I can't find any pre-made policy I need to create one. Using the SELinux Policy Generation Tool in CentOS 6 I created a fairly generic policy following the "User Application" template.
The policy defined the VirtualBox_exec_t, VirtualBox_rw_t, and VirtualBox_t types then set labels on the program directories. I loaded the new module and set it as permissive, then ran the program to generate AVCs I could import into audit2allow. The problem is that simply starting the app and loading a VM and shutting it down straight away generated more than 600 AVC entries, the vast majority of which I don't understand. I could just dump the whole lot into audit2allow without checking, but that strikes me as poor security practice. If I want shoddy or no security I can just leave the app unconfined. Just a quick glance shows several AVCs about access to the /home folders, which I know is not needed. Virtualbox keeps VMs in the user home folder by default, but I've put mine in another location so there is nothing in home for it need. Who knows what other access rights I could end up giving away without realizing it? It may default to check for write access to files it only needs read access to, but which still generates write access AVC entries which I would somehow have to pick out from the rest. How in the world can I make sense of the deluge of AVC entries? All my searching on the net for instructions on creating policy has mostly turned up info 5 years old or older. I'm wondering if what I'm trying to accomplish is even feasible or will require either blanket allow permissions defeating the purpose or reverse engineering the entire application including every syscall and some kind of debugger. |
Quote:
|
1 Attachment(s)
Quote:
|
Sure it has to deal with 96 other contexts and 11 classes but taking into account what kind of application VirtualBox is, what tasks it has to perform to be able to run a guest OS, I think your policy file looks pretty much OK.
From the set of { add_name, associate, connectto, create, destroy, execmem, execmod, execute, execute_no_trans, getattr, ioctl, lock, open, read, remove_name, rename, rmdir, search, setcap, setpgid, setrlimit, setsched, signal, signull, unix_read, unix_write, unlink, write } access types the only ones I would investigate are those that force conditions beyond what's ordinarily necessary like exec{heap,mem,mod} (read http://people.redhat.com /~drepper/selinux-mem.html), some set.* like setcap, setsched and setrlimit, ioctl (syscalls not covered by other types of permission) and execute_no_trans (exec file in VirtualBox_rw_t or bin_t w/o transitioning from VirtualBox_t). |
Quote:
|
Quote:
Quote:
|
@unSpawn After several evenings working on this I feel I'm finally getting a handle on it. Most of the {exec*} denials were being caused by a few lingering mislabelings. Rather than using semanage to do this I've been adding the correct labels to the fc file as I intend to post the entire policy for others to use.
I did find one TEXTREL problem, I believe, as the site you linked to mentioned. This was generating execmem denials. I'll be reporting it to the Virtualbox developers as a bug. Hopefully something will be done about it. Until then I suppose I could set the execmen boolean or set that policy to "no audit". There are a few other avc denials I'm concerned with though. Can you offer any insight on these? Feb 16 21:28:06 (null) (null): audit(1329449286.802:1312): avc: denied { execute_no_trans } for pid=9276 comm=virtualbox path="/sbin/lsmod" ino=29622352 dev=dm-1 scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file There are 2 exec_no_trans denials, one for lsmod and one for grep. I'm not sure what to do with these. I think one option would be to write a transition rule to bin_t, but it seems that would basically allow Virtualbox to execute anything in /bin which seems overly broad. There are 2 denials related to the unconfined domain, which seems particularly sensitive to me as I thought the whole point of SE Linux is to separate confined applications from unconfined ones. Feb 16 21:28:06 (null) (null): audit(1329449286.835:1394): avc: denied { open } for pid=9279 comm=ps name=stat ino=22259 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_dbusd_t:s0 tclass=file Feb 16 10:45:24 (null) (null): audit(1329410724.427:303): avc: denied { connectto } for pid=2876 comm=VirtualBox path=002F746D702F2E4943452D756E69782F32363138 scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0 tclass=unix_stream_socket One thing I've noticed is a majority of the denials show "comm=ps" and "name=stat". These show up under a variety of contexts: syslogd_t, kernel_t, rpcbind_t, etc. I'm guessing Virtualbox is executing ps and piping the output through stat for some reason. Seems harmless enough, but I'm wondering if there is a simple way to allow this without having to create an allow rule for each different context it shows up under. Fix the root of the problem as it were. It looks like most of the {set*} permissions you suggested I look into relate to VirtualBox_t self:process. I'm not really clear on what that is about, but it seems fairly harmless to allow it modify itself. Is there something about this I should be paying attention to? |
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
Quote:
Quote:
Quote:
Since you agree creating a transition rule to bin_t is not advisable, what is the next best option? Create new contexts for grep and lsmod and then add transition rules for grep_t and lsmod_t? Quote:
Quote:
Here are some additional ps related virtualbox AVCs if that helps you figure anything out. Feb 16 10:45:22 (null) (null): audit(1329410722.678:201): avc: denied { open } for pid=2882 comm=ps name=stat ino=13440 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:system_r:irqbalance_t:s0 tclass=file Feb 16 10:45:22 (null) (null): audit(1329410722.680:217): avc: denied { read } for pid=2882 comm=ps name=stat ino=15429 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:system_r:cupsd_t:s0-s0:c0.c1023 tclass=file Feb 16 10:45:22 (null) (null): audit(1329410722.681:233): avc: denied { search } for pid=2882 comm=ps name=2112 ino=15666 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:system_r:abrt_dump_oops_t:s0 tclass=dir It looks like somewhere between 70-80% of the AVCs are related to ps with name=stat or name={pid}. I can't seem to figure out why either ps or stat would be running in another context though, much less in several. Quote:
|
I've moved into the stage of setting the proto policy enforcing to watch how it breaks and add in rules one at a time until it works. Pretty early on I hit some snags where it would not even load the GUI without some rules I'm not comfortable with.
Without "allow VirtualBox_t bin_t:file { read execute open getattr execute_no_trans };" and "allow VirtualBox_t bin_t:lnk_file read;" I get these errors: /usr/bin/virtualbox: line 23: /sbin/lsmod: Permission denied /usr/bin/virtualbox: line 23: /bin/grep: Permission denied /usr/bin/virtualbox: line 24: /bin/uname: Permission denied /usr/bin/virtualbox: line 24: /bin/cat: Permission denied /usr/bin/virtualbox: line 53: /bin/grep: Permission denied /usr/bin/virtualbox: line 53: /usr/bin/awk: Permission denied /usr/bin/virtualbox: line 53: /usr/bin/whoami: Permission denied /usr/bin/virtualbox: line 53: /bin/ps: Permission denied /usr/bin/virtualbox: line 74: /bin/basename: Permission denied Unknown application - How can I deal with this without allowing virutalbox unrestricted access to /bin? I could change the labelling of only those files and grant access to them, but it seems that would probably screw up some other programs that expect those binaries to have the bin_t label. Also I'm having trouble writing a transition rule. The /usr/bin/virtualbox file is actually just a link to /usr/bin/VBox. Both have the type VirtualBox_exec_t but for some reason I'm getting avc denials about execute_no_trans from source VirtualBox_t to target VirtualBox_exec_t. I created the following transition rule: type_transition VirtualBox_t VirtualBox_exec_t:process VirtualBox_exec_t; But without an allow execute_no_trans rule I get this error: /usr/bin/virtualbox: line 77: /usr/lib/virtualbox/VirtualBox: Permission denied /usr/bin/virtualbox: line 77: /usr/lib/virtualbox/VirtualBox: Permission denied for which I show the following permissions: -r-s--x--x. root root system_u:object_r:VirtualBox_exec_t:s0 /usr/lib/virtualbox/VirtualBox I find the fact that all of these binaries are labelled VirtualBox_exec_t to be quite confusing. |
Quote:
Quote:
BTW, was this fixed: Quote:
|
Quote:
Quote:
Mar 12 11:57:19 (null) (null): audit(1331571439.627:2035): avc: denied { execute_no_trans } for pid=3578 comm=virtualbox path="/usr/lib/virtualbox/VirtualBox" ino=3278667 dev=dm-1 scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:object_r:VirtualBox_exec_t:s0 tclass=file I'm stumped on that one. Quote:
Feb 16 10:45:22 (null) (null): audit(1329410722.678:201): avc: denied { open } for pid=2882 comm=ps name=stat ino=13440 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:system_r:irqbalance_t:s0 tclass=file Feb 16 10:45:22 (null) (null): audit(1329410722.680:217): avc: denied { read } for pid=2882 comm=ps name=stat ino=15429 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:system_r:cupsd_t:s0-s0:c0.c1023 tclass=file Feb 16 10:45:22 (null) (null): audit(1329410722.681:233): avc: denied { search } for pid=2882 comm=ps name=2112 ino=15666 dev=proc scontext=unconfined_u:unconfined_r:VirtualBox_t:s0 tcontext=system_u:system_r:abrt_dump_oops_t:s0 tclass=dir I posted a question about this to the virtualbox support forums last week, just asking what virtualbox is trying to do and why, but haven't gotten a response. The funny thing is, so far anyway, denying those permissions hasn't stopped virtualbox from running. I've managed to cobble together a list of the minimum permissions needed to get the basic GUI up, without attempting to load any VMs. A lot fewer permissions were required than I thought. Next step is to load VMs and exercise different aspects of functionality. |
Well, I have cobbled together an ugly but functional policy at this point. The weird "ps" permissions were not required, so there's no point in losing sleep over that until the Oracle people can explain why that is important. I still need help with the transition rule from VirtualBox_t to VirtualBox_exec_t. Or is it ok to keep using the execute_no_trans as I have? Seems like things should run in the exec domain, but I'm not sure. Maybe it doesn't make any difference.
I've been trying to fine tune things, lock it down just little. I noticed there are a few virtualbox related files I've not accounted for showing up under /dev/vboxdrv /dev/vboxusb /dev/vboxnetctrl These have something to do with how virtualbox creates emulated hardware and maps it to real hardware. By default vboxdrv and vboxnetctrl get assigned to xserver_misc_device_t and vboxusb gets a mix of device_t and xserver_misc_device_t. ls -alZ /dev/vboxusb/001 drwxr-x---. root vboxusers system_u:object_r:device_t:s0 . drwxr-x---. root vboxusers system_u:object_r:device_t:s0 .. crw-rw----. root vboxusers system_u:object_r:xserver_misc_device_t:s0 005 Since device_t is the default context for /dev lots of stuff has that which virtualbox probably doesn't need access to. I tried to create a new context called VirtualBox_device_t, but I really don't know what to do with that and the shell script refused to compile the policy module. Here's what I put in the te file: type VirtualBox_device_t files_type(VirtualBox_device_t) allow VirtualBox_t VirtualBox_device_t:chr_file { read write open getattr }; manage_dirs_pattern(VirtualBox_t, VirtualBox_device_t, VirtualBox_device_t) manage_files_pattern(VirtualBox_t, VirtualBox_device_t, VirtualBox_device_t) and the fe file: /dev/vboxusb(/.*)? gen_context(system_u:object_r:VirtualBox_device_t,s0) When that didn't work, I assigned VirtualBox_rw_t to /dev/vboxusb and did a quick restorecon but that broke the USB functionality and yet generated no avc denials. When I changed the context back to its default everything worked fine again. |
2 Attachment(s)
Well, my policy is as fine tuned as I can get it. I don't get any errors and can do everything I need it to do. People who want it to do different things may need to change settings, but I tried to comment it thoroughly. I did submit it to RedHat for comments/advice, but in 6+ months have heard no specific feedback other than its good but needs work. Thanks guys. Maybe someone else will find some value in this, so I'm releasing it here. Comments and improvements welcome.
Note: sometimes the /dev/vboxusb directory loses its defined context and requires a restorecon reset. |
Quote:
Quote:
|
Quote:
Hopefully somebody out there finds this usefull. The redhat guy said they need a vbox policy and suggested they might use this as a starting point, so this or something similar may one day end up in the offical repository. Comments and improvements are welcome. |
All times are GMT -5. The time now is 04:20 PM. |