# SELinux: allow a process to create any file in a certain directory

I have a script that, when invoked, will cause the contents of dmesg to be written to a file, with the file's name basically being a timestamp. SELinux prevents this. Following the advice of Fedora's SELinux troubleshooting app, I tried:

grep dmesg /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypol.pp


However, this doesn't seem to work, probably because the name of the file it's creating is different every time. So how do I tell SELinux to allow dmesg to create (and write to) any file in a certain directory? Or tell it that the script in question (and all the processes it spawns) can do that?

EDIT: I tried Akshay's answer, and in /usr/share/selinux/devel made a copy of example.te and added Akshay's code. Two problems:

1) At first, when I did make it told me:

unknown type admin_home_t


2) I added type admin_home_t;. This let make complete, but then when I tried semodule -i it gave me:

libsepol.scope_copy_callback: userdomain: Duplicate declaration in module: type/attribute admin_home_t (No such file or directory).


EDIT 2: I created an entirely new file label in the .te file:

type dmesg_old_t;
logging_log_file(dmesg_old_t)


This let semodule -r work. Then I used chcon to change the type of the directories to dmesg_old_t. However, it's still blocking. The raw ACV:

type=AVC msg=audit(1377981239.693:1279): avc:  denied  { write } for  pid=23919 comm="dmesg" path="/root/dmesg/warn/08:31:13:33.txt" dev="dm-1" ino=524290 scontext=system_u:system_r:dmesg_t:s0 tcontext=system_u:object_r:dmesg_old_t:s0 tclass=file


Also, here's the .te file I'm trying to use:

policy_module(script,1.0.0)

########################################
#
# Declarations
#

type script_t;
type script_exec_t;
domain_type(script_t)
domain_entry_file(script_t, script_exec_t)

type script_old_t;
logging_log_file(script_old_t)

########################################
#
# Myapp local policy
#

allow script_t file_type : filesystem getattr ;
allow script_t script_old_t : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow script_t script_old_t : lnk_file { read getattr } ;


EDIT 3: I fixed the problem by having the script save the result of dmesg into a variable, and then having the script write the variable into the text file; this way the dmesg process doesn't need to have write access to any files.

edit retag close merge delete

Why are you focused on dmesg writing files? I don't believe that dmesg has an option to write its output to a file. More likely, its your script writing to the file, perhaps by using shell output redirection, so it's the context in which the script is run, not dmesg itself, which determines how to define your rules.

( 2013-08-30 21:49:54 -0500 )edit

What is the purpose

( 2013-08-31 01:48:08 -0500 )edit

You still haven't posted the AVCs that are generated by running your script.

( 2013-08-31 07:48:47 -0500 )edit

( 2013-08-31 07:58:33 -0500 )edit

( 2013-08-31 08:00:40 -0500 )edit

Sort by » oldest newest most voted

To perform that you need to create your own policy

1. create a type for your script and with attribute exec_type (eg script_exec_t)

2. create type for the process that is created by the script with attribute domain(script_t)

3. perform a type transition that when we execute a script the process created should have the type script_t

4. Now we need script_t to allow into the directory where it generates a rand file

for this i will take help of sesearch bec when httpd starts it creates a file lock file

sesearch --allow -s httpd_t -t var_lock_t
Found 3 semantic av rules:
allow httpd_t file_type : filesystem getattr ;
allow httpd_t var_lock_t : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t var_lock_t : lnk_file { read getattr } ;


now replace httpd_t with your script_t and replace var_lock_t with type of dir whre your script is creating a rand file

Note: create your policy file in /usr/share/selinux/devel directory with .te extension then run make to create a binary and load it with semodule -i policy_name.pp

more

The name of the file is insignificant

You need to enclose the AVC denial(s) (Or if you do not know what a AVC denial is, and how to retrieve it enclose the whole setroubleshoot report)

These "reports" have all the information we need to suggest an informed solution, rather than speculating

more