public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Sven Vermeulen" <sven.vermeulen@siphos.be>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/hardened-docs:master commit in: html/
Date: Sat, 23 Apr 2011 11:35:17 +0000 (UTC)	[thread overview]
Message-ID: <bdb128145f81f05f094fb220d4df1a1768458779.SwifT@gentoo> (raw)

commit:     bdb128145f81f05f094fb220d4df1a1768458779
Author:     Sven Vermeulen <sven.vermeulen <AT> siphos <DOT> be>
AuthorDate: Sat Apr 23 11:32:27 2011 +0000
Commit:     Sven Vermeulen <sven.vermeulen <AT> siphos <DOT> be>
CommitDate: Sat Apr 23 11:32:27 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-docs.git;a=commit;h=bdb12814

update previews

---
 html/selinux-development.html |  654 ++++++++++++++++++++++++++++++++++++++---
 1 files changed, 618 insertions(+), 36 deletions(-)

diff --git a/html/selinux-development.html b/html/selinux-development.html
index 72f7a56..9767824 100644
--- a/html/selinux-development.html
+++ b/html/selinux-development.html
@@ -97,6 +97,12 @@ highlights...
     <span class="emphasis">interface file</span> which can then be called by other modules. This
     includes the necessary permissions to allow domain transitions
   </li>
+  <li>
+    SELinux uses attributes to make multiple domains manageable. Domains can
+    have certain permissions against all domains or types that are given a
+    particular attribute. Be aware of this when you start assigning attributes
+    to your own types or domains.
+  </li>
 </ul>
 <p class="chaphead"><a name="doc_chap2"></a><span class="chapnum">2.
             </span>Setting Up Your Environment</p>
@@ -209,14 +215,14 @@ one:
 <a name="doc_chap2_pre4"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
 <tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing2.4: Setting up a local workspace</p></td></tr>
 <tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
-~$ <span class="code-input">mkdir dev/local</span>
-~$ <span class="code-input">cp -r dev/hardened/strict dev/local/</span>
+~$ <span class="code-input">cd dev/hardened</span>
+~$ <span class="code-input">cp -r strict strict.local/</span>
 </pre></td></tr>
 </table>
 <p class="secthead"><a name="doc_chap2_sect4">Navigating the policy workspace</a></p>
 <p>
 The main location you will work with is
-<span class="path" dir="ltr">dev/local/strict/policy/modules</span>. This location is subdivided in
+<span class="path" dir="ltr">dev/hardened/strict.local/policy/modules</span>. This location is subdivided in
 categories:
 </p>
 <dl>
@@ -244,7 +250,7 @@ Inside the categories, the modules are available using their three files
 <a name="doc_chap2_pre5"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
 <tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing2.5: Listing the available sudo files</p></td></tr>
 <tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
-~$ <span class="code-input">cd dev/local/strict/policy/modules/admin</span>
+~$ <span class="code-input">cd dev/hardened/strict.local/policy/modules/admin</span>
 ~$ <span class="code-input">ls sudo.*</span>
 sudo.fc    sudo.if     sudo.te
 </pre></td></tr>
@@ -257,7 +263,7 @@ To build a module, go to the location where the module code is. Then, run
 <a name="doc_chap2_pre6"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
 <tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing2.6: Building the portage module</p></td></tr>
 <tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
-~$ <span class="code-input">cd dev/local/strict/policy/modules/admin</span>
+~$ <span class="code-input">cd dev/hardened/strict.local/policy/modules/admin</span>
 ~$ <span class="code-input">make -f ../../../support/Makefile.devel portage.pp</span>
 </pre></td></tr>
 </table>
@@ -272,7 +278,7 @@ If you want to build the base policy, run <span class="code" dir="ltr">make base
 <a name="doc_chap2_pre7"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
 <tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing2.7: Building the base policy</p></td></tr>
 <tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
-~$ <span class="code-input">cd dev/local/strict</span>
+~$ <span class="code-input">cd dev/hardened/strict.local</span>
 ~$ <span class="code-input">make base</span>
 </pre></td></tr>
 </table>
@@ -406,7 +412,9 @@ find the AVC denials you are looking for.
 <p>
 The next step is to see if we are dealing with the right security contexts. This
 does require a bit of insight in how both the application (that is failing) and
-the policy relate to each other.
+the policy relate to each other. In essence, you want to make sure that the
+process is running in the right domain and is trying to work on the right target
+type.
 </p>
 <p>
 Say you are having issues with SELinux (re)labeling and you notice the following
@@ -557,7 +565,7 @@ creating an additional domain or type can be beneficial.
 <p>
 A noticeable example is Portage' support for CVS/SVN/GIT ebuilds (the so-called
 live ebuilds). These ebuilds get their repository and store it in the
-<span class="path" dir="ltr">distfiles/svn+src</span> location, which was by default labelled
+<span class="path" dir="ltr">distfiles/svn+src</span> location, which was by default labeled
 <span class="path" dir="ltr">portage_ebuild_t</span> with only read-access for the
 <span class="path" dir="ltr">portage_sandbox_t</span> domain. However, with those live ebuilds, the
 <span class="path" dir="ltr">portage_sandbox_t</span> domain also needs write privileges to this
@@ -573,67 +581,641 @@ need to create the proper interface functions in the target domain and call
 these functions from the source domain.
 </p>
 <p>
-TODO extend this explanation, use a common example, like mysql_stream_connect in
-postfix.
+Interface functions are the APIs that a module provides towards other SELinux
+modules when they need to interact with the domains. For instance, the
+<span class="path" dir="ltr">mysql</span> module provides, amongst other functions, the
+<span class="code" dir="ltr">mysql_stream_connect</span> interface:
+</p>
+<a name="doc_chap3_pre12"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing3.12: mysql_stream_connect interface</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+########################################
+## &lt;summary&gt;
+##      Connect to MySQL using a unix domain stream socket.
+## &lt;/summary&gt;
+## &lt;param name="domain"&gt;
+##      &lt;summary&gt;
+##      Domain allowed access.
+##      &lt;/summary&gt;
+## &lt;/param&gt;
+## &lt;rolecap/&gt;
+#
+interface(`mysql_stream_connect',`
+        gen_require(`
+                type mysqld_t, mysqld_var_run_t, mysqld_db_t;
+        ')
+
+        stream_connect_pattern($1, mysqld_var_run_t, mysqld_var_run_t, mysqld_t)
+        stream_connect_pattern($1, mysqld_db_t, mysqld_var_run_t, mysqld_t)
+')
+</pre></td></tr>
+</table>
+<p>
+The interface declares that the domain passed on as its first (and only)
+argument gets the rights offered by <span class="code" dir="ltr">stream_connect_pattern</span>, which is a
+macro (defined in <span class="path" dir="ltr">policy/support/ipc_patterns.spt</span> that looks like
+so:
+</p>
+<a name="doc_chap3_pre13"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing3.13: stream_connect_pattern</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+define(`stream_connect_pattern',`
+        allow $1 $2:dir search_dir_perms;
+        allow $1 $3:sock_file write_sock_file_perms;
+        allow $1 $4:unix_stream_socket connectto;
+')
+</pre></td></tr>
+</table>
+<p>
+Modules that need to interact with MySQL through a Unix domain stream socket
+(<span class="path" dir="ltr">/var/run/mysqld/mysqld.sock</span>) will need the proper permissions to
+work with the target type (<span class="path" dir="ltr">mysqld_var_run_t</span>). Modules cannot just
+set <span class="emphasis">allow</span> statements towards <span class="path" dir="ltr">mysqld_var_run_t</span> as they do not
+know this type. Instead, they call the <span class="code" dir="ltr">mysql_stream_connect</span> interface,
+like the <span class="path" dir="ltr">postfix.te</span> file does:
 </p>
+<a name="doc_chap3_pre14"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing3.14: Postfix module calling mysql_stream_connect</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+optional_policy(`
+        mysql_stream_connect(postfix_master_t)
+        mysql_stream_connect(postfix_cleanup_t)
+        mysql_stream_connect(postfix_local_t)
+')
+</pre></td></tr>
+</table>
 <p>
-TODO explain that changes in the interface require rebuilds and reinstallations
-of the base (package, not only .pp file, due to includes). tell that this is the
-reason why selinux-base-policy has that many revisions.
+If the change you need is adding existing interface calls to the module (in 
+the <span class="path" dir="ltr">.te</span> file) then you should be able to test it easily by building
+the changed module and loading it. However, if you need to change the interface
+of your module itself (in the <span class="path" dir="ltr">.if</span> file) you will eventually need
+to rebuild the base policy and even provide and install a new
+<span class="path" dir="ltr">sec-policy/selinux-base-policy</span> package as the interfaces are placed
+in <span class="path" dir="ltr">/usr/share/selinux/strict/include</span>. This is one of the reasons
+why the <span class="path" dir="ltr">sec-policy/selinux-base-policy</span> package in Gentoo Hardened
+has a high revision number (and many updates).
 </p>
 <p class="chaphead"><a name="doc_chap4"></a><span class="chapnum">4.
             </span>No Domain Exists (Yet)</p>
 <p class="secthead"><a name="doc_chap4_sect1">Reuse existing domains</a></p>
 <p>
-TODO talk about potentially reusing domains (like apache module providing the
-various httpd_* domains which can be reused by lighttpd). Talk about assigning
-the proper labels to the files to see if that is sufficient.
+If you are facing problems because you run an application which has no domain
+itself (and hence is probably running in the <span class="path" dir="ltr">user_t</span>,
+<span class="path" dir="ltr">staff_t</span> or <span class="path" dir="ltr">sysadm_t</span> domains - or even tries to run in
+the <span class="path" dir="ltr">initrc_t</span> domain), you will need to create one. But before we do
+that, it might be possible that the application can work within the domain
+definition of a different application.
 </p>
-<p class="secthead"><a name="doc_chap4_sect2">Copy from existing domains</a></p>
 <p>
-TODO talk about finding a similar module (apps or service) and start from a
-(slimmed-down) domain. Not recommended as it might already open too much, but it
-is a good start, if not to just look at with every denial you get later. Keep it
-short, most information is in next section.
+One example here is lighttpd. This lightweight HTTPd service "uses" the
+definitions offered by the <span class="path" dir="ltr">apache</span> module. By marking its executable
+file <span class="path" dir="ltr">httpd_exec_t</span> it runs in the <span class="path" dir="ltr">httpd_t</span> domain and
+uses the same policy like Apache. By labeling the files according to the
+<span class="path" dir="ltr">apache.fc</span> definitions (but now for lighttpd) it might Just Work
+™
+</p>
+<p>
+Reusing existing domains requires that you at least consider the following
+aspects:
+</p>
+<ul>
+  <li>
+    Will the application run on the same system as the application for which the
+    domain is originally intended? If so, then both might run in the same domain
+    (and as such have more privileges towards each other than intended) which
+    might not be what you want.
+  </li>
+  <li>
+    Do you need to enhance (read: add additional privileges) the master domain?
+    If so, make sure that you don't add more privileges than the original domain
+    would ever need to the extend that these privileges become a security risk.
+  </li>
+</ul>
+<p class="secthead"><a name="doc_chap4_sect2">(Do Not) Copy from existing domains</a></p>
+<p>
+If reusing existing domains introduces too many risks, you'll need to create a
+new domain for the application. Many people would be inclined to copy the domain
+definition of a similar application and work from there. Although this is a
+viable approach, it is considered a bad practice because you start by providing
+privileges to the domain that are never needed, and removing privileges from a
+domain later is very difficult. Even more, if you are not the author of the
+modules, most developers will not even try to remove them as they assume that
+the author of the domain had a good reason to add it in the first place. This is
+one of the reasons why upstream takes great care in accepting patches - they
+must be properly documented before they are accepted.
+</p>
+<p>
+Instead, create a domain from scratch but take a close eye on the domain you
+belief is very similar. Issues that arise during the module development might be
+quickly resolved by looking at how the original domain is defined.
 </p>
 <p class="secthead"><a name="doc_chap4_sect3">Starting from scratch</a></p>
 <p>
-TODO talk about defining the proper domains, set proper types (like file_type or
-application_type), refer to refpolicy guidelines
+To start the development of a new module from scratch, first identify the
+domain(s) you want to have. An application that, in its entire lifespan only
+constitutes of a single process, will most likely only have one domain. For
+instance, the Skype client will have just <span class="path" dir="ltr">skype_t</span>. However,
+applications that have multiple processes running might need multiple domains
+too. For instance, the Postfix application runs a master
+(<span class="path" dir="ltr">postfix_master_t</span>), queue manager (<span class="path" dir="ltr">postfix_qmgr_t</span>) and
+pickup service (<span class="path" dir="ltr">postfix_pickup_t</span>), but depending on the commands
+you execute, it will also have (short-lived) processes running as
+<span class="path" dir="ltr">postfix_cleanup_t</span>, <span class="path" dir="ltr">postfix_bounce_t</span>, etc.) It is
+considered a best practice to start with a fine-grained model for domains
+and only later decide if merging multiple domains into one is beneficial.
+Splitting domains later is more difficult. Don't forget to look at the
+client-side aspect too!
+</p>
+<p>
+Next, define the types that each domain interacts with. This of course includes
+the binary (like <span class="path" dir="ltr">skype_exec_t</span>) but do not forget resources like
+</p>
+<ul>
+  <li>
+    The configuration file(s) in <span class="path" dir="ltr">/etc</span> (f.i.
+    <span class="path" dir="ltr">postfix_etc_t</span>)
+  </li>
+  <li>
+    PID files (f.i. <span class="path" dir="ltr">sshd_var_run_t</span>)
+  </li>
+  <li>
+    Spool files (f.i. <span class="path" dir="ltr">postfix_spool_t</span>)
+  </li>
+  <li>
+    Variable data files (f.i. <span class="path" dir="ltr">snmpd_var_lib_t</span>)
+  </li>
+  <li>
+    Log files (f.i. <span class="path" dir="ltr">zebra_log_t</span>)
+  </li>
+  <li>
+    Cache files (f.i. <span class="path" dir="ltr">squid_cache_t</span>)
+  </li>
+  <li>
+    (User) content files (f.i. <span class="path" dir="ltr">httpd_sys_content_t</span> and
+    <span class="path" dir="ltr">httpd_user_content_t</span>)
+  </li>
+</ul>
+<p>
+Also, try to separate types that are used by other domains as well. This way,
+the other domains can only interact with those files or resources that are
+labeled accordingly, rather than interact with a broad spectrum of files. The
+distinction that the <span class="path" dir="ltr">apache</span> module makes between system-provided
+content (like phpmyadmin files) and user-provided content (in the
+<span class="path" dir="ltr">public_html</span> directory in the users' home directories) seems (and
+is) very logical, but one could wrongly say that for Apache itself, the access
+controls are the same. Although that might be true, both types are clearly used
+in different ways so this mandates the use of different domains.
+</p>
+<p>
+Once you have defined those types too, start writing down the intra-domain
+permissions. Right now is a good time to look at other modules to see how they
+do things. Start with defining the accesses towards the domains.
+</p>
+<a name="doc_chap4_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing4.1: Snippet from the spamassassin module</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+type spamassassin_t;
+type spamassassin_exec_t;
+application_domain(spamassassin_t, spamassassin_exec_t)
+ubac_constrained(spamassassin_t)
+</pre></td></tr>
+</table>
+<p>
+This small snippet defines many things. The first two lines just mention the new
+types (the <span class="path" dir="ltr">spamassassin_t</span> domain and
+<span class="path" dir="ltr">spamassassin_exec_t</span> type). The <span class="code" dir="ltr">application_domain</span> interface
+marks <span class="path" dir="ltr">spamassassin_t</span> as an application domain type (it gets the
+<span class="path" dir="ltr">application_domain_type</span> and <span class="path" dir="ltr">domain</span> attributes and a
+few default permissions (like allowing that it sends SIGCHLD and SIGNULL to
+init). It also marks <span class="path" dir="ltr">spamassassin_exec_t</span> as an applications'
+executable type (<span class="path" dir="ltr">application_exec_type</span> and <span class="path" dir="ltr">exec_type</span>
+attributes) so that it can be executed by regular users (these domains have
+execute rights against all resources that have the
+<span class="path" dir="ltr">application_exec_type</span> attribute set. Finally, it marks the
+<span class="path" dir="ltr">spamassassin_t</span> domain as a constrained domain for user-based access
+controls. In other words, if SELinux users <span class="path" dir="ltr">user_u</span> and
+<span class="path" dir="ltr">staff_u</span> launch the application in <span class="path" dir="ltr">spamassassin_t</span>
+domains, then the domains are segregated from each other (the intra-domain rules
+inside <span class="path" dir="ltr">spamassassin_t</span> are only valid for communication within the
+same SELinux user, not between SELinux users).
+</p>
+<p>
+Attributes are an important aspect in SELinux policy development. They make
+managing the domains easier, but you should always consider the implications
+when you add an attribute to one of your types. It usually means that a whole
+lot of permissions are suddenly granted between other domains and yours.
+</p>
+<p>
+Next, set the proper intra-domain permissions. For instance, allow your domain
+to read its configuration files as well as more access inside its own
+<span class="path" dir="ltr">/var/lib</span> location:
+</p>
+<a name="doc_chap4_pre2"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing4.2: Snippet from openca module</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+allow openca_ca_t openca_etc_t:file read_file_perms;
+allow openca_ca_t openca_etc_t:dir list_dir_perms;
+
+manage_dirs_pattern(openca_ca_t, openca_var_lib_t, openca_var_lib_t)
+manage_files_pattern(openca_ca_t, openca_var_lib_t, openca_var_lib_t)
+</pre></td></tr>
+</table>
+<p>
+The majority of work in developing SELinux policy modules is using and choosing
+the right interfaces. Having a few functions available to browse through all the
+available information is always interesting, so you might want to use the
+following function definitions (definitely not mandatory - this is only to help
+people skim through the policy definitions):
+</p>
+<a name="doc_chap4_pre3"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing4.3: SELinux policy development function definitions</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+POLICY_LOCATION="http://www.gentoo.org/path/to/your/refpolicy";
+
+# sefindif - Find interface definitions that have a string that matches the
+# given regular expression
+sefindif() {
+  REGEXP="$1";
+  cd ${POLICY_LOCATION}/policy/modules;
+  for FILE in */*.if;
+  do
+    awk "http://www.gentoo.org/(interface\(|template\()/ { NAME=\$NF; P=0 }; /${REGEXP}/ { if (P==0) {P=1; print NAME}; print };" ${FILE} | sed -e "s:^:${FILE}\: :g";
+  done
+}
+
+# seshowif - Show the interface definition
+seshowif() {
+  INTERFACE="$1";
+  cd ${POLICY_LOCATION}/policy/modules;
+  for FILE in */*.if;
+  do
+    grep -A 9999 "\(interface(\`${INTERFACE}'\|template(\`${INTERFACE}'\)" ${FILE} | grep -B 9999 -m 1 "^')";
+  done
+}
+
+# sefinddef - Find macro definitions that have a string that matches the given
+# regular expression
+sefinddef() {
+  REGEXP="$1";
+  grep -H "define(\`.*${REGEXP}.*" ${POLICY_LOCATION}/policy/support/* | sed -e 's:.*\/\([^(]*\):\1:g'
+}
+
+# seshowdef - Show the macro definition
+seshowdef() {
+  MACRONAME="$1";
+  cd ${POLICY_LOCATION}/policy/support;
+  for FILE in *.spt;
+  do
+    grep -A 9999 "define(\`${MACRONAME}'" ${FILE} | grep -B 999 -m 1 "')";
+  done
+}
+</pre></td></tr>
+</table>
+<p>
+These functions can then be used to find the information / interfaces you are
+looking for. For instance, you need the application to read the postfix
+configuration files:
+</p>
+<a name="doc_chap4_pre4"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing4.4: Looking for the interface(s) needed</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+~$ <span class="code-input">sefindif postfix_etc_t</span>
+services/postfix.if: template(`postfix_domain_template',`
+services/postfix.if:    allow postfix_$1_t postfix_etc_t:dir list_dir_perms;
+services/postfix.if:    read_files_pattern(postfix_$1_t, postfix_etc_t, postfix_etc_t)
+services/postfix.if:    read_lnk_files_pattern(postfix_$1_t, postfix_etc_t, postfix_etc_t)
+<span class="code-comment">services/postfix.if: interface(`postfix_read_config',`
+services/postfix.if:            type postfix_etc_t;
+services/postfix.if:    read_files_pattern($1, postfix_etc_t, postfix_etc_t)
+services/postfix.if:    read_lnk_files_pattern($1, postfix_etc_t, postfix_etc_t)</span>
+services/postfix.if: interface(`postfix_config_filetrans',`
+services/postfix.if:            type postfix_etc_t;
+services/postfix.if:    filetrans_pattern($1, postfix_etc_t, $2, $3)
+
+~$ <span class="code-input">seshowif postfix_read_config</span>
+interface(`postfix_read_config',`
+        gen_require(`
+                type postfix_etc_t;
+        ')
+
+        read_files_pattern($1, postfix_etc_t, postfix_etc_t)
+        read_lnk_files_pattern($1, postfix_etc_t, postfix_etc_t)
+        files_search_etc($1)
+')
+</pre></td></tr>
+</table>
+<p>
+Same thing if you want to look for the correct macro definition (usually, if you
+notice something but you cannot find it as an interface, then it is most likely
+a macro):
+</p>
+<a name="doc_chap4_pre5"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing4.5: Looking for the right macros</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+<span class="code-comment"># Suppose you need to read, write, connect, ... to a socket</span>
+~$ <span class="code-input">sefinddef connect</span>
+ipc_patterns.spt:define(`stream_connect_pattern',`
+<span class="code-comment">obj_perm_sets.spt:define(`rw_socket_perms', `{ ioctl read getattr write setattr append bind connect getopt setopt shutdown }')</span>
+obj_perm_sets.spt:define(`connected_socket_perms', `{ create ioctl read getattr write setattr append bind getopt setopt shutdown }')
+obj_perm_sets.spt:define(`connected_stream_socket_perms', `{ connected_socket_perms listen accept }')
+
+<span class="code-comment"># To see what the ps_process_pattern is about</span>
+~$ <span class="code-input">seshowdef ps_process_pattern</span>
+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;
+')
+</pre></td></tr>
+</table>
+<p>
+As we strive to bring most of our patches upstream, please do consider the <a href="http://oss.tresys.com/projects/refpolicy/wiki/HowToContribute">contribution
+guidelines</a> of the reference policy project. The project has a documented
+style guide, naming convention and an online API reference (for the various
+interfaces).
+</p>
+<p>
+Note that, the moment you create a new module, you'll need to create the proper
+role interfaces (if it is an application that is directly called from a user
+domain). Take a look at <span class="code" dir="ltr">tvtime_role</span> and how it is used in the
+<span class="path" dir="ltr">staff.te</span> and <span class="path" dir="ltr">sysadm.te</span> role definitions.
 </p>
 <p class="secthead"><a name="doc_chap4_sect4">Testing new modules</a></p>
 <p>
-TODO talk about users trying to do maximum testing (all the way). Also, if they
-want to support unconfined domains too, how they can do this (and should test).
+When you test your application, test it in as many ways as possible. If your
+application is a command-line application, run it both from a regular terminal
+(tty) as well as a virtual one (in an xterm). See if it still works if you run
+it in a screen session. Try out all functions and features that the application
+supports.
+</p>
+<p>
+This rigorous testing is necessary because SELinux denies everything that isn't
+explicitly allowed. If you do not test certain features, chances are that the
+module does not provide the necessary permissions and as such, users will be
+impacted.
 </p>
+<p>
+To test out a new module, load it (<span class="code" dir="ltr">semodule -i modulename.pp</span>) and relabel
+the files affiliated with the application (either through <span class="code" dir="ltr">rlpkg</span> or using
+<span class="code" dir="ltr">restorecon</span>). Consider the following testing activities if applicable (not
+all domains are interactive domains, so please read the activities with your
+domain definition in mind):
+</p>
+<ul>
+  <li>
+    Sending signals to the application (if you need to be able to kill it, try
+    killing it)
+  </li>
+  <li>
+    Run it both as a regular user (<span class="path" dir="ltr">user_u</span>) as well as
+    administrative users (if applicable). If your domain needs to support
+    unconfined domains/users, run it from an unconfined user domain too.
+  </li>
+  <li>
+    Run it from a terminal, console, screen, sudo, ...
+  </li>
+  <li>
+    Change the applications' configuration file (including rendering it useless
+    with syntax errors) and look at the applications' behavior. Especially
+    syntax failures as that might trigger the application to log things at
+    places that you haven't discovered earlier.
+  </li>
+</ul>
 <p class="chaphead"><a name="doc_chap5"></a><span class="chapnum">5.
             </span>Policy Guidelines</p>
+<p class="secthead"><a name="doc_chap5_sect1">Cosmetic denials</a></p>
 <p>
-TODO dealing with cosmetic denials
+When working on policy modules, you'll notice that the application is trying to
+do things which are denied, but have no obvious effect on the applications
+functionality. This is to be expected: many applications do not handle file
+descriptors properly (file descriptor leaks are common) or applications read
+attributes of files but don't do anything with it. You'll notice that you learn
+a lot from the application while writing its policy ;-)
 </p>
 <p>
-TODO resources - gentoo selinux policy, refpolicy guidelines
+Gentoo Hardened's idea here is to only allow what is actually needed by the
+application. Cosmetic denials are to be <span class="code" dir="ltr">dontaudit</span>'ed. Gentoo Hardened
+uses the <span class="code" dir="ltr">gentoo_try_dontaudit</span> boolean for this:
+</p>
+<a name="doc_chap5_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing5.1: Example usage of gentoo_try_dontaudit</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+<span class="code-comment"># Hide sshd_t calling module_request from the kernel_t domain</span>
+tunable_policy(`gentoo_try_dontaudit',`
+        kernel_dontaudit_request_load_module(sshd_t)
+')
+</pre></td></tr>
+</table>
+<p class="secthead"><a name="doc_chap5_sect2">Gentoo Hardened SELinux policy</a></p>
+<p>
+To streamline the policy development efforts, Gentoo Hardened as a <a href="selinux-policy.xml">SELinux Policy</a> document explaining the
+principles used during policy development and the implementation guidelines we
+strive to follow during development.
+</p>
+<p>
+Such a policy is important because we want to have a consistent security policy
+that users and developers can relate to. By following the policy, we hope that
+other developers can quickly jump in and work on it further.
 </p>
 <p class="chaphead"><a name="doc_chap6"></a><span class="chapnum">6.
             </span>Submitting Patches</p>
+<p class="secthead"><a name="doc_chap6_sect1">File context patches</a></p>
+<p>
+If you are able to fix a problem by adding the proper file contexts (using
+<span class="code" dir="ltr">semanage fcontext -a</span>), please consider the following:
+</p>
+<ul>
+  <li>
+    If the location for which you set the context deviates from the standard
+    location as either intended by the project or Gentoo itself, it might be
+    best to document it in the forums or elsewhere. We will not change file
+    contexts to match every ones configuration, unless the file context change
+    is apparent for each installation.
+  </li>
+  <li>
+    Developers might not immediately push file context changes in new policy
+    module packages to keep the amount of policy module changes low. Instead,
+    these changes can be stacked and pushed when other changes occur as well.
+  </li>
+</ul>
 <p>
-TODO differentiate between base patch and module patch.
+If you believe that the change is needed for everyone using Gentoo Hardened with
+SELinux, create a <a href="https://bugs.gentoo.org">bugreport</a> and assign
+it to <span class="code" dir="ltr">selinux@gentoo.org</span>. In the bugreport, mention the file context you
+think is necessary and why.
 </p>
+<p class="secthead"><a name="doc_chap6_sect2">Module patches</a></p>
 <p>
-TODO perhaps talk about file context patches. Perhaps we will not make a new
-build release for it, but stage it to be included in the next release when a
-non-filecontext patch is added?
+Module patches with changes that are intra-module (and have no effect outside)
+are best generated from the <span class="path" dir="ltr">policy/modules</span> location:
+</p>
+<a name="doc_chap6_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing6.1: Example generating patch for modular changes</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+~$ <span class="code-input">cd dev/hardened/strict.local/policy/modules</span>
+~$ <span class="code-input">diff -ut ../../../strict/policy/modules/services/openct.te services/openct.te</span>
+--- ../../../../strict/policy/modules/services/openct.te   2011-04-22 23:28:17.932918002 +0200
++++ services/openct.te  2011-04-23 09:55:08.156918002 +0200
+@@ -47,6 +47,10 @@
+ 
+ miscfiles_read_localization(openct_t)
+ 
++tunable_policy(`gentoo_try_dontaudit',`
++        kernel_dontaudit_read_system_state(openct_t)
++')
++
+ userdom_dontaudit_use_unpriv_user_fds(openct_t)
+ userdom_dontaudit_search_user_home_dirs(openct_t)
+</pre></td></tr>
+</table>
+<p>
+Attach this patch to the <a href="https://bugs.gentoo.org">bugreport</a>
+explaining why it is needed. If you think the patch itself is not obvious, make
+sure that the necessary comments are in place <span class="emphasis">inside the patch</span> for future
+reference.
+</p>
+<p>
+Please have a separate patch file per module (do not combine multiple modules in
+a single patch).
+</p>
+<p class="secthead"><a name="doc_chap6_sect3">Base policy patches</a></p>
+<p>
+If a patch extends a single module, or it includes interface changes on a
+module, you'll need to create a patch for the base policy. In this case, the
+patch is best made from the upper location.
+</p>
+<a name="doc_chap6_pre2"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing6.2: Generating a base policy patch</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+~$ <span class="code-input">cd dev/hardened/strict.local</span>
+~$ <span class="code-input">diff -ut ../strict/policy/modules/services/openct.if policy/modules/services/openct.if</span>
+--- ../strict/policy/modules/services/openct.if    2011-04-22 23:28:17.918918002 +0200
++++ policy/modules/services/openct.if       2011-04-23 10:01:38.753918001 +0200
+@@ -15,7 +15,7 @@
+                 type openct_t;
+         ')
+ 
+-        allow $1 openct_t:process signull;
++        allow $1 openct_t:process { signull sigchld };
+ ')
+ 
+ ########################################
+</pre></td></tr>
+</table>
+<p>
+Attach this patch to the <a href="https://bugs.gentoo.org">bugreport</a>
+explaining why it is needed. If you think the patch itself is not obvious, make
+sure that the necessary comments are in place <span class="emphasis">inside the patch</span> for future
+reference.
+</p>
+<p>
+Please have a separate patch file per major change (do not combine multiple
+unrelated changes in a single patch).
 </p>
 <p class="chaphead"><a name="doc_chap7"></a><span class="chapnum">7.
             </span>Running Your Own Policy</p>
+<p class="secthead"><a name="doc_chap7_sect1">Creating a local overlay</a></p>
+<p>
+If you want to use your own policy rather than Gentoo's, we seriously recommend
+to use a local overlay which uses the same package names and constructs. This
+allows your policy to integrate properly with the other Gentoo packages (which
+might depend on the SELinux packages). For instance, when you install openldap,
+it will still properly depend on the <span class="path" dir="ltr">sec-policy/selinux-ldap</span>
+package even if you provide it completely.
+</p>
+<p>
+To do so, first create a local overlay and copy the content of the
+<span class="path" dir="ltr">sec-policy</span> category inside it.
+</p>
+<a name="doc_chap7_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing7.1: Creating a local overlay</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+~$ <span class="code-input">mkdir dev/overlay</span>
+~$ <span class="code-input">cp -r /usr/portage/sec-policy dev/overlay</span>
+</pre></td></tr>
+</table>
+<p>
+Next, tell Portage to not synchronise the <span class="path" dir="ltr">sec-policy</span> category of
+the main tree anymore. To do so, create the file
+<span class="path" dir="ltr">/etc/portage/rsync_excludes</span> with the following content:
+</p>
+<a name="doc_chap7_pre2"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing7.2: Rsync exclusion information</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+sec-policy/
+</pre></td></tr>
+</table>
+<p>
+Finally, add your current overlay by editing <span class="path" dir="ltr">/etc/make.conf</span>:
+</p>
+<a name="doc_chap7_pre3"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing7.3: Editing make.conf</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+PORTDIR_OVERLAY="${PORTDIR_OVERLAY} /home/user/dev/overlay"
+</pre></td></tr>
+</table>
+<p>
+From now onwards, Gentoo Portage will only use your local overlay (you can
+remove <span class="path" dir="ltr">/usr/portage/sec-policy</span> if you don't want Portage to even
+reuse the current set of packages.
+</p>
+<p class="secthead"><a name="doc_chap7_sect2">Updating module packages</a></p>
 <p>
-TODO describe how to create your own overlay with modules and patchbundles. Also
-usable for developers to stage their ebuild / patch submissions before actually
-putting in git repo. Ensure that naming is consistent (so that ebuild
-dependencies of packages remain).
+To create or update a module package, you can use the following skeleton for the
+ebuilds:
 </p>
+<a name="doc_chap7_pre4"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing7.4: Skeleton for ebuilds, example for postfix</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+<span class="code-comment"># Set the MODS variable to the refpolicy name used, so services/postfix.te gives "postfix"</span>
+MODS="postfix"
+IUSE=""
+
+inherit selinux-policy-2
+
+DESCRIPTION="SELinux policy for postfix"
+
+KEYWORDS="~amd64 ~x86"
+
+<span class="code-comment"># POLICY_PATCH is optional (only when you have a patch), without it just uses the 
+# refpolicy version.</span>
+POLICY_PATCH="${FILESDIR}/fix-services-postfix-r3.patch"
+</pre></td></tr>
+</table>
+<p>
+The patch(es) that you can put in the <span class="path" dir="ltr">files/</span> location (and referred to
+in the <span class="code" dir="ltr">POLICY_PATCH</span>) should be made as defined earlier in this document.
+You can put multiple patches in this variable if you want.
+</p>
+<p>
+Don't forget to run <span class="code" dir="ltr">repoman manifest</span> with every change, and run
+<span class="code" dir="ltr">repoman scan</span> to check for potential mistakes.
+</p>
+<p class="secthead"><a name="doc_chap7_sect3">Updating base package</a></p>
+<p>
+To provide updates on the base policy, it is recommended to keep all patches you
+made centrally in a directory (say <span class="path" dir="ltr">dev/hardened/base-patches</span>). When
+you want to create a new <span class="path" dir="ltr">sec-policy/selinux-base-policy</span> release,
+create a patchbundle from your patch directory, put the bundle in the
+<span class="path" dir="ltr">files</span> location, create the updated ebuild and try it out.
+</p>
+<a name="doc_chap7_pre5"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
+<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing7.5: Building a base policy package</p></td></tr>
+<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
+~$ <span class="code-input">cd dev/hardened/base-patches</span>
+~$ <span class="code-input">tar cjvf ../overlay/sec-policy/selinux-base-policy/files/patchbundle-selinux-base-policy-2.20101213-r13.tar.bz2 *</span>
+~$ <span class="code-input">cd ../overlay/sec-policy/selinux-base-policy</span>
+~$ <span class="code-input">cp selinux-base-policy-2.20101213-r12.ebuild selinux-base-policy-2.20101213-r13.ebuild</span>
+</pre></td></tr>
+</table>
 <p>
-TODO describe how to exclude sec-policy in regular rsync
+Don't forget to run <span class="code" dir="ltr">repoman manifest</span> and <span class="code" dir="ltr">repoman scan</span>. You can
+then install <span class="path" dir="ltr">sec-policy/selinux-base-policy-2.20101213-r13</span> and test
+it out.
 </p>
 <br><p class="copyright">
     The contents of this document are licensed under the <a href="http://creativecommons.org/licenses/by-sa/2.5">Creative Commons -



             reply	other threads:[~2011-04-23 11:35 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-23 11:35 Sven Vermeulen [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-07-10 19:45 [gentoo-commits] proj/hardened-docs:master commit in: html/ Michael Palimaka
2011-09-04 19:13 Sven Vermeulen
2011-09-03 12:11 Sven Vermeulen
2011-07-15 16:09 Sven Vermeulen
2011-07-13 22:04 Sven Vermeulen
2011-06-01 21:26 Sven Vermeulen
2011-05-04 22:03 Francisco Blas Izquierdo Riera
2011-05-03 21:06 Sven Vermeulen
2011-05-03 20:23 Sven Vermeulen
2011-05-01 20:24 Sven Vermeulen
2011-04-25 23:38 Francisco Blas Izquierdo Riera
2011-03-27  1:00 Francisco Blas Izquierdo Riera
2011-03-27  0:55 Francisco Blas Izquierdo Riera
2011-03-26 23:49 Francisco Blas Izquierdo Riera
2011-03-09 18:14 Sven Vermeulen
2011-02-21 21:55 Sven Vermeulen
2011-02-19 17:01 Francisco Blas Izquierdo Riera
2011-02-19  3:29 Francisco Blas Izquierdo Riera
2011-02-19  0:14 Francisco Blas Izquierdo Riera
2011-02-18 16:11 Francisco Blas Izquierdo Riera
2011-02-18  7:07 Francisco Blas Izquierdo Riera
2011-02-15  4:40 Francisco Blas Izquierdo Riera

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bdb128145f81f05f094fb220d4df1a1768458779.SwifT@gentoo \
    --to=sven.vermeulen@siphos.be \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox