| <!-- Common Interface Language (CIL) Reference Guide --> |
| <!-- class_and_permission_statements.xml --> |
| |
| <sect1> |
| <title>Class and Permission Statements</title> |
| <sect2 id="common"> |
| <title>common</title> |
| <para>Declares a common identifier in the current namespace with a set of common permissions that can be used by one or more <literal><link linkend="class">class</link></literal> identifiers. The <literal><link linkend="classcommon">classcommon</link></literal> statement is used to associate a <literal><link linkend="common">common</link></literal> identifier to a specific <literal><link linkend="class">class</link></literal> identifier.</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(common common_id (permission_id ...))]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="common">common</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="common">common</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>common_id</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="common">common</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>permission_id</literal></para> |
| </entry> |
| <entry> |
| <para>One or more permissions.</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| |
| <para><emphasis role="bold">Example:</emphasis></para> |
| <para>This common statement will associate the <literal><link linkend="common">common</link></literal> identifier '<literal>file</literal>' with the list of permissions:</para> |
| <programlisting><![CDATA[ |
| (common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton))]]> |
| </programlisting> |
| </sect2> |
| |
| <sect2 id="classcommon"> |
| <title>classcommon</title> |
| <para>Associate a <literal><link linkend="class">class</link></literal> identifier to a one or more permissions declared by a <literal><link linkend="common">common</link></literal> identifier.</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(classcommon class_id common_id)]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="classcommon">classcommon</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classcommon">classcommon</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>class_id</literal></para> |
| </entry> |
| <entry> |
| <para>A single previously declared <literal><link linkend="class">class</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>common_id</literal></para> |
| </entry> |
| <entry> |
| <para>A single previously declared <literal><link linkend="common">common</link></literal> identifier that defines the common permissions for that class.</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| <para><emphasis role="bold">Example:</emphasis></para> |
| <para>This associates the <literal>dir</literal> class with the list of permissions declared by the <literal>file common</literal> identifier:</para> |
| <programlisting><![CDATA[ |
| (common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton)) |
| |
| (classcommon dir file)]]> |
| </programlisting> |
| </sect2> |
| |
| <sect2 id="class"> |
| <title>class</title> |
| <para>Declares a class and zero or more permissions in the current namespace.</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(class class_id (permission_id ...))]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="class">class</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="class">class</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>class_id</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="class">class</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>permission_id</literal></para> |
| </entry> |
| <entry> |
| <para>Zero or more permissions declared for the class. Note that if zero permissions, an empty list is required as shown in the example.</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| |
| <para><emphasis role="bold">Examples:</emphasis></para> |
| <para>This example defines a set of permissions for the <literal>binder</literal> class indentifier:</para> |
| <programlisting><![CDATA[(class binder (impersonate call set_context_mgr transfer receive))]]> |
| </programlisting> |
| |
| <para>This example defines a common set of permissions to be used by the <literal>sem</literal> class, the <literal>(class sem ())</literal> does not define any other permissions (i.e. an empty list):</para> |
| <programlisting><![CDATA[ |
| (common ipc (create destroy getattr setattr read write associate unix_read unix_write)) |
| |
| (classcommon sem ipc) |
| (class sem ())]]> |
| </programlisting> |
| <simpara>and will produce the following set of permissions for the <literal>sem</literal> class identifier of:</simpara> |
| <programlisting><![CDATA[(class sem (create destroy getattr setattr read write associate unix_read unix_write))]]> |
| </programlisting> |
| |
| <para>This example, with the following combination of the <literal><link linkend="common">common</link></literal>, <literal><link linkend="classcommon">classcommon</link></literal> and <literal><link linkend="class">class</link></literal> statements:</para> |
| <programlisting><![CDATA[ |
| (common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton)) |
| |
| (classcommon dir file) |
| (class dir (add_name remove_name reparent search rmdir open audit_access execmod))]]> |
| </programlisting> |
| <simpara>will produce a set of permissions for the <literal>dir</literal> class identifier of:</simpara> |
| <programlisting><![CDATA[(class dir (add_name remove_name reparent search rmdir open audit_access execmod ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton))]]> |
| </programlisting> |
| </sect2> |
| <sect2 id="classorder"> |
| <title>classorder</title> |
| <para>Defines the order of <link linkend="class">class</link>'s. This is a mandatory statement. Multiple <literal>classorder</literal> statements declared in the policy will form an ordered list.</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(classorder (class_id ...))]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal>classorder</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal>classorder</literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>class_id</literal></para> |
| </entry> |
| <entry> |
| <para>One or more <literal><link linkend="class">class</link></literal> identifiers.</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| |
| <para><emphasis role="bold">Example:</emphasis></para> |
| <para>This will produce an ordered list of "<literal>file dir process</literal>"</para> |
| <programlisting><![CDATA[ |
| (class process) |
| (class file) |
| (class dir) |
| (classorder (file dir)) |
| (classorder (dir process))]]> |
| </programlisting> |
| </sect2> |
| <sect2 id="classpermission"> |
| <title>classpermission</title> |
| <para>Declares a class permission set identifier in the current namespace that can be used by one or more <literal><link linkend="classpermissionset">classpermissionset</link></literal>s to associate one or more classes and permissions to form a named set.</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(classpermission classpermissionset_id)]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="classpermission">classpermission</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classpermission">classpermission</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classpermissionset_id</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classpermissionset">classpermissionset</link></literal> identifier.</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| <para><emphasis role="bold">Example:</emphasis></para> |
| <para>See the <literal><link linkend="classpermissionset">classpermissionset</link></literal> statement for examples.</para> |
| </sect2> |
| |
| <sect2 id="classpermissionset"> |
| <title>classpermissionset</title> |
| <para>Defines a class permission set identifier in the current namespace that associates a class and one or more permissions to form a named set. Nested expressions may be used to determine the required permissions as shown in the examples. Anonymous <literal>classpermissionset</literal>s may be used in av rules and constraints.</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(classpermissionset classpermissionset_id (class_id (permission_id | expr ...)))]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2.25 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="classpermissionset">classpermissionset</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classpermissionset">classpermissionset</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classpermissionset_id</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classpermissionset">classpermissionset</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>class_id</literal></para> |
| </entry> |
| <entry> |
| <para>A single previously declared <literal><link linkend="class">class</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>permission_id</literal></para> |
| </entry> |
| <entry> |
| <para>Zero or more permissions required by the class.</para> |
| <para>Note that there must be at least one <literal>permission</literal> identifier or <literal>expr</literal> declared).</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>expr</literal></para> |
| </entry> |
| <entry> |
| <para>Zero or more <literal>expr</literal>'s, the valid operators and syntax are:</para> |
| <simpara><literal> (and (permission_id ...) (permission_id ...))</literal></simpara> |
| <simpara><literal> (or (permission_id ...) (permission_id ...))</literal></simpara> |
| <simpara><literal> (xor (permission_id ...) (permission_id ...))</literal></simpara> |
| <simpara><literal> (not (permission_id ...))</literal></simpara> |
| <simpara><literal> (all)</literal></simpara> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| |
| <para><emphasis role="bold">Examples:</emphasis></para> |
| <para>These class permission set statements will resolve to the permission sets shown in the kernel policy language <literal><link linkend="allow">allow</link></literal> rules:</para> |
| <programlisting><![CDATA[ |
| (class zygote (specifyids specifyrlimits specifycapabilities specifyinvokewith specifyseinfo)) |
| |
| (type test_1) |
| (type test_2) |
| (type test_3) |
| (type test_4) |
| (type test_5) |
| |
| ; NOT |
| (classpermission zygote_1) |
| (classpermissionset zygote_1 (zygote |
| (not |
| (specifyinvokewith specifyseinfo) |
| ) |
| )) |
| (allow unconfined.process test_1 zygote_1) |
| ;; allow unconfined.process test_1 : zygote { specifyids specifyrlimits specifycapabilities } ; |
| |
| ; AND - ALL - NOT - Equiv to test_1 |
| (classpermission zygote_2) |
| (classpermissionset zygote_2 (zygote |
| (and |
| (all) |
| (not (specifyinvokewith specifyseinfo)) |
| ) |
| )) |
| (allow unconfined.process test_2 zygote_2) |
| ;; allow unconfined.process test_2 : zygote { specifyids specifyrlimits specifycapabilities } ; |
| |
| ; OR |
| (classpermission zygote_3) |
| (classpermissionset zygote_3 (zygote ((or (specifyinvokewith) (specifyseinfo))))) |
| (allow unconfined.process test_3 zygote_3) |
| ;; allow unconfined.process test_3 : zygote { specifyinvokewith specifyseinfo } ; |
| |
| ; XOR - This will not produce an allow rule as the XOR will remove all the permissions: |
| (classpermission zygote_4) |
| (classpermissionset zygote_4 (zygote (xor (specifyids specifyrlimits specifycapabilities specifyinvokewith specifyseinfo) (specifyids specifyrlimits specifycapabilities specifyinvokewith specifyseinfo)))) |
| |
| ; ALL |
| (classpermission zygote_all_perms) |
| (classpermissionset zygote_all_perms (zygote (all))) |
| (allow unconfined.process test_5 zygote_all_perms) |
| ;; allow unconfined.process test_5 : zygote { specifyids specifyrlimits specifycapabilities specifyinvokewith specifyseinfo } ;]]> |
| </programlisting> |
| </sect2> |
| |
| <sect2 id="classmap"> |
| <title>classmap</title> |
| <para>Declares a class map identifier in the current namespace and one or more class mapping identifiers. This will allow:</para> |
| <orderedlist> |
| <listitem><para>Multiple <literal><link linkend="classpermissionset">classpermissionset</link></literal>s to be linked to a pair of <literal><link linkend="classmap">classmap</link></literal> / <literal><link linkend="classmapping">classmapping</link></literal> identifiers.</para></listitem> |
| <listitem><para>Multiple <literal><link linkend="class">class</link></literal>s to be associated to statements and rules that support a list of classes:</para> |
| <simplelist type="inline"> |
| <member><literal><link linkend="typetransition">typetransition</link></literal></member> |
| <member><literal><link linkend="typechange">typechange</link></literal></member> |
| <member><literal><link linkend="typemember">typemember</link></literal></member> |
| <member><literal><link linkend="rangetransition">rangetransition</link></literal></member> |
| <member><literal><link linkend="roletransition">roletransition</link></literal></member> |
| <member><literal><link linkend="defaultuser">defaultuser</link></literal></member> |
| <member><literal><link linkend="defaultrole">defaultrole</link></literal></member> |
| <member><literal><link linkend="defaulttype">defaulttype</link></literal></member> |
| <member><literal><link linkend="defaultrange">defaultrange</link></literal></member> |
| <member><literal><link linkend="validatetrans">validatetrans</link></literal></member> |
| <member><literal><link linkend="mlsvalidatetrans">mlsvalidatetrans</link></literal></member> |
| </simplelist></listitem> |
| </orderedlist> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(classmap classmap_id (classmapping_id ...))]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="classmap">classmap</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classmap">classmap</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classmap_id</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classmap">classmap</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classmapping_id</literal></para> |
| </entry> |
| <entry> |
| <para>One or more <literal><link linkend="classmapping">classmapping</link></literal> identifiers.</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| <para><emphasis role="bold">Example:</emphasis></para> |
| <para>See the <literal><link linkend="classmapping">classmapping</link></literal> statement for examples.</para> |
| </sect2> |
| |
| <sect2 id="classmapping"> |
| <title>classmapping</title> |
| <para>Define sets of <literal><link linkend="classpermissionset">classpermissionset</link></literal>s (named or anonymous) to form a consolidated <literal><link linkend="classmapping">classmapping</link></literal> set. Generally there are multiple <literal><link linkend="classmapping">classmapping</link></literal> statements with the same <literal><link linkend="classmap">classmap</link></literal> and <literal><link linkend="classmapping">classmapping</link></literal> identifiers that form a set of different <literal><link linkend="classpermissionset">classpermissionset</link></literal>'s. This is useful when multiple class / permissions are required in rules such as the <literal><link linkend="allow">allow</link></literal> rules (as shown in the examples).</para> |
| <para><emphasis role="bold">Statement definition:</emphasis></para> |
| <programlisting><![CDATA[(classmapping classmap_id classmapping_id classpermissionset_id)]]></programlisting> |
| <para><emphasis role="bold">Where:</emphasis></para> |
| <informaltable frame="all"> |
| <tgroup cols="2"> |
| <colspec colwidth="2.25 *"/> |
| <colspec colwidth="6 *"/> |
| <tbody> |
| <row> |
| <entry> |
| <para><literal><link linkend="classmapping">classmapping</link></literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classmapping">classmapping</link></literal> keyword.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classmap_id</literal></para> |
| </entry> |
| <entry> |
| <para>A single previously declared <literal><link linkend="classmap">classmap</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classmapping_id</literal></para> |
| </entry> |
| <entry> |
| <para>The <literal><link linkend="classmapping">classmapping</link></literal> identifier.</para> |
| </entry> |
| </row> |
| <row> |
| <entry> |
| <para><literal>classpermissionset_id</literal></para> |
| </entry> |
| <entry> |
| <para>A single named <literal><link linkend="classpermissionset">classpermissionset</link></literal> identifier or a single anonymous <literal><link linkend="classpermissionset">classpermissionset</link></literal> using <literal>expr</literal>'s as required (see the <literal><link linkend="classpermissionset">classpermissionset</link></literal> statement).</para> |
| </entry> |
| </row> |
| </tbody></tgroup> |
| </informaltable> |
| <para><emphasis role="bold">Examples:</emphasis></para> |
| <para>These class mapping statements will resolve to the permission sets shown in the kernel policy language <literal><link linkend="allow">allow</link></literal> rules:</para> |
| <programlisting><![CDATA[ |
| (class binder (impersonate call set_context_mgr transfer receive)) |
| (class property_service (set)) |
| (class zygote (specifyids specifyrlimits specifycapabilities specifyinvokewith specifyseinfo)) |
| |
| (classpermission cps_zygote) |
| (classpermissionset cps_zygote (zygote (not (specifyids)))) |
| |
| (classmap android_classes (set_1 set_2 set_3)) |
| |
| (classmapping android_classes set_1 (binder (all))) |
| (classmapping android_classes set_1 (property_service (set))) |
| (classmapping android_classes set_1 (zygote (not (specifycapabilities)))) |
| |
| (classmapping android_classes set_2 (binder (impersonate call set_context_mgr transfer))) |
| (classmapping android_classes set_2 (zygote (specifyids specifyrlimits specifycapabilities specifyinvokewith))) |
| |
| (classmapping android_classes set_3 cps_zygote) |
| (classmapping android_classes set_3 (binder (impersonate call set_context_mgr))) |
| |
| (block map_example |
| (type type_1) |
| (type type_2) |
| (type type_3) |
| |
| (allow type_1 self (android_classes (set_1))) |
| (allow type_2 self (android_classes (set_2))) |
| (allow type_3 self (android_classes (set_3))) |
| ) |
| |
| ; The above will resolve to the following AV rules: |
| ;; allow map_example.type_1 map_example.type_1 : binder { impersonate call set_context_mgr transfer receive } ; |
| ;; allow map_example.type_1 map_example.type_1 : property_service set ; |
| ;; allow map_example.type_1 map_example.type_1 : zygote { specifyids specifyrlimits specifyinvokewith specifyseinfo } ; |
| |
| ;; allow map_example.type_2 map_example.type_2 : binder { impersonate call set_context_mgr transfer } ; |
| ;; allow map_example.type_2 map_example.type_2 : zygote { specifyids specifyrlimits specifycapabilities specifyinvokewith } ; |
| |
| ;; allow map_example.type_3 map_example.type_3 : binder { impersonate call set_context_mgr } ; |
| ;; allow map_example.type_3 map_example.type_3 : zygote { specifyrlimits specifycapabilities specifyinvokewith specifyseinfo } ;]]> |
| </programlisting> |
| </sect2> |
| |
| </sect1> |