#814 Add SELinux Independent Policy Guidelines
Closed 2 years ago by vmojzis. Opened 6 years ago by vmojzis.
vmojzis/packaging-committee master  into  master

@@ -0,0 +1,31 @@ 

+ ########################################

+ # 

+ # Interface compatibility blocks

+ #

+ # The following definitions ensure compatibility with distribution policy

+ # versions that do not contain given interfaces (epel, or older Fedora

+ # releases).

+ # Each block tests for existence of given interface and defines it if needed.

+ #

+ 

+ ########################################

+ ## <summary>

+ ##    Allow caller to signull sssd.

+ ##    Backport from RHEL8

+ ## </summary>

+ ## <param name="domain">

+ ##    <summary>

+ ##    Domain allowed access.

+ ##    </summary>

+ ## </param>

+ #

+ ifndef(`sssd_signull',`

+   interface(`sssd_signull',`

+       gen_require(`

+           type sssd_t;

+       ')

+ 

+       allow $1 sssd_t:process signull;

+   ')

+ ')

+ 

@@ -0,0 +1,108 @@ 

+ %global with_selinux 1

+ %global modulename mypolicy

+ %global selinuxtype targeted

This is not necessary.

+ 

+ ----------------------------------------

+ 

+ Source2:       %{modulename}.te

+ Source3:       %{modulename}.if

+ Source4:       %{modulename}.fc

+ 

+ ----------------------------------------

+ 

+ %if 0%{?with_selinux}

+ # This ensures that the *-selinux package and all it’s dependencies are not pulled

+ # into containers and other systems that do not use SELinux

+ Requires:        (%{name}-selinux if selinux-policy-%{selinuxtype})

This can just be selinux-policy

+ %endif

+ 

+ ----------------------------------------

+ 

+ %if 0%{?with_selinux}

+ # SELinux subpackage

+ %package selinux

+ Summary:             Myapp SELinux policy

+ BuildArch:           noarch

+ Requires:            selinux-policy-%{selinuxtype}

+ Requires(post):      selinux-policy-%{selinuxtype}

selinux-policy-%{selinuxtype} is redundant with %{?selinux_requires}

+ BuildRequires:       selinux-policy-devel

+ %{?selinux_requires}

+ 

+ %description selinux

+ Custom SELinux policy module

+ %endif

+ 

+ -------- %build section ----------------

+ 

+ %if 0%{?with_selinux}

+ # SELinux policy (originally from selinux-policy-contrib)

+ # this policy module will override the production module

+ mkdir selinux

+ cp -p %{SOURCE2} selinux/

+ cp -p %{SOURCE3} selinux/

+ cp -p %{SOURCE4} selinux/

+ 

+ make -f %{_datadir}/selinux/devel/Makefile %{modulename}.pp

+ bzip2 -9 %{modulename}.pp

+ %endif

+ 

+ -------- %install section --------------

+ 

+ %if 0%{?with_selinux}

+ install -D -m 0644 %{modulename}.pp.bz2 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2

Remove /%{selinuxtype} from the path to install the module.

+ install -D -p -m 0644 selinux/%{modulename}.if %{buildroot}%{_datadir}/selinux/devel/include/distributed/%{modulename}.if

/distributed doesn't exist in the selinux-policy hierarchy, and I've generally seen it put in /contrib instead, which does exist.

+ %endif

+ 

+ ----------------------------------------

+ 

+ %if 0%{?with_selinux}

+ # SELinux contexts are saved so that only affected files can be

+ # relabeled after the policy module installation

+ %pre selinux

+ %selinux_relabel_pre -s %{selinuxtype}

Drop -s %{selinuxtype}

+ 

+ %post selinux

+ %selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2

Drop -s %{selinuxtype} and /%{selinuxtype}

+ 

+ %postun selinux

+ if [ $1 -eq 0 ]; then

+     %selinux_modules_uninstall -s %{selinuxtype} %{modulename}

Drop -s %{selinuxtype}

+ fi

+ 

+ %posttrans selinux

+ %selinux_relabel_post -s %{selinuxtype}

Drop -s %{selinuxtype}

+ # if with_selinux

+ %endif

+ 

+ -------- version for daemons/services --------

+ 

+ %if 0%{?with_selinux}

+ # SELinux contexts are saved so that only affected files can be

+ # relabeled after the policy module installation

+ %pre selinux

+ %selinux_relabel_pre -s %{selinuxtype}

Drop -s %{selinuxtype}

+ 

+ %post selinux

+ %selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2

Drop -s %{selinuxtype} and /%{selinuxtype}

+ %selinux_relabel_post -s %{selinuxtype}

Drop -s %{selinuxtype}

+ 

+ if [ "$1" -le "1" ]; then # First install

+    # the daemon needs to be restarted for the custom label to be applied

+    %systemd_postun_with_restart %{modulename}.service

+ fi

+ 

+ %postun selinux

+ if [ $1 -eq 0 ]; then

+     %selinux_modules_uninstall -s %{selinuxtype} %{modulename}

Drop -s %{selinuxtype}

+     %selinux_relabel_post -s %{selinuxtype}

Drop -s %{selinuxtype}

+ fi

+ %endif

+ 

+ ----------------------------------------

+ 

+ %if 0%{?with_selinux}

+ %files selinux

+ %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.*

Drop /%{selinuxtype}

+ %{_datadir}/selinux/devel/include/distributed/%{modulename}.if

You probably want to use /contrib rather than /distributed here, as the latter doesn't exist as far as I can tell.

+ %ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}

%verify() is redundant with %ghost and this should be macroized so %ghost entries exist for all available SELinux policy variants provided by the selinux-policy package, with the correct override number in the file path set by the other macros.

+ %endif

@@ -0,0 +1,58 @@ 

+ # defining macros needed by SELinux

+ %global selinuxtype targeted

+ %global modulename myapp

+ 

+ Name: myapp-selinux

+ Version: 1.0

+ Release: 1%{?dist}

+ License: GPLv2

+ URL: # URL to git repository with policy source files

+ Summary: SELinux policies for product

+ Source0: # archive with SELinux policy sources. e.g: myapp-selinux.tar

+ Requires: selinux-policy-%{selinuxtype}

+ Requires(post): selinux-policy-%{selinuxtype}

+ BuildRequires: selinux-policy-devel

+ BuildArch: noarch

+ %{?selinux_requires}

+ %description

+ SELinux policy modules for product.

+ 

+ %prep

+ %setup -q

+ 

+ %build

+ make

+ 

+ %pre

+ %selinux_relabel_pre -s %{selinuxtype}

+ 

+ %install

+ # install policy modules

+ install -D -m 0644 %{modulename}.pp.bz2 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2

+ install -D -p -m 0644 selinux/%{modulename}.if %{buildroot}%{_datadir}/selinux/devel/include/distributed/%{modulename}.if

+ %check

+ 

+ %post

+ %selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2

+ %selinux_relabel_post -s %{selinuxtype}

+ 

+ if [ "$1" -le "1" ]; then # First install

+    # the daemon needs to be restarted for the custom label to be applied

+    %systemd_postun_with_restart %{modulename}.service

+ fi

+ 

+ %postun

+ if [ $1 -eq 0 ]; then

+     %selinux_modules_uninstall -s %{selinuxtype} %{modulename}

+     %selinux_relabel_post -s %{selinuxtype}

+ fi

+ 

+ %files

+ %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.*

+ %{_datadir}/selinux/devel/include/distributed/%{modulename}.if

+ %ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}

+ %license COPYING

+ 

+ %changelog

+ * Mon Jan 01 2017 Author Name <Author@mail-example.com> - 0.1.0-1

+ - First Build

@@ -0,0 +1,1 @@ 

+ /sbin/myapp --  gen_context(system_u:object_r:myapp_exec_t,s0)

@@ -0,0 +1,2 @@ 

+ ##

+ My app service. 

\ No newline at end of file

@@ -0,0 +1,8 @@ 

+ policy_module(myapp,1.0)

+ 

+ type myapp_t;

+ type myapp_exec_t;

+ init_daemon_domain(myapp_t, myapp_exec_t)

+ 

+ # Grant myapp_t the signal privilege

+ allow myapp_t self:process { signal }; 

\ No newline at end of file

@@ -0,0 +1,487 @@ 

+ = Decentralized SELinux Policy Guidelines

+ 

+ In Fedora, there is a lot of applications and daemons

+ which require customized SELinux security policy.

+ The former approach with providing all policies as a part of the system

+ has been enhanced by the option to create and ship a custom policy.

+ 

+ This enables releasing updated security policy when needed

+ as opposed to waiting for next release of SELinux policy package.

+ In other words custom SELinux policy is always synchronized

+ with the corresponding product (package).

+ 

+ This guideline is dedicated to shipping custom SELinux security module

+ as a subpackage for a daemon or an application.

+ 

+ 

+ [[agreement-workflow]]

+ == Agreement workflow

+ 

+ Before you start shipping custom policies,

+ let the SELinux team know about your intentions.

+ To do this, use SELinux Fedora mailing list

+ or contact SELinux policy maintainer:

+ 

+ * mailto:selinux-policy-owner@fedoraproject.org[SELinux Policy maintainer]

+ * mailto:selinux@lists.fedoraproject.org[selinux@lists.fedoraproject.org]

+ 

+ 

+ [[policy-sources]]

+ == Policy sources

+ 

+ Maintainer should base the custom policy

+ on a policy extracted from distribution policy package

+ when possible.

+ The Git repository with distribution policies is located on

+ https://github.com/fedora-selinux/selinux-policy

+ and

+ https://github.com/fedora-selinux/selinux-policy-contrib.

+ This way the custom policy can override the original policy --

+ as long as all definitions (types, attributes, aliases, etc.) are kept.

+ 

+ CAUTION: Distribution policies have GPL license,

+ so any policy extracted from Distribution policy

+ must have a GPL compatible license.

+ 

+ 

+ If new policy was created

+ (no suitable policy existed, or the original policy was significantly altered)

+ it has to be submitted to SELinux team for review before shipping.

+ See `sepolicy generate` tool when writing a policy from scratch.

+ 

+ Please make sure the policy sources follow

+ https://github.com/TresysTechnology/refpolicy/wiki/StyleGuide[SELinux policy Style Guide].

+ 

+ 

+ [[policy-source-examples]]

+ === Policy source examples

+ 

+ For the purpose of this example, we create a policy named myapp:

+ 

+ .myapp.te

+ [source]

+ ----

+ include::{examplesdir}/selinux/myapp.te[]

+ ----

+ .myapp.fc

+ [source]

+ ----

+ include::{examplesdir}/selinux/myapp.fc[]

+ ----

+ .myapp.if

+ [source]

+ ----

+ include::{examplesdir}/selinux/myapp.if[]

+ ----

+ 

+ The custom policy repository must contain the following files

+ (replace myapp with a name of your package):

+ 

+ ....

+ $ ls

+ myapp.fc  myapp.if  myapp.te COPYING

+ ....

+ 

+ It is also recommended to include a Makefile for ease of use

+ (can be generated using `sepolicy generate` tool)

+ Alternatively the following command (selinux-policy-devel package),

+ can be used to compile the policy source:

+ ....

+ make -f /usr/share/selinux/devel/Makefile <module name>.pp

+ ....

+ 

+ 

+ [[using-custom-interfaces]]

+ === Using custom interfaces

+ 

+ Interfaces (content of .if file) allow other policy modules to gain access

+ to resources of confined package when needed. Whenever a new interface is defined,

+ it is necessary to ship the updated interface file as part of the policy package (rpm)

+ so that other policy modules can use it.

+ 

+ ....

+ %install

+ install -D -p -m 644 selinux/%{modulename}.if %{buildroot}%{_datadir}/selinux/devel/include/distributed/%{modulename}.if

+ 

+ %files

+ %{_datadir}/selinux/devel/include/distributed/%{modulename}.if

+ ....

+ 

+ CAUTION: All custom interfaces

+ (that is, interfaces that are not part of distribution policy)

+ _must_ be prefixed with "_ipp__"

+ not to be confused with distribution interfaces.

+ 

+ Changes to interfaces of the original module

+ can only be delivered via distribution _selinux-policy-*_ packages.

+ If such a change is necessary, please contact the SELinux team,

+ or submit a pull request.

+ Please bear in mind that such changes will influence other policy modules

+ that use given interface.

+ 

+ === Backwards compatibility

+ 

+ The most common problem with using custom policies

+ on older distributions is undefined interfaces.

+ 

+ ....

+ Compiling targeted nagios module

+ selinux/nagios.te:374:ERROR 'syntax error' at token 'sssd_signull' on line 19406:

+     sssd_signull(nrpe_t)

+ ....

+ 

+ This issue can be resolved by conditionally defining the missing interface.

+ To do this, find definition of the missing interface in

+ https://github.com/fedora-selinux/selinux-policy-contrib[SELinux-policy-contrib]

+ or

+ https://github.com/fedora-selinux/selinux-policy[SELinux-policy]

+ repository, copy it to your interface file and enclose in an _ifndef_

+ statement.

+ 

+ Example using _sssd_signull_ (necessary to use this interface in epel8):

+ 

+ .myapp.if

+ [source]

+ ----

+ include::{examplesdir}/selinux/interface-compatibility-block.if[]

+ ----

+ 

+ === Moving type/attribute/alias definitions

+ 

+ Whenever a type,attribute or alias definition is moved between modules

+ (this is usually done when two modules are merged together,

+ or some distinct part of a policy is moved to a separate module)

+ maintainers should include the following steps in the custom policy installation:

+ 

+ * Disable the distribution version of affected module(s) before calling

+ `%selinux_modules_install`

+ ** `semodule -d &> /dev/null || true;`

+ * Re-enable the original policy modules after

+ `%selinux_modules_uninstall`

+ ** `semodule -e &> /dev/null || true;`

+ 

+ These steps are necessary to avoid type, attribute or alias redefinition errors,

+ which may cause the custom package installation to fail.

+ Example of such error:

+ 

+ ....

+ Running scriptlet: freeipa-selinux-4.8.6-1.fc33.noarch                            2/4

+ Re-declaration of type ipa_custodia_t

+ Failed to create node

+ Bad type declaration at /var/lib/selinux/targeted/tmp/modules/100/ipa_custodia/cil:1

+ /usr/sbin/semodule:  Failed!

+ ....

+ 

+ [[file-contexts]]

+ === File contexts and equivalency rules

+ 

+ File context can be specified either by mapping labels to specific paths

+ in ".fc" policy files

+ (eg. `+/usr/bin/cdcc -- gen_context(system_u:object_r:cdcc_exec_t,s0)+`),

+ or by setting file path equivalency

+ (eg. `+semanage fcontext -a -e /home /export/home+`).

+ The latter approach mirrors labelling structure of the source directory to the target.

+ There is only a handful of file path equivalencies in the distribution policy,

+ but it is important to take them into consideration

+ whenever a file context rule is edited or added.

+ 

+ File context rules must not reference paths

+ that are labelled according to an equivalency

+ (the new context must be assigned to the original path --

+ source of the equivalency, not to the target).

+ 

+ [[custom-policy-modules-and-distribution-policy]]

+ === Custom policy modules and distribution policy

+ 

+ It's important to note that distribution policies _should not_ use

+ interfaces from removable policy modules.

+ 

+ When using types from custom policy modules

+ _stub_ interfaces should be used instead of directly requiring given type.

+ Stub interface is defined and used in distribution module as follows.

+ 

+ .distribution_module.if

+ ....

+ ...

+ ...

+ ########################################

+ ## <summary>

+ ##  DBUS stub interface.  No access allowed.

+ ## </summary>

+ ## <param name="domain" unused="true">

+ ## <summary>

+ ##  Domain allowed access

+ ## </summary>

+ ## </param>

+ #

+ interface(`distro_stub',`

+     gen_require(`

+         type dystro_t;

+     ')

+ ')

+ ...

+ ...

+ ....

+ 

+ .myapp.te

+ ....

+ ...

+ ...

+ optional_policy(`

+     distro_stub()

+     allow distro_t myapp_log_t:file read_file_perms;

+ ')

+ ...

+ ...

+ 

+ ....

+ 

+ As with any type defined outside of _SELinux policy base modules_,

+ _optional_policy_ block must be used

+ when using types from removable modules in distribution policy.

+ 

+ 

+ [[spec-file]]

+ == Spec File

+ 

+ When a repository with SELinux policy sources is ready,

+ create your .spec file (rpmbuild configuration file).

+ 

+ IMPORTANT: Please note that this guideline focuses on _targeted_ SELinux mode.

+ In case you intend to use the custom policy in multiple SELinux modes,

+ please see

+ https://fedoraproject.org/wiki/SELinux/IndependentPolicy_MLS[custom

+ product policies targeting multiple SELinux modes].

+ 

+ You can use the following example as a template (separate myapp-selinux package):

+ 

+ .myapp-selinux.spec

+ [source]

+ ----

+ include::{examplesdir}/selinux/myapp-selinux.spec[]

+ ----

+ 

+ Or the following example as a guide how to edit your existing spec file:

+ 

+ .myapp.spec changes

+ [source]

+ ----

+ include::{examplesdir}/selinux/myapp-selinux-edit.spec[]

+ ----

+ 

+ [[naming]]

+ === Naming conventions

+ 

+ The (sub)package containing custom SELinux policy must be named after

+ the package that uses given policy, followed by _-selinux_

+ (eg. _myapp-selinux_).

+ 

+ For intefrace naming and other policy conventions see

+ https://github.com/SELinuxProject/refpolicy/wiki[Reference Policy wiki pages].

+ 

+ 

+ [[adding-dependency-to-the-spec-file-of-corresponding-package]]

+ === Adding dependency to the spec file of corresponding package

+ 

+ The *-selinux package should only be required on SELinux enabled systems.

+ Therefore the following rich dependency syntax should be used:

+ 

+ ....

+ Requires: (%{name}-selinux if selinux-policy-%{selinuxtype})

+ ....

+ 

+ This ensures that the *-selinux package and all its dependencies

+ are not pulled into containers and other systems that do not use SELinux.

+ 

+ 

+ [[selinux-policy-module-Install]]

+ === SELinux Policy module installation

+ SELinux modules are not installed by the spec file _install_ command,

+ but using the _semodule_ tool.

+ Maintainers should use _%selinux_modules_install_ macro,

+ which calls _semodule_ with all the necessary parameters.

+ 

+ The actual module data are then stored in

+ `%{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}`

+ directory (you can see it specified in the _files_ section of the spec file as _%ghost_).

+ The "_200_" refers to the priority at which the module is installed

+ (see <<selinux-policy-module-priorities>> for more deatils).

+ 

+ The only binary file used in this process is the _.pp_ archive,

+ which is architecture independent.

+ Therfore the resulting subpackage should be created as _noarch_ (`BuildArch: noarch`).

+ 

+ [[selinux-policy-module-priorities]]

+ === SELinux Policy module priorities

+ 

+ IMPORTANT: Policy modules can be installed with different priorities.

+ When multiple modules of the same name exist in the system,

+ only the module with the highest priority takes effect.

+ 

+ Distribution policy modules are installed with priority of 100.

+ Custom policy should always be shipped with priority of 200

+ to override distribution policy.

+ This value is contained inside the _%selinux_modules_install_ macro

+ and should not be changed.

+ 

+ Note that _semodule_ installs policy modules with priority of 400 by default.

+ 

+ See

+ https://plautrba.fedorapeople.org/selinux-modules-and-priority.html[SELinux modules and priority]

+ for more details about module priority.

+ 

+ 

+ [[setting-booleans-during-installation]]

+ === Setting Booleans During Installation

+ 

+ WARNING: Setting generic booleans can open security holes in the system!

+ 

+ In some cases, it is necessary to enable or disable booleans

+ defined in the system security policy.

+ Maintainers should use the following steps to do so:

+ 

+ * Find a boolean that best fits your needs while avoiding generic booleans if possible (additional access in the custom policy module is preferred to switching a boolean that impacts other policy modules).

+ 

+ * Specify booleans in the following format in the .spec file:

+ +

+ ....

+ # default boolean values need to be changed due to the custom policy

+ # the change is performed by "%selinux_set_booleans" macro in %post phase

+ %global selinuxbooleans booleanname=1 booleanname2=0

+ 

+ ....

+ * It is necessary to use special macro _%selinux_set_booleans

+ during "%post" phase of rpmbuild

+ to make sure that the specified boolean values are set.

+ 

+ See the following example:

+ 

+ ....

+ %post

+ %selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2

+ %selinux_set_booleans -s %{selinuxtype} %{selinuxbooleans}

+ 

+ %postun

+ %selinux_modules_uninstall -s %{selinuxtype} %{modulename}

+ %selinux_unset_booleans -s %{selinuxtype} %{selinuxbooleans}

+ 

+ ....

+ 

+ The boolean macros mentioned above behave as follows:

+ 

+ * The value of each boolean set using _%selinux_set_booleans_ is recorded

+ and will be reset to the original value when "%selinux_unset_booleans" is called

+ 

+ * Number of calls to _%selinux_set_booleans_ and _%selinux_unset_booleans_

+ has to match in order for this mechanism to work properly

+ 

+ [[port-labeling]]

+ === Port Labeling

+ 

+ If your custom policy does not define port labels (such as _product_port_t_),

+ you can skip this section.

+ 

+ You should assign a port number and a port type to every port label.

+ Assigning a port label should be done in %post install phase.

+ For example, for the TCP 1111 port, the

+ `semanage port -a -t product_port_t -p tcp 1111`

+ command should be added to the if statement in the .spec file:

+ 

+ ....

+ if %{_sbindir}/selinuxenabled ; then

+      %{_sbindir}/semanage port -a -t product_port_t -p tcp 1111

+ fi

+ ....

+ 

+ Where the `a`, `t`, and `p` of the `semanage` command mean the

+ following:

+ 

+ ....

+ -a   Add a record of the specified object type

+ -t   SELinux type for the port

+ -p   Protocol  for  the  specified  port  (tcp|udp)

+ ....

+ 

+ For the %post uninstall phase, the port assignment should be removed.

+ To do this, add the

+ `semanage port -d -t <PORT>`

+ command in your .spec file.

+ For example:

+ 

+ ....

+ if %{_sbindir}/selinuxenabled ; then

+     %{_sbindir}/semanage port -d  -p tcp -t product_port_t

+ fi

+ ....

+ 

+ [[testing]]

+ === Testing

+ 

+ Place a copy of

+ https://pagure.io/DSP_test/blob/master/f/example_tests-DSP.yml[tests-DSP.yml]

+ into the resulting package distgit _tests_ directory

+ to test for potentially dangerous policy issues

+ (we recommend leaving the name at _tests-DSP.yml_,

+ but anything that fits _tests*.yml_ will work).

+ The environment section needs to be configured to your package

+ and the package also needs to be added to required_packages.

+ 

+ Example environment configurations:

+ 

+ https://src.fedoraproject.org/rpms/zabbix/pull-request/4[Zabbix]

+ - policy sources are placed directly in

+ https://src.fedoraproject.org/rpms/zabbix/tree/master[distgit]

+ (hence `POLICY_TAR: ''`)

+ ....

+ TEST_RPM: zabbix-selinux

+ TEST_POLICY: zabbix

+ POLICY_TAR: ''

+ POLICY_PATH: .

+ ....

+ 

+ https://src.fedoraproject.org/rpms/freeipa/tree/master[Freeipa]

+ - policy sources live in

+ https://github.com/freeipa/freeipa/tree/master/selinux[freeipa upstream]

+ (in _selinux_ directory)

+ ....

+ TEST_RPM: freeipa-selinux

+ TEST_POLICY: ipa

+ POLICY_TAR: 'freeipa-*.tar.gz'

+ POLICY_PATH: 'freeipa-*/selinux'

+ ....

+ 

+ https://src.fedoraproject.org/rpms/usbguard/tree/master[USBGuard]

+ - policy sources are stored in a

+ https://github.com/USBGuard/usbguard-selinux[separate repository]

+ (separate tar.gz)

+ ....

+ TEST_RPM: usbguard-selinux

+ TEST_POLICY: usbguard

+ POLICY_TAR: 'usbguard-selinux*.tar.gz'

+ POLICY_PATH: 'usbguard-selinux*'

+ ....

+ 

+ 

+ [[removing-your-custom-policy-from-the-system-policy]]

+ 

+ == Removing your Custom Policy from the System Policy

+ 

+ When your SELinux subpackage is ready for a release,

+ contact the SELinux policy maintainer.

+ He should remove the corresponding policy module from the SELinux distribution policy

+ and update the package.

+ You should then add a dependency on the new selinux-policy package:

+ 

+ ....

+ # Version of selinux-policy when custom policy was removed

+ %global selinux_policyver POLICY_VERSION

+ Requires: selinux-policy >= %{selinux_policyver}

+ ....

+ 

+ If the released policy was not part of the distribution policy,

+ there is no need to add a version dependency to your .spec file.

+ 

+ Now your SELinux subpackage is ready for release.

+ It is recommended to create a group update

+ together with selinux-policy package

+ to ensure that the updating process will be successful.

Please provide such makefile as part of selinux-devel or such package so that packagers do not have to copy it over and over

So after reading this, I think different structure should be used, probably something like:

  • BuildRequires
  • %build section, which commands to execute in order to build policy (note the makefile comment above, so plain commands + example with using makefile, not the makefile itself)
  • %install section, where to install, some small example which files to install and where
  • Scriptlets
    applying policy
    port labelling
  • Example spec
  • Links to some examples which mention how to write a policy

probably %build, %install and scriptlets should be a subsections of port labels / other policies

None of this "git repository setup" section belongs in the packaging guidelines. I would completely remove lines 50 through 131.

I believe this needs to be converted to prescriptive language. If we're saying that manipulating booleans in this way is a requirement, then use "MUST" and such. Right now I can't tell if "it is necessary" means that the macro is the way to do this kind of thing, or if the package has to take these steps.

What is a "product" in this context? It's not a term we use elsewhere in the guidelines.

Please follow semantic line breaks: http://sembr.org/

Sorry, I'll fix that.

What is a "product" in this context? It's not a term we use elsewhere in the guidelines.

Application or daemon. As specified in the first sentence of the section.

IMO this should not be in guidelines.

I believe the "Extraction process" is important. Especially for people who are new to writing SELinux policy. Should we move it to our wiki page and reference in this document, or what would be the best approach?

None of this "git repository setup" section belongs in the packaging guidelines. I would completely remove lines 50 through 131.

This part is in place to suggest keeping the SELinux policy sources in a separate repository to minimize synchronization issues with distribution policy (during the transitional period when the policy module is in both "selinux-policy-{targeted|mls}" and "foo-selinux" packages).

Please provide such makefile as part of selinux-devel or such package so that packagers do not have to copy it over and over

The makefile is not necessary, but it's nice to have. The idea here is that the maintainer will customize the makefile with all that is necessary for the module installation (switching booleans, adding port mappings, etc.).
The module compilation is actually done using a makefile provided by selinux-policy-devel (make -f ${SHAREDIR}/selinux/devel/Makefile $@).

I believe this needs to be converted to prescriptive language. If we're saying that manipulating booleans in this way is a requirement, then use "MUST" and such. Right now I can't tell if "it is necessary" means that the macro is the way to do this kind of thing, or if the package has to take these steps.

I'll reword the section. It only describes the behaviour of the macros.

1 new commit added

  • Update based on comments from the packaging committee
6 years ago

2 new commits added

  • Update based on comments from the packaging committee
  • Add SELinux Independent Policy Guidelines
6 years ago

as said earlier, this doesn't belong to Packaging Guidelines.

why is this makefile needed? Just create necessary RPM macro for it.

why is this makefile needed? Just create necessary RPM macro for it.

The makefile makes it possible to easily use the policy outside of an RPM. Also, it is consistent with policies generated by "sepolicy generate".
However, an RPM macro is a good idea. We could let maintainers decide what they want to use.

Updated:
- Describe Makefile as optional
- Remove "Git Repository setup" section
- Change section label syntax to work with "asciidoc" properly

1 new commit added

  • Update based on comments from the packaging committee
5 years ago

Could someone please have a look at the updated document?

also, you can drop square brackets since there is no good replacement.

I'm not happy with this wording. Probably something like create a build script (e.g. Makefile)?

But this is definitely important note. Probably annotate it with CAUTION: and move somewhere above where text is about whether to write from scratch or extract it from selinux-policy? I know it is obvious that people should look at license of the project they are taking code from, but it won't hurt anybody to repeat it again.

If sepolicy generate generates it, let's remove this section and put somewhere above something like You can use sepolicy generate to start new project or something like that?

Especially because it is already distributed by selinux. Let's just say that packagers can use this command to compile their policies.

this should be executed by brp-* script in RPM, mind opening RFE or sending patch on https://github.com/rpm-software-management/rpm ?

You can annotate file names in asciidoctor syntax (see Rust.adoc for some example).

Let's remove this section entirely. Guidelines is not the place where you describe how to set up git repo and archive files.

Just use install -D to create directory so that previous line is not needed

As I said, guidelines is not a tutorial. Just put one complete spec file in Expamles section on this page

I would prefer if it would be .pp* so that if we ever change archive format we won't have to redo all specs. Does selinux support different compression formats?

would appreciate if you could tell what this "200" means

hi @vmojzis, I took a quick look on page. It does look better, but I left some comments.

Basically guidelines is the page where you describe things like "you MUST call %selinux_foo_bar in %post", "you MUST NOT depend on custom interfaces blah" and so on.

It definitely should have some examples and some quick guide how to actually package selinux policies, but not how to create tarball and create license file.

Thank you. Updated and rebased.

would appreciate if you could tell what this "200" means

That is the priority of the new module. As described in the "SELinux Policy module priorities" section, all custom policy modules are shipped with this priority.

rebased onto d50c10127b237e717c03d328763b8954a8f38d82

5 years ago

Thank you for the review. Updated and rebased.

Could someone please review the latest changes?

Metadata Update from @churchyard:
- Pull-request tagged with: meeting

5 years ago

I don't understand, why this guildeline appears to suggest to create independent "myapp-selinux" packages, while the typical use case should be just "-slinux" subpackages IMO.

On Thursday, September 26, 2019 11:55:16 AM CEST V=EDt Ondruch wrote:

=20
vondruch commented on the pull-request: Add SELinux Independent Policy G= uidelines that you are following:
I don't understand, why this guildeline appears to suggest to create independent "myapp-selinux" packages, while the typical use case should be just "-slinux" subpackages IMO.

I think that separate package is better because - if one eventually decides=
to
maintain the separate policy - usually there would be more packages ruled=
by
one selinux package. E.g. postgresql-selinux would be usable not only by
postgresql.spec but also third party modules (and other higher level
stuff built on top of postgresql-server e.g).

Then, it is much easier to have separate selinux package with separate life=
cycle
(it is easier and less risky to update the policy without rebuilding any ot=
her
package). Subpackage sounds like a valid option, but I guess that would be=
less
frequent.

I don't understand, why this guildeline appears to suggest to create independent "myapp-selinux" packages, while the typical use case should be just "-slinux" subpackages IMO.

Both are possible (and SELinux team has no preference), but we expect that subpackages will be more common.
The example spec file can be easily used to add a -selinux subpackage to an existing spec file, while containing all the information necessary for a standalone package.

based on the real life conversation with @vmojzis I'm assigning this to him for now. He is planning to update the proposal to be more guidelines-like.

We discussed this at this weeks meeting (https://meetbot-raw.fedoraproject.org/fedora-meeting-1/2019-11-21/fpc.2019-11-21-17.00.txt):

I spoke to @lvrabec, not lbrabec, sorry about that. I've edited your comment to correct that.

rebased onto 91f194a7b052333f89af731c302e36a815c041b1

5 years ago

Updated and rebased. Hopefully I addressed all that we talked about :)

1 new commit added

  • Add alternative example spec file and equivalency section
4 years ago

I added an alternative example spec file and a section advising how to treat file context equivalency rules.

@churchyard any issues after the update?

Sorry, I wasn't able to look into this yet. I was on PTO for a week and my TODO list is overflowing. Will try to do this soon.

I understand, thank you.

Rebased and updated:
- Add "Backwards compatibility" and "Moving type/attribute/alias definitions" sections
- Improve "Setting Booleans During Installation"
- Fix minor issues in example spec files

rebased onto c82fb3cfb7318c53660bcbd65e5562ab54138d1c

4 years ago

@churchyard is the "meeting" tag still valid?

Yes, but our meetings tend to get cancelled for no quorum. See also https://pagure.io/packaging-committee/issue/977

We talked about this at this weeks meeting (https://meetbot-raw.fedoraproject.org/fedora-meeting-1/2020-09-03/fpc.2020-09-03-16.00.txt):

rebased onto 9088995

3 years ago

Rebased and updated based on experience with latest policy "adopters".
- minor changes to example spec file
- new section regarding testing
- rewritten interface file handling
- add link to multi-mode policy package guide

selinux-policy-%{selinuxtype} is redundant with %{?selinux_requires}

Remove /%{selinuxtype} from the path to install the module.

/distributed doesn't exist in the selinux-policy hierarchy, and I've generally seen it put in /contrib instead, which does exist.

You probably want to use /contrib rather than /distributed here, as the latter doesn't exist as far as I can tell.

%verify() is redundant with %ghost and this should be macroized so %ghost entries exist for all available SELinux policy variants provided by the selinux-policy package, with the correct override number in the file path set by the other macros.

Metadata Update from @james:
- Pull-request untagged with: meeting
- Pull-request tagged with: needinfo

2 years ago

Moving this to needinfo.
mhroncok kind of volunteered to speak to everyone and try to get the changes needed in, but I don't think he's had time and it isn't moving forward in other ways.

Just as a housekeeping note/reminder, in addition to the other changes requested here by reviewers, if this were to be revived all of the links that use URLs like:

https://src.fedoraproject.org/rpms/foo/tree/master

would need to be changed to

https://src.fedoraproject.org/rpms/foo/tree/rawhide

To avoid the ugly redirect-to-default-branch banner on arrival.

This seems to assume people won't use different policy types, which is not required, nor a good idea.

When I wrote the SELinux policy for snapd, I was able to avoid those pitfalls.

Actually, "selinuxtype" is important because the policy module needs to be compiled separately for different policy types (binary policy module compiled against targeted policy will not work with mls policy). Most of the time we really only want to deploy the policy module for targeted policy, but the path we save the module files should still contain selinuxtype if this was to change (if the package started deploying versions for other policy types).

You did not avoid the pitfalls. Your policy module will not install on an "mls" or "minimum" system because of the policytype check in %selinux_modules_install. And as explained above, it would fail to install even if you used "semodule -i" directly. Also, %verify() is not redundant with %ghost. Try removing it and verifying the package after installation.

I'm sorry, but this PR has taken way too much of everyone's time and the wiki page seems to work just fine for this purpose so I'm closing it.
Thanks everyone for your reviews and notes, they have been important in finalizing the document.

Pull-Request has been closed by vmojzis

2 years ago