Re: Support macro documantation [was: Sample Passenger/Rails policy for review]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 08/18/2010 01:51 PM, Moray Henderson wrote:
> Jason Axelson wrote:
>> On Tue, Aug 17, 2010 at 5:34 AM, Moray Henderson
>> <Moray.Henderson@xxxxxxxxxxxxxxxx> wrote:
>>> Are any of the macros in /usr/share/selinux/devel/include/support/
>>> documented anywhere?  I couldn't find them in the Tresys Refpolicy
> API
>>> documentation or the selinuxproject.org wiki.
>>
>> Have you tried doing a "make html" in the refpolicy source? That will
>> generate a nice html interface to the macros, although there are many
>> so it can still be hard to tell which one would be best to use. Not
>> sure if you'll have it with your distribution but if you download from
>> tresys directly [1] you will be fine.
>>
>> 1. http://oss.tresys.com/projects/refpolicy
>>
>> Jason
> 
> In the CentOS 5 policy source (selinux-policy-2.4.6-279.el5.src.rpm)
> "make html" produces html for the files in admin, apps, kernel, services
> and system directories of policy/modules/ which have embedded xml usage
> notes.  
> 
> The basic support macros, however, are defined in policy/support/*.spt,
> which do not even contain the xml comments necessary to produce the
> html.
> 
> Then too I'm looking for documentation that actually explains what these
> commands are for and how to put them together into something useful:
> when should you use domain_auto_transition_pattern and when
> domain_transition_pattern?  Why is there a macro called "domain_trans"
> when it doesn't do a domain transition?  The often-cryptic one-liners in
> the html reference seem to assume that level of knowledge.
> 

macros, interfaces, templates, permission sets, you name it, are ways to
group policy. They are used to make policy simpler to read and easier to
maintain. They provide a "single point of failure".

When to use what, depends on which macros, interfaces, template,
permission set, you name it, matches your requirements best.

Its a matter of referencing your requirements to the available macros,
interfaces, you name it.

I agree that by just looking at the macros, interfaces, you name it, it
may not be directly clear what its purpose is. You will see that when
such an macro, interface, you name it, best suites your requirement.

The tresys wiki has some information on the basics:

http://oss.tresys.com/projects/refpolicy/wiki/

But anyone can design any macro, interface, you name it that best fits
your particular need and so it does not make as much sense to document a
particular interface, macro, you name it, as it does to document the
parts it includes.

The reason for the various interfaces, macros, you name it, is to
provide flexibility. One interface can call another (can compliment
another). So that they can be both used together and separately.

I learned this by looking at the refpolicy tree. referencing things.
In what type of policy is a particular macro, interface, you name it
often used?

for example:

if you looks at policy for user applications, you will often see the
application_domain. So you can conclude that this is used for user
application policy. Then by looking at the application_domain definition
you can see what it includes.

When you write a user application policy, without using any macro,
interface, you name it (for example by using audit2allow), and then
finding the interfaces, macros, you name it, that best provide the
access you need. You will find out the purpose of the interfaces.

The more you practice the more you will see why a particular interface
is there.

After a while of practice you will know what to use when without even
referencing. (this can be dangerous though, routine is one of the
biggest enemy of policy writers in my view)

But the point is:
1. theyre just grouping policy for one reason or another, or several
reasons. In some cases there is a description of what it actually does.
But it does not describe every use case because there may be more and it
may be variable.
2. Look at the content rather then the description. Does the content
meet your requirements closest? Then it is probably what you need,
despite its description.
3. Learn but do not blindly trust by looking to the policy as a whole.
What kind of domains are there in a system and are there defined in
policy. Which macros, interfaces, you name it, are used most in any of
these kinds of domains.
4. Practice makes perfect.

I can imagine that some things in refpolicy are hard to understand, and
i cannot explain every macro, interface, you name it, and its use case
either. It does not really matter. Its probably there for a reason and
until i need it i will just trust on that.

If i need it depends on whether its contents matches my requirements
closest.

And if nothing matches my requirements, then i will create a macro,
interface, you name it, myself, you meet my requirements.

When i do so, i keep in mind the reasons for using these in the first place:

Group policy that facilitates a certain common access to achieve
simplicity, maintainability, a single point of failure.

Let me give you one example:

I am writing policy for some process. process1_t.
Now some other processes policy (domain) wants to read my process state
(my process in /proc)

So i will write in interface that other policies can call that provides
the caller access to read my process state.

The interface will in turn use a pattern: ps_process_pattern which
facilitate access that the state of the specified process.

The ps_process_pattern itself uses permission sets to use permission
that are grouped to the functionality, like list dirs, read files etc.

It provides a single point of failure. A central place to modify policy
that will propagate.

so:

########################################
## <summary>
##	Read state of process1.
## </summary>
## <param name="domain">
##	<summary>
##	Domain allowed access.
##	</summary>
## </param>
#
interface(`process1_read_state',`
	gen_require(`
		type process1_t;
	')

	ps_process_pattern($1, process1_t)
')

This is the interface that facilitates the access to read process1
state. The description (summary) is short and to the point.
Its not going to explain why one would need to read a process state it
just says what is provides.

It expects a parameter "domain". domains AKA domain types are types for
processes.

if process2_t wants to read state of process1_t, then process2 local
policy (process2.te) would call:

process1_read_state(process2_t)

The $1 is replaced by the only parameter it expects: domain type process2_t.


so you get:
ps_process_pattern(process2_t, process1_t)

Now lets look at the contents of ps_process_pattern:

define(`ps_process_pattern',`
	allow $1 $2:dir list_dir_perms;
	allow $1 $2:file read_file_perms;
	allow $1 $2:lnk_file read_lnk_file_perms;
	allow $1 $2:process getattr;
')

Translated it will be:

allow process2_t process1_t:dir list_dir_perms;
allow process2_t process1_t:file read_file_perms;
allow process2_t process1_t:lnk_file read_lnk_file_perms;
allow process2_t process1_t:process getattr;

Now we almost have "raw" policy. E.g. policy the kernel understands.
Except the permission sets used need to be translated:

list_dir_perms:

define(`list_dir_perms',`{ getattr search open read lock ioctl }')

read_file_perms:

define(`read_file_perms',`{ open read_inherited_file_perms }')

which in turn calls:

read_inherited_file_perms: ( this separation is done to differentiate
between reading files and reading inherited files, reading inherited
files do not require the open permission )

define(`read_inherited_file_perms',`{ getattr read ioctl lock }')

and read_lnk_file_perms:

define(`read_lnk_file_perms',`{ getattr read }')

so:

Translating the human usable interface call: process1_read_state(process2_t)

can be translated into kernel readable raw policy:

allow process2_t process1_t:dir { getattr search open read lock ioctl };
allow process2_t process1_t:file { getattr open read ioctl lock };
allow process2_t process1_t:lnk_file { getattr read };
allow process2_t process1_t:process getattr;

.. providing: simplicity, flexibility/maintainability and a single point
of failure.

This post is not to explain the details, it tries to explain how you can
figure out the details. Why things work the way they work.

Why its not always easy the explain a macros, interfaces purpose,
because there may be several purposes. or its purpose may just be part
or another interface, macro etc. It does really matter. What matters it
what access it facilitates and if that access meets your requirement
best, then chances are you should be using it.



> 
> Moray.
> "To err is human.  To purr, feline"
> 
> --
> selinux mailing list
> selinux@xxxxxxxxxxxxxxxxxxxxxxx
> https://admin.fedoraproject.org/mailman/listinfo/selinux


Attachment: signature.asc
Description: OpenPGP digital signature

--
selinux mailing list
selinux@xxxxxxxxxxxxxxxxxxxxxxx
https://admin.fedoraproject.org/mailman/listinfo/selinux

[Index of Archives]     [Fedora Users]     [Fedora Desktop]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux