[PATCH RFC 3/3] security: more call_int_hook_ignore_default use-cases

Paolo Abeni pabeni at redhat.com
Thu Aug 3 17:12:42 UTC 2023


The vm_enough_memory and xfrm_state_pol_flow_match behavior is somewhat
similar, as both possibly need to reconciliate multiple LSM return value
to a take a single decision. Currently xfrm_state_pol_flow_match has a
simple implementation leveraging the fact that only a LSM is supposed to
implement such hook.

This patch extend xfrm_state_pol_flow_match() to possibly cope with
multiple hooks alike what vm_enough_memory is currently doing, switch
both hooks to use the call_int_hook_ignore_default helper and change
the default hook return value to 1.

Overall the above should not lead to any functional change.

After this change, LSM returning the LSM_RET_DEFAULT value will become
a no-op for the mentioned hooks.

Signed-off-by: Paolo Abeni <pabeni at redhat.com>
---
 include/linux/lsm_hook_defs.h |  2 +-
 security/security.c           | 34 ++++++++--------------------------
 2 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 49f1f9bed958..e41ae0f90825 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -48,7 +48,7 @@ LSM_HOOK(int, 0, quota_on, struct dentry *dentry)
 LSM_HOOK(int, 0, syslog, int type)
 LSM_HOOK(int, 0, settime, const struct timespec64 *ts,
 	 const struct timezone *tz)
-LSM_HOOK(int, 0, vm_enough_memory, struct mm_struct *mm, long pages)
+LSM_HOOK(int, 1, vm_enough_memory, struct mm_struct *mm, long pages)
 LSM_HOOK(int, 0, bprm_creds_for_exec, struct linux_binprm *bprm)
 LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *file)
 LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm)
diff --git a/security/security.c b/security/security.c
index 0528cbef0624..b7b2d359c230 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1036,9 +1036,7 @@ int security_settime64(const struct timespec64 *ts, const struct timezone *tz)
  */
 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
 {
-	struct security_hook_list *hp;
-	int cap_sys_admin = 1;
-	int rc;
+	int cap_sys_admin;
 
 	/*
 	 * The module will respond with a positive value if
@@ -1047,13 +1045,8 @@ int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
 	 * agree that it should be set it will. If any module
 	 * thinks it should not be set it won't.
 	 */
-	hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {
-		rc = hp->hook.vm_enough_memory(mm, pages);
-		if (rc <= 0) {
-			cap_sys_admin = 0;
-			break;
-		}
-	}
+	cap_sys_admin = call_int_hook_ignore_default(vm_enough_memory, 1, mm,
+						     pages);
 	return __vm_enough_memory(mm, pages, cap_sys_admin);
 }
 
@@ -4922,24 +4915,13 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
 				       struct xfrm_policy *xp,
 				       const struct flowi_common *flic)
 {
-	struct security_hook_list *hp;
-	int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match);
-
 	/*
-	 * Since this function is expected to return 0 or 1, the judgment
-	 * becomes difficult if multiple LSMs supply this call. Fortunately,
-	 * we can use the first LSM's judgment because currently only SELinux
-	 * supplies this call.
-	 *
-	 * For speed optimization, we explicitly break the loop rather than
-	 * using the macro
+	 * The module will respond with a 1 value if
+	 * it thinks there is a match. If all of the modules
+	 * agree we consider the match succesfull.
 	 */
-	hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
-			     list) {
-		rc = hp->hook.xfrm_state_pol_flow_match(x, xp, flic);
-		break;
-	}
-	return rc;
+	return call_int_hook_ignore_default(xfrm_state_pol_flow_match,
+					    1, x, xp, flic);
 }
 
 /**
-- 
2.41.0



More information about the Linux-security-module-archive mailing list