From Fedora Project Wiki
 
(17 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{admon/important | Comments and Explanations | The page source contains comments providing guidance to fill out each section. They are invisible when viewing this page. To read it, choose the "view source" link.<br/> '}}
 
 
{{admon/tip | Guidance | For details on how to fill out this form, see the [https://docs.fedoraproject.org/en-US/program_management/changes_guide/ documentation].}}
 
 
 
<!-- The actual name of your proposed change page should look something like: Changes/Your_Change_Proposal_Name.  This keeps all change proposals in the same namespace -->
 
<!-- The actual name of your proposed change page should look something like: Changes/Your_Change_Proposal_Name.  This keeps all change proposals in the same namespace -->
  
Disable CONFIG_SECURITY_SELINUX_DISABLE<!-- The name of your change proposal --> =
+
Remove support for SELinux runtime disable<!-- The name of your change proposal --> =
  
 
== Summary ==
 
== Summary ==
Line 11: Line 7:
 
Note that motivation for the change should be in the Benefit to Fedora section below, and this part should answer the question "What?" rather than "Why?". -->
 
Note that motivation for the change should be in the Benefit to Fedora section below, and this part should answer the question "What?" rather than "Why?". -->
  
Build kernel without CONFIG_SECURITY_SELINUX_DISABLE, disable writing to a selinuxfs node 'disable' and disable SELinux to be disabled at runtime prior to the policy load. Kernel build without CONFIG_SECURITY_SELINUX_DISABLE can use the '__ro_after_init' kernel hardening feature for security hooks.
+
Remove support for SELinux runtime disable so that [https://www.kernel.org/doc/html/latest/security/lsm.html the LSM hooks] can be hardened via [https://lore.kernel.org/kernel-hardening/1448494286-16029-1-git-send-email-keescook@chromium.org/ read-only-after-initialization] protections.
 +
 
 +
Migrate users to using ''selinux=0'' on the kernel command line if they want to disable SELinux.
 +
 
 +
NOTE: By "disabling SELinux" here we mean that the kernel doesn't call into the SELinux subsystem at all. Switching SELinux between "permissive" and "enforcing" mode using ''setenforce(8)'' (which is often incorrectly called "disabling/enabling SELinux") is not affected and will remain fully functional. There is a nice [https://wiki.gentoo.org/wiki/SELinux/Tutorials/Permissive_versus_enforcing article] on Gentoo wiki explaining the SELinux modes in more detail.
 +
 
 +
<!--
 +
Build kernel without CONFIG_SECURITY_SELINUX_DISABLE, disable writing to a selinuxfs node ''disable'' and disable SELinux to be disabled at runtime prior to the policy load. Kernel build without CONFIG_SECURITY_SELINUX_DISABLE can use the ''__ro_after_init'' kernel hardening feature for security hooks.
 +
-->
  
 
== Owner ==
 
== Owner ==
Line 34: Line 38:
  
 
== Current status ==
 
== Current status ==
[[Category:ChangePageIncomplete]]
+
[[Category:ChangeAnnounced]]
<!-- When your change proposal page is completed and ready for review and announcement -->
 
<!-- remove Category:ChangePageIncomplete and change it to Category:ChangeReadyForWrangler -->
 
<!-- The Wrangler announces the Change to the devel-announce list and changes the category to Category:ChangeAnnounced (no action required) -->
 
<!-- After review, the Wrangler will move your page to Category:ChangeReadyForFesco... if it still needs more work it will move back to Category:ChangePageIncomplete-->
 
 
 
<!-- Select proper category, default is Self Contained Change -->
 
<!-- [[Category:SelfContainedChange]] -->
 
 
[[Category:SystemWideChange]]
 
[[Category:SystemWideChange]]
  
Line 61: Line 58:
 
<!-- Expand on the summary, if appropriate.  A couple sentences suffices to explain the goal, but the more details you can provide the better. -->
 
<!-- Expand on the summary, if appropriate.  A couple sentences suffices to explain the goal, but the more details you can provide the better. -->
  
CONFIG_SECURITY_SELINUX_DISABLE functionality was originally developed to make it easier for Linux distributions to support architectures where adding parameters to the kernel command line was difficult.
+
Currently, SELinux can be disabled using ''selinux=0'' on the kernel command line, or in userspace via ''/etc/selinux/config''.
Unfortunately, supporting runtime disable meant we had to make some security trade-offs when it came to the LSM hooks.  
+
In the latter case, ''/etc/selinux/config'' is read by libselinux userspace library during boot and if it contains ''SELINUX=disabled'', it writes ''1'' into ''/sys/fs/selinux/disable'' and unmounts ''/sys/fs/selinux''.
  
Marking the LSM hooks as read only provides some very nice security benefits, but it does mean that we can no longer disable SELinux at runtime.
+
Support for SELinux runtime disable via ''/etc/selinux/config'' was originally developed to make it easier for Linux distributions to support architectures where adding parameters to the kernel command line was difficult.
Toggling between enforcing and permissive mode while booted will remain unaffected and it will still be possible to disable SELinux by adding "selinux=0" to the kernel command line via the boot loader (GRUB).
+
Unfortunately, supporting runtime disable meant we had to make some security trade-offs when it comes to the kernel LSM hooks.
 +
 
 +
Marking the kernel LSM hooks as read only provides some very nice security benefits, but it does mean that we can no longer disable SELinux at runtime.
 +
Toggling between enforcing and permissive mode while booted will remain unaffected and it will still be possible to disable SELinux by adding ''selinux=0'' to the kernel command line via the boot loader (GRUB).
 
   
 
   
System with SELINUX=disabled in /etc/selinux/config will come up with selinuxfs unmounted,
+
System with ''SELINUX=disabled'' in ''/etc/selinux/config'' will come up with ''/sys/fs/selinux'' unmounted,
userspace will think SELinux is disabled, but internally SELinux will be enabled with no policy so that there will be no SELinux checks applied.
+
userspace will detect SELinux as disabled. Internally SELinux will be enabled but not initialized so that there will be no SELinux checks applied.  This state is very similar to SELinux disabled - the hooks are active, but they mostly do almost nothing so there should be very little effect on the time spent in syscalls compared to SELinux fully disabled.
  
NOTE: Runtime disable is considered as deprecated, and using it will become increasingly painful (e.g. sleeping/blocking) through future kernel releases until eventually it is removed completely.
+
Runtime disable is considered deprecated by upstream, and using it will become increasingly painful (e.g. sleeping/blocking) through future kernel releases until eventually it is removed completely.
Current kernel reports the following message during runtime disable: "SELinux:  Runtime disable is deprecated, use selinux=0 on the kernel cmdline"
+
Current kernel reports the following message during runtime disable: ''SELinux:  Runtime disable is deprecated, use selinux=0 on the kernel cmdline''
  
 
Additional info:
 
Additional info:
Line 113: Line 113:
 
-->
 
-->
  
Marking the LSM hooks as read only provides some very nice security benefits, e.g. in case an attacker gains ability to write to certain kernel memory regions, they have a bigger chance of using side effects of CONFIG_SECURITY_SELINUX_DISABLE to turn off SELinux permission checking.
+
Marking the LSM hooks as read-only provides extra security hardening against certain attacks, e.g. in case an attacker gains ability to write to random kernel memory locations, with support for disable SELinux runtime (''CONFIG_SECURITY_SELINUX_DISABLE=y'') they have a bigger chance to turn off (parts of) SELinux permission checking.
  
 
== Scope ==
 
== Scope ==
 
* Proposal owners:
 
* Proposal owners:
 
<!-- What work do the feature owners have to accomplish to complete the feature in time for release?  Is it a large change affecting many parts of the distribution or is it a very isolated change? What are those changes?-->
 
<!-- What work do the feature owners have to accomplish to complete the feature in time for release?  Is it a large change affecting many parts of the distribution or is it a very isolated change? What are those changes?-->
 +
** Make sure the kernel is built with ''CONFIG_SECURITY_SELINUX_DISABLE'' disabled.
 +
** Make sure the relevant documentation is updated in a way that ''selinux=0'' on kernel command line is the preferred way to disable SELinux.
 +
*** https://docs.fedoraproject.org/en-US/quick-docs/changing-selinux-states-and-modes/
 +
*** ''selinux(8)'' man page
 +
** Make sure [https://github.com/rhinstaller/anaconda/ the installer] uses the kernel command line instead of ''/etc/selinux/config'' to disable SELinux.
 +
** Optional: [https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/selinux.py ''selinux'' Ansible module] should warn that SELinux needs to be disabled using ''selinux=0''.
 +
** Optional: [https://github.com/linux-system-roles/selinux linux-system-roles.selinux] should disable SELinux using ''selinux=0''.
  
Make sure kernel is built without CONFIG_SECURITY_SELINUX_DISABLE
+
* Other developers: N/A <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
 
* Other developers: N/A (not a System Wide Change) <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
 
<!-- What work do other developers have to accomplish to complete the feature in time for release?  Is it a large change affecting many parts of the distribution or is it a very isolated change? What are those changes?-->
 
<!-- What work do other developers have to accomplish to complete the feature in time for release?  Is it a large change affecting many parts of the distribution or is it a very isolated change? What are those changes?-->
  
* Release engineering: [https://pagure.io/releng/issues #Releng issue number] (a check of an impact with Release Engineering is needed) <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
+
* Release engineering: [https://pagure.io/releng/issue/9742 #9742] (a check of an impact with Release Engineering is needed) <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
<!-- Does this feature require coordination with release engineering (e.g. changes to installer image generation or update package delivery)?  Is a mass rebuild required?  include a link to the releng issue.  
 
<!-- Does this feature require coordination with release engineering (e.g. changes to installer image generation or update package delivery)?  Is a mass rebuild required?  include a link to the releng issue.  
 
The issue is required to be filed prior to feature submission, to ensure that someone is on board to do any process development work and testing and that all changes make it into the pipeline; a bullet point in a change is not sufficient communication -->
 
The issue is required to be filed prior to feature submission, to ensure that someone is on board to do any process development work and testing and that all changes make it into the pipeline; a bullet point in a change is not sufficient communication -->
  
* Policies and guidelines: N/A (not a System Wide Change) <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
+
* Policies and guidelines: N/A <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
<!-- Do the packaging guidelines or other documents need to be updated for this feature?  If so, does it need to happen before or after the implementation is done?  If a FPC ticket exists, add a link here. -->
 
<!-- Do the packaging guidelines or other documents need to be updated for this feature?  If so, does it need to happen before or after the implementation is done?  If a FPC ticket exists, add a link here. -->
  
Line 137: Line 142:
 
<!-- What happens to systems that have had a previous versions of Fedora installed and are updated to the version containing this change? Will anything require manual configuration or data migration? Will any existing functionality be no longer supported? -->
 
<!-- What happens to systems that have had a previous versions of Fedora installed and are updated to the version containing this change? Will anything require manual configuration or data migration? Will any existing functionality be no longer supported? -->
  
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
+
Users should not be directly affected by this change.
N/A (not a System Wide Change)
 
 
 
Users should not directly affected by this change.
 
  
 
== How To Test ==
 
== How To Test ==
Line 158: Line 160:
  
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
N/A (not a System Wide Change)
+
 
 +
# Install a kernel built with ''CONFIG_SECURITY_SELINUX_DISABLE'' disabled, e.g. from https://copr.fedorainfracloud.org/coprs/omos/drop-selinux-disable/.
 +
# Confirm that SELinux is disabled when ''selinux=0'' is used on kernel command line.
 +
# Confirm that userspace considers SELinux disabled when ''SELINUX=disabled'' is used in ''/etc/selinux/config''.
 +
# Confirm that userspace considers SELinux disabled when there is no ''/etc/selinux/config''.
 +
# Confirm that the system works as expected in all previous cases.
  
 
== User Experience ==
 
== User Experience ==
Line 174: Line 181:
 
There's no visible change for users with SELinux enabled.
 
There's no visible change for users with SELinux enabled.
  
Users with SELINUX=disabled in /etc/selinux/config and without selinux=0 on kernel command line might notice that `ps Z` command uses 'kernel' domain for processes instead of '-'.
+
Users with ''SELINUX=disabled'' in ''/etc/selinux/config'' and without ''selinux=0'' on kernel command line might notice that `ps Z` command uses ''kernel'' domain for processes, while with ''selinux=0'' `ps Z` prints '-'.
These users will be also able to load SELinux policy after boot.
+
These users will also be able to load SELinux policy after boot.
  
 
== Dependencies ==
 
== Dependencies ==
Line 181: Line 188:
  
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
N/A (not a System Wide Change)
+
Upstream kernel SELinux subsystem waits for this change in order to remove CONFIG_SECURITY_SELINUX_DISABLE functionality - https://lore.kernel.org/selinux/157836784986.560897.13893922675143903084.stgit@chester/#t
  
 
== Contingency Plan ==
 
== Contingency Plan ==
  
 
<!-- If you cannot complete your feature by the final development freeze, what is the backup plan?  This might be as simple as "Revert the shipped configuration".  Or it might not (e.g. rebuilding a number of dependent packages).  If you feature is not completed in time we want to assure others that other parts of Fedora will not be in jeopardy.  -->
 
<!-- If you cannot complete your feature by the final development freeze, what is the backup plan?  This might be as simple as "Revert the shipped configuration".  Or it might not (e.g. rebuilding a number of dependent packages).  If you feature is not completed in time we want to assure others that other parts of Fedora will not be in jeopardy.  -->
* Contingency mechanism: (What to do? Who will do it?) N/A (not a System Wide Change)  <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
+
* Contingency mechanism:  Revert the kernel build option change and build kernel with ''CONFIG_SECURITY_SELINUX_DISABLE=y''
 
<!-- When is the last time the contingency mechanism can be put in place?  This will typically be the beta freeze. -->
 
<!-- When is the last time the contingency mechanism can be put in place?  This will typically be the beta freeze. -->
* Contingency deadline: N/A (not a System Wide Change)  <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
+
* Contingency deadline: Beta freeze
 
<!-- Does finishing this feature block the release, or can we ship with the feature in incomplete state? -->
 
<!-- Does finishing this feature block the release, or can we ship with the feature in incomplete state? -->
* Blocks release? N/A (not a System Wide Change), Yes/No <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
+
* Blocks release? No
* Blocks product? product <!-- Applicable for Changes that blocks specific product release/Fedora.next -->
+
<!-- * Blocks product? product Applicable for Changes that blocks specific product release/Fedora.next -->
  
 
== Documentation ==
 
== Documentation ==
Line 197: Line 204:
  
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
N/A (not a System Wide Change)
+
TBD
  
 
== Release Notes ==
 
== Release Notes ==
Line 205: Line 212:
 
Release Notes are not required for initial draft of the Change Proposal but has to be completed by the Change Freeze.  
 
Release Notes are not required for initial draft of the Change Proposal but has to be completed by the Change Freeze.  
 
-->
 
-->
 +
 +
TBD

Latest revision as of 14:29, 10 September 2020


Remove support for SELinux runtime disable

Summary

Remove support for SELinux runtime disable so that the LSM hooks can be hardened via read-only-after-initialization protections.

Migrate users to using selinux=0 on the kernel command line if they want to disable SELinux.

NOTE: By "disabling SELinux" here we mean that the kernel doesn't call into the SELinux subsystem at all. Switching SELinux between "permissive" and "enforcing" mode using setenforce(8) (which is often incorrectly called "disabling/enabling SELinux") is not affected and will remain fully functional. There is a nice article on Gentoo wiki explaining the SELinux modes in more detail.


Owner


Current status

  • Targeted release: Fedora 34
  • Last updated: 2020-09-10
  • FESCo issue: <will be assigned by the Wrangler>
  • Tracker bug: <will be assigned by the Wrangler>
  • Release notes tracker: <will be assigned by the Wrangler>

Detailed Description

Currently, SELinux can be disabled using selinux=0 on the kernel command line, or in userspace via /etc/selinux/config. In the latter case, /etc/selinux/config is read by libselinux userspace library during boot and if it contains SELINUX=disabled, it writes 1 into /sys/fs/selinux/disable and unmounts /sys/fs/selinux.

Support for SELinux runtime disable via /etc/selinux/config was originally developed to make it easier for Linux distributions to support architectures where adding parameters to the kernel command line was difficult. Unfortunately, supporting runtime disable meant we had to make some security trade-offs when it comes to the kernel LSM hooks.

Marking the kernel LSM hooks as read only provides some very nice security benefits, but it does mean that we can no longer disable SELinux at runtime. Toggling between enforcing and permissive mode while booted will remain unaffected and it will still be possible to disable SELinux by adding selinux=0 to the kernel command line via the boot loader (GRUB).

System with SELINUX=disabled in /etc/selinux/config will come up with /sys/fs/selinux unmounted, userspace will detect SELinux as disabled. Internally SELinux will be enabled but not initialized so that there will be no SELinux checks applied. This state is very similar to SELinux disabled - the hooks are active, but they mostly do almost nothing so there should be very little effect on the time spent in syscalls compared to SELinux fully disabled.

Runtime disable is considered deprecated by upstream, and using it will become increasingly painful (e.g. sleeping/blocking) through future kernel releases until eventually it is removed completely. Current kernel reports the following message during runtime disable: SELinux: Runtime disable is deprecated, use selinux=0 on the kernel cmdline

Additional info:

Feedback

Benefit to Fedora

Marking the LSM hooks as read-only provides extra security hardening against certain attacks, e.g. in case an attacker gains ability to write to random kernel memory locations, with support for disable SELinux runtime (CONFIG_SECURITY_SELINUX_DISABLE=y) they have a bigger chance to turn off (parts of) SELinux permission checking.

Scope

  • Other developers: N/A
  • Release engineering: #9742 (a check of an impact with Release Engineering is needed)
  • Policies and guidelines: N/A
  • Trademark approval: N/A (not needed for this Change)

Upgrade/compatibility impact

Users should not be directly affected by this change.

How To Test

  1. Install a kernel built with CONFIG_SECURITY_SELINUX_DISABLE disabled, e.g. from https://copr.fedorainfracloud.org/coprs/omos/drop-selinux-disable/.
  2. Confirm that SELinux is disabled when selinux=0 is used on kernel command line.
  3. Confirm that userspace considers SELinux disabled when SELINUX=disabled is used in /etc/selinux/config.
  4. Confirm that userspace considers SELinux disabled when there is no /etc/selinux/config.
  5. Confirm that the system works as expected in all previous cases.

User Experience

There's no visible change for users with SELinux enabled.

Users with SELINUX=disabled in /etc/selinux/config and without selinux=0 on kernel command line might notice that ps Z command uses kernel domain for processes, while with selinux=0 ps Z prints '-'. These users will also be able to load SELinux policy after boot.

Dependencies

Upstream kernel SELinux subsystem waits for this change in order to remove CONFIG_SECURITY_SELINUX_DISABLE functionality - https://lore.kernel.org/selinux/157836784986.560897.13893922675143903084.stgit@chester/#t

Contingency Plan

  • Contingency mechanism: Revert the kernel build option change and build kernel with CONFIG_SECURITY_SELINUX_DISABLE=y
  • Contingency deadline: Beta freeze
  • Blocks release? No

Documentation

TBD

Release Notes

TBD