diff mbox series

[V2,Notebook] How to add a new policy capability

Message ID 20220404082947.5817-1-richard_c_haines@btinternet.com (mailing list archive)
State Changes Requested
Delegated to: Paul Moore
Headers show
Series [V2,Notebook] How to add a new policy capability | expand

Commit Message

Richard Haines April 4, 2022, 8:29 a.m. UTC
Describes the steps required to add a new policy capability to:
kernel, libsepol, and policy.

Also add the ioctl_skip_cloexec capability description.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
V2 Changes:
Clarify naming conventions.
Change enums from POLICYDB_CAPABILITY to POLICYDB_CAP
Add ioctl_skip_cloexec

 src/lsm_selinux.md              |   4 +
 src/policy_config_statements.md | 139 ++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+)

Comments

Daniel Burgener April 4, 2022, 2:16 p.m. UTC | #1
On 4/4/2022 4:29 AM, Richard Haines wrote:
> Describes the steps required to add a new policy capability to:
> kernel, libsepol, and policy.
> 
> Also add the ioctl_skip_cloexec capability description.
> 
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---
> V2 Changes:
> Clarify naming conventions.
> Change enums from POLICYDB_CAPABILITY to POLICYDB_CAP
> Add ioctl_skip_cloexec
> 
>   src/lsm_selinux.md              |   4 +
>   src/policy_config_statements.md | 139 ++++++++++++++++++++++++++++++++
>   2 files changed, 143 insertions(+)
> 
> diff --git a/src/lsm_selinux.md b/src/lsm_selinux.md
> index 560d89f..2fa34dd 100644
> --- a/src/lsm_selinux.md
> +++ b/src/lsm_selinux.md
> @@ -712,6 +712,10 @@ or *libsepol* library.
>   - Enables fine-grained labeling of symlinks in pseudo filesystems based
>     on *genfscon* rules.
>   
> +*policy_capabilities/ioctl_skip_cloexec*
> +
> +- If true always allow FIOCLEX and FIONCLEXE ioctl permissions (from kernel 5.18).
> +
>   *policy_capabilities/network_peer_controls*
>   
>   - If true the following *network_peer_controls* are enabled:
> diff --git a/src/policy_config_statements.md b/src/policy_config_statements.md
> index d4eee48..90bf440 100644
> --- a/src/policy_config_statements.md
> +++ b/src/policy_config_statements.md
> @@ -1,5 +1,12 @@
>   # Policy Configuration Statements
>   
> +- [*policycap*](#policycap)
> +  - [Adding A New Policy Capability](#adding-a-new-policy-capability)
> +    - [Kernel Updates](#kernel-updates)
> +    - [*libsepol* Library Updates](#libsepol-library-updates)
> +    - [Reference Policy Updates](#reference-policy-updates)
> +    - [CIL Policy Updates](#cil-policy-updates)
> +
>   ## *policycap*
>   
>   Policy version 22 introduced the *policycap* statement to allow new
> @@ -47,6 +54,138 @@ Conditional Policy Statements
>   policycap network_peer_controls;
>   ```
>   
> +## Adding A New Policy Capability
> +
> +The kernel, userspace libsepol library and policy must be updated to enable
> +the new capability as described below. For readability, the new capability
> +should follow a consistent naming convention, where:
> +
> +- policy capability identifier is a lower-case string.
> +- enum definition is ```POLICYDB_CAP_``` with the indentifier appended in
> +  upper-case.
> +- kernel function call is ```selinux_policycap_``` with the indentifier
> +  appended in lower-case.

Second and third bullets have a typo of "indentifier" instead of 
"identifier"

> +
> +### Kernel Updates
> +
> +In kernel source update the following three files with the new capability:
> +
> +***security/selinux/include/policycap_names.h***
> +
> +Add new entry at end of this list:
> +
> +```
> +/* Policy capability names */
> +const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = {
> +	...
> +	"genfs_seclabel_symlinks",
> +	"ioctl_skip_cloexec",
> +	"new_name"
> +};
> +```
> +
> +***security/selinux/include/policycap.h***
> +
> +Add new entry at end of this list:
> +
> +```
> +/* Policy capabilities */
> +enum {
> +	...
> +	POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
> +	POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
> +	POLICYDB_CAP_NEW_NAME,
> +	__POLICYDB_CAP_MAX
> +};
> +```
> +
> +***security/selinux/include/security.h***
> +
> +Add a new call to retrieve the loaded policy capability state:
> +
> +```
> +static inline bool selinux_policycap_new_name(void)
> +{
> +	struct selinux_state *state = &selinux_state;
> +
> +	return READ_ONCE(state->policycap[POLICYDB_CAP_NEW_NAME]);
> +}
> +```
> +
> +Finally in the updated code that utilises the new policy capability do
> +something like:
> +
> +```
> +if (selinux_policycap_new_name())
> +	do this;
> +else
> +	do that;
> +```
> +
> +### *libsepol* Library Updates
> +
> +In selinux userspace source update the following two files with the new
> +capability:
> +
> +***selinux/libsepol/src/polcaps.c***
> +
> +Add new entry at end of this list:
> +
> +```
> +static const char * const polcap_names[] = {
> +	...
> +	"genfs_seclabel_symlinks",	/* POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS */
> +	"ioctl_skip_cloexec",		/* POLICYDB_CAP_IOCTL_SKIP_CLOEXEC */
> +	"new_name",			/* POLICYDB_CAP_NEW_NAME */
> +	NULL
> +};
> +```
> +
> +***selinux/libsepol/include/sepol/policydb/polcaps.h***
> +
> +Add new entry at end of this list:
> +
> +```
> +/* Policy capabilities */
> +enum {
> +	...
> +	POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
> +	POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
> +	POLICYDB_CAP_NEW_NAME,
> +	__POLICYDB_CAP_MAX
> +};
> +```
> +
> +### Reference Policy Updates
> +
> +The new policy capability identifier is then added to the Reference Policy file:

This should probably be written as a directive to match the other 
instructions rather than in passive voice?

> +
> +***policy/policy_capabilities***
> +
> +To enable the capability in policy:
> +
> +```
> +# A description of the capability
> +policycap new_name;
> +```
> +
> +To disable the capability comment out the entry:

nit: I'd put a comma after capability

> +
> +```
> +# A description of the capability
> +#policycap new_name;
> +```
> +
> +### CIL Policy Updates
> +
> +To enable the capability in policy, add the following entry to a CIL
> +source file:
> +
> +```
> +; A description of the capability
> +(policycap new_name)
> +```
> +
>   <!-- %CUTHERE% -->
>   
>   ---
diff mbox series

Patch

diff --git a/src/lsm_selinux.md b/src/lsm_selinux.md
index 560d89f..2fa34dd 100644
--- a/src/lsm_selinux.md
+++ b/src/lsm_selinux.md
@@ -712,6 +712,10 @@  or *libsepol* library.
 - Enables fine-grained labeling of symlinks in pseudo filesystems based
   on *genfscon* rules.
 
+*policy_capabilities/ioctl_skip_cloexec*
+
+- If true always allow FIOCLEX and FIONCLEXE ioctl permissions (from kernel 5.18).
+
 *policy_capabilities/network_peer_controls*
 
 - If true the following *network_peer_controls* are enabled:
diff --git a/src/policy_config_statements.md b/src/policy_config_statements.md
index d4eee48..90bf440 100644
--- a/src/policy_config_statements.md
+++ b/src/policy_config_statements.md
@@ -1,5 +1,12 @@ 
 # Policy Configuration Statements
 
+- [*policycap*](#policycap)
+  - [Adding A New Policy Capability](#adding-a-new-policy-capability)
+    - [Kernel Updates](#kernel-updates)
+    - [*libsepol* Library Updates](#libsepol-library-updates)
+    - [Reference Policy Updates](#reference-policy-updates)
+    - [CIL Policy Updates](#cil-policy-updates)
+
 ## *policycap*
 
 Policy version 22 introduced the *policycap* statement to allow new
@@ -47,6 +54,138 @@  Conditional Policy Statements
 policycap network_peer_controls;
 ```
 
+## Adding A New Policy Capability
+
+The kernel, userspace libsepol library and policy must be updated to enable
+the new capability as described below. For readability, the new capability
+should follow a consistent naming convention, where:
+
+- policy capability identifier is a lower-case string.
+- enum definition is ```POLICYDB_CAP_``` with the indentifier appended in
+  upper-case.
+- kernel function call is ```selinux_policycap_``` with the indentifier
+  appended in lower-case.
+
+### Kernel Updates
+
+In kernel source update the following three files with the new capability:
+
+***security/selinux/include/policycap_names.h***
+
+Add new entry at end of this list:
+
+```
+/* Policy capability names */
+const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = {
+	...
+	"genfs_seclabel_symlinks",
+	"ioctl_skip_cloexec",
+	"new_name"
+};
+```
+
+***security/selinux/include/policycap.h***
+
+Add new entry at end of this list:
+
+```
+/* Policy capabilities */
+enum {
+	...
+	POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
+	POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
+	POLICYDB_CAP_NEW_NAME,
+	__POLICYDB_CAP_MAX
+};
+```
+
+***security/selinux/include/security.h***
+
+Add a new call to retrieve the loaded policy capability state:
+
+```
+static inline bool selinux_policycap_new_name(void)
+{
+	struct selinux_state *state = &selinux_state;
+
+	return READ_ONCE(state->policycap[POLICYDB_CAP_NEW_NAME]);
+}
+```
+
+Finally in the updated code that utilises the new policy capability do
+something like:
+
+```
+if (selinux_policycap_new_name())
+	do this;
+else
+	do that;
+```
+
+### *libsepol* Library Updates
+
+In selinux userspace source update the following two files with the new
+capability:
+
+***selinux/libsepol/src/polcaps.c***
+
+Add new entry at end of this list:
+
+```
+static const char * const polcap_names[] = {
+	...
+	"genfs_seclabel_symlinks",	/* POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS */
+	"ioctl_skip_cloexec",		/* POLICYDB_CAP_IOCTL_SKIP_CLOEXEC */
+	"new_name",			/* POLICYDB_CAP_NEW_NAME */
+	NULL
+};
+```
+
+***selinux/libsepol/include/sepol/policydb/polcaps.h***
+
+Add new entry at end of this list:
+
+```
+/* Policy capabilities */
+enum {
+	...
+	POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
+	POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
+	POLICYDB_CAP_NEW_NAME,
+	__POLICYDB_CAP_MAX
+};
+```
+
+### Reference Policy Updates
+
+The new policy capability identifier is then added to the Reference Policy file:
+
+***policy/policy_capabilities***
+
+To enable the capability in policy:
+
+```
+# A description of the capability
+policycap new_name;
+```
+
+To disable the capability comment out the entry:
+
+```
+# A description of the capability
+#policycap new_name;
+```
+
+### CIL Policy Updates
+
+To enable the capability in policy, add the following entry to a CIL
+source file:
+
+```
+; A description of the capability
+(policycap new_name)
+```
+
 <!-- %CUTHERE% -->
 
 ---