lsm: Refactor return value of LSM hook vm_enough_memory

To be consistent with most LSM hooks, convert the return value of
hook vm_enough_memory to 0 or a negative error code.

Before:
- Hook vm_enough_memory returns 1 if permission is granted, 0 if not.
- LSM_RET_DEFAULT(vm_enough_memory_mm) is 1.

After:
- Hook vm_enough_memory reutrns 0 if permission is granted, negative
  error code if not.
- LSM_RET_DEFAULT(vm_enough_memory_mm) is 0.

Signed-off-by: Xu Kuohai <xukuohai@huawei.com>
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
Xu Kuohai 2024-07-24 10:06:58 +08:00 committed by Paul Moore
parent 61a1dcdceb
commit be72a57527
5 changed files with 14 additions and 27 deletions

View File

@ -48,7 +48,7 @@ LSM_HOOK(int, 0, quota_on, struct dentry *dentry)
LSM_HOOK(int, 0, syslog, int type) LSM_HOOK(int, 0, syslog, int type)
LSM_HOOK(int, 0, settime, const struct timespec64 *ts, LSM_HOOK(int, 0, settime, const struct timespec64 *ts,
const struct timezone *tz) const struct timezone *tz)
LSM_HOOK(int, 1, vm_enough_memory, struct mm_struct *mm, long pages) LSM_HOOK(int, 0, 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_for_exec, struct linux_binprm *bprm)
LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, const struct file *file) LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, const struct file *file)
LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm)

View File

@ -634,7 +634,7 @@ static inline int security_settime64(const struct timespec64 *ts,
static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
{ {
return __vm_enough_memory(mm, pages, cap_vm_enough_memory(mm, pages)); return __vm_enough_memory(mm, pages, !cap_vm_enough_memory(mm, pages));
} }
static inline int security_bprm_creds_for_exec(struct linux_binprm *bprm) static inline int security_bprm_creds_for_exec(struct linux_binprm *bprm)

View File

@ -1396,17 +1396,12 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
* Determine whether the allocation of a new virtual mapping by the current * Determine whether the allocation of a new virtual mapping by the current
* task is permitted. * task is permitted.
* *
* Return: 1 if permission is granted, 0 if not. * Return: 0 if permission granted, negative error code if not.
*/ */
int cap_vm_enough_memory(struct mm_struct *mm, long pages) int cap_vm_enough_memory(struct mm_struct *mm, long pages)
{ {
int cap_sys_admin = 0; return cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
CAP_OPT_NOAUDIT);
if (cap_capable(current_cred(), &init_user_ns,
CAP_SYS_ADMIN, CAP_OPT_NOAUDIT) == 0)
cap_sys_admin = 1;
return cap_sys_admin;
} }
/** /**

View File

@ -1129,15 +1129,14 @@ int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
int rc; int rc;
/* /*
* The module will respond with a positive value if * The module will respond with 0 if it thinks the __vm_enough_memory()
* it thinks the __vm_enough_memory() call should be * call should be made with the cap_sys_admin set. If all of the modules
* made with the cap_sys_admin set. If all of the modules * agree that it should be set it will. If any module thinks it should
* agree that it should be set it will. If any module * not be set it won't.
* thinks it should not be set it won't.
*/ */
hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) { hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {
rc = hp->hook.vm_enough_memory(mm, pages); rc = hp->hook.vm_enough_memory(mm, pages);
if (rc <= 0) { if (rc < 0) {
cap_sys_admin = 0; cap_sys_admin = 0;
break; break;
} }

View File

@ -2202,23 +2202,16 @@ static int selinux_syslog(int type)
} }
/* /*
* Check that a process has enough memory to allocate a new virtual * Check permission for allocating a new virtual mapping. Returns
* mapping. 0 means there is enough memory for the allocation to * 0 if permission is granted, negative error code if not.
* succeed and -ENOMEM implies there is not.
* *
* Do not audit the selinux permission check, as this is applied to all * Do not audit the selinux permission check, as this is applied to all
* processes that allocate mappings. * processes that allocate mappings.
*/ */
static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
{ {
int rc, cap_sys_admin = 0; return cred_has_capability(current_cred(), CAP_SYS_ADMIN,
CAP_OPT_NOAUDIT, true);
rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
CAP_OPT_NOAUDIT, true);
if (rc == 0)
cap_sys_admin = 1;
return cap_sys_admin;
} }
/* binprm security operations */ /* binprm security operations */