7

My current understanding is that you have to manually use restorecon to apply the desired context to a newly created file or directory unless you are happy with the context that it inherits from its parent directory.

I am wondering if it is possible to automatically apply a context on creation based on its path without having to run restorecon.

I googled a bit and found this post by Dan Walsh where he mentions restorecond which uses inotify to change context on creation. He also points out the obvious problem with it (race condition). Is this the only way to automatically solve the issue of re-context-ing in case a child should not inherit its context from the parent directory?

One problem is that restorecond does not seem to handle entries the same way as /etc/selinux/targeted/contexts/files/file_contexts, that is, no regexes and it does not work recursively, so /etc/selinux/restorecond.conf cannot contain something like

/var/www(/.*)?/logs(/.*)?

or

/var/www/*

or even

/var/www/*/logs

Is there a way to work around this problem?

EDIT:

As per @Michael's answer this should work OOTB if a respective rule exists, but it doesn't:

# rm -rf /var/www/foo
# semanage fcontext -a -t httpd_log_t '/var/www/foo/logs'
# grep '/var/www.*logs' /etc/selinux/targeted/contexts/files/file_contexts*
/etc/selinux/targeted/contexts/files/file_contexts:/var/www(/.*)?/logs(/.*)?    system_u:object_r:httpd_log_t:s0
/etc/selinux/targeted/contexts/files/file_contexts.local:/var/www/foo/logs    system_u:object_r:httpd_log_t:s0
# matchpathcon /var/www/foo/logs
/var/www/foo/logs       system_u:object_r:httpd_log_t:s0
# mkdir -p /var/www/foo/logs
# touch /var/www/foo/logs/quux
# ls -alZ /var/www/foo/logs*
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 ..
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 quux
# restorecon -vR /var/www/foo
restorecon reset /var/www/foo/logs context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0
restorecon reset /var/www/foo/logs/quux context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0
  • Your regex looks fine. I think you may have found a bug. – Michael Hampton Aug 16 '13 at 10:52
  • @MichaelHampton This is a CentOS6 box. The regex in `file_contexts` ships with the installation. Since that did not work I added the second with `semanage fcontext` with a plain absolute path and no further regex magic, so I agree, that should work. I tried on both a CentOS 6.0 as well as a CentOS 6.3 server and it works on neither. Hm. – Adrian Frühwirth Aug 16 '13 at 10:58
  • Hey, you're right, that did come with the system. I think it's time to yell at Dan Walsh :) – Michael Hampton Aug 16 '13 at 11:00

3 Answers3

9

The kernel makes the following procedure to determine what the file type of a newly created file will be.

  • There exists in policy a specific file transition rule. So apply this.
  • Make the newly created file acquire the type of the parent directory.

In the vast majority of cases, new files inherit the parent directories type. Sometimes this is not desirable -- so a policy writer can create rules based off the conditions of who is doing the labelling and where in order to transition to another type.

This is controlled in policy with the type_transition statement, although normally a policy writer will call the filetrans_pattern macro instead.

In the kernel, these decisions are not based on paths but types (although a minor exception exists in newer policies).

A rule typically looks like this;

type_transition httpd_t var_log_t:file httpd_var_log_t;

In this example, the rule states that. If the process/user performing the file creation is httpd_t and the directory the object is being created in is var_log_t and the object is classified as a file, then the new file must be labelled as httpd_var_log_t.

This, of course has a number of limitations, a good example of this is the condition when you create .htaccess files in apache (in /var/www/html). In this example the default policy of creating a file type with the same type as its parent directory applies, but in reality the proper type of this file is httpd_sys_htacess_t not the default of httpd_sys_content_t.

This was a known problem for a number of years and was eventually fixed by allowing policy writers to specify the filename that the transition applies to in policy -- unfortunately this features is not available in EL6.

In your specific case -- as you have mentioned there are some workarounds involving restorecond. Other than this you should ideally split your data up with different types by putting them in separate subdirectories where the subdirectory is an adequately labelled type. If this is still not possible, and restorecond is not possible -- the only solution is a post-fix of running restorecon on the file after its creation.

Even the 'newer' named filetrans has problems because ultimately it does not support globbing or regex, which severely limits its functionality to specifically well-named files (like .htaccess).

As it stands at this moment, there exists no in-kernel mechanism as flexible as restorecon and its regexes to properly label files correctly to that degree.

Matthew Ife
  • 22,927
  • 2
  • 54
  • 71
3

The problem of correct labeling at file creation was addressed in Fedora 16 with a feature called file name transition (although you can find it also as "named file transitions"), whose definition basically states that:

With File Name Transitions Features, policy writers can write rules that take into account the file name, not the file path. This is the basename of the file path. Since the kernel knows at the time of object creation the label of the containing directory, the label of the process creating the object and the objects Name. we can now write a policy rule that states, if an unconfined_t process creates a file named resolv.conf in a directory labelled etc_t, the file should get labelled resolv.conf.

It is known that the way an object gets labeled at creation time can vary depending on the process creating the object (cp vs. mv is a good example). Also, the default way to label an object would be by inheritance: the object gets the label of the parent directory.

While this is convenient, it is not always correct, and the system administrator must correct the situation manually using (a combination of) restorecon + restorecond + semanage fcontext -a -t.

This is the problem Name File Transitions try to correct, by letting

[...] policy writers have the ability to overwrite this by writing a rule in policy that states, if a process with type a_t creates a object of class "file" in a directory labelled b_t, the object will get created c_t.

Obviously, named file transitions don't exist for custom locations. You could find already existing ones with, for example:

# sesearch -ASCT -s unconfined_t | grep Found
...
Found XX named file transition filename_trans:
...

So, in order to address your problem, you need to know beforehand which user (SELinux user) will create what file/directory and where, and then write a custom policy including a file transition. There are a couple of examples in the Fedora Project wiki page I linked above.

dawud
  • 14,918
  • 3
  • 41
  • 61
2

This is not a problem, you're just approaching it from the wrong direction.

If you want your own file contexts, just create your own using semanage fcontext. This does accept regular expressions.

Here is a common example, used to relocate the directory from which Apache serves files:

semanage fcontext -a -t httpd_sys_content_t "/volume1/web(/.*)?"

Feel free to adapt this to your own needs.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • You misunderstood my question. `semanage fcontext` just creates the respective entry in `/etc/selinux/targeted/contexts/files/file_contexts.local` which `restorecon` honors and sets the context according to the regex when you run it. Of course, this is what I do anyway. What I want is the context to be set automatically without having to run `restorecon`, and just having a rule in place created by `semanage fcontext` does not achieve that. – Adrian Frühwirth Aug 16 '13 at 09:57
  • This _is_ how you have the contexts set automatically. If it didn't work for you for some reason, you should ask a question about that. – Michael Hampton Aug 16 '13 at 09:58
  • No, you still need to run `restorecon` on the target file(s)/directory to relabel them. – Adrian Frühwirth Aug 16 '13 at 09:58
  • Of course. This sets the default file context, and will apply to newly created files. If you want to apply it to existing files, you have to run `restorecon`. – Michael Hampton Aug 16 '13 at 09:59
  • 1
    Exactly. I know all that and that was not the question (hence the `restoreconD` reference). What I want is automatic labelling on *creation* if the target file should get a different context than the parent directory *without* the need to run `restorecon` manually. – Adrian Frühwirth Aug 16 '13 at 10:01
  • And that is the question I answered. – Michael Hampton Aug 16 '13 at 10:03
  • OK, I had thought it would do that but it didn't. I will update my question and get back to you...thanks. But if that is how it is supposed to be in the first place, then what's the purpose of `restorecond`? – Adrian Frühwirth Aug 16 '13 at 10:27
  • I edited the question, apparently I must be doing something wrong - please enlighten me. – Adrian Frühwirth Aug 16 '13 at 10:50