hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/security/commoncap.c
....@@ -1,15 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Common capabilities, needed by capability.o.
2
- *
3
- * This program is free software; you can redistribute it and/or modify
4
- * it under the terms of the GNU General Public License as published by
5
- * the Free Software Foundation; either version 2 of the License, or
6
- * (at your option) any later version.
7
- *
83 */
94
105 #include <linux/capability.h>
116 #include <linux/audit.h>
12
-#include <linux/module.h>
137 #include <linux/init.h>
148 #include <linux/kernel.h>
159 #include <linux/lsm_hooks.h>
....@@ -58,7 +52,7 @@
5852 * @cred: The credentials to use
5953 * @ns: The user namespace in which we need the capability
6054 * @cap: The capability to check for
61
- * @audit: Whether to write an audit message or not
55
+ * @opts: Bitmask of options defined in include/linux/security.h
6256 *
6357 * Determine whether the nominated task has the specified capability amongst
6458 * its effective set, returning 0 if it does, -ve if it does not.
....@@ -303,7 +297,8 @@
303297 struct inode *inode = d_backing_inode(dentry);
304298 int error;
305299
306
- error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
300
+ error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0,
301
+ XATTR_NOSECURITY);
307302 return error > 0;
308303 }
309304
....@@ -397,8 +392,10 @@
397392 &tmpbuf, size, GFP_NOFS);
398393 dput(dentry);
399394
400
- if (ret < 0 || !tmpbuf)
401
- return ret;
395
+ if (ret < 0 || !tmpbuf) {
396
+ size = ret;
397
+ goto out_free;
398
+ }
402399
403400 fs_ns = inode->i_sb->s_user_ns;
404401 cap = (struct vfs_cap_data *) tmpbuf;
....@@ -611,7 +608,8 @@
611608
612609 fs_ns = inode->i_sb->s_user_ns;
613610 size = __vfs_getxattr((struct dentry *)dentry, inode,
614
- XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ);
611
+ XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ,
612
+ XATTR_NOSECURITY);
615613 if (size == -ENODATA || size == -EOPNOTSUPP)
616614 /* no data, that's ok */
617615 return -ENODATA;
....@@ -662,6 +660,8 @@
662660 cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
663661 cpu_caps->inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
664662
663
+ cpu_caps->rootid = rootkuid;
664
+
665665 return 0;
666666 }
667667
....@@ -670,7 +670,8 @@
670670 * its xattrs and, if present, apply them to the proposed credentials being
671671 * constructed by execve().
672672 */
673
-static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_fcap)
673
+static int get_file_caps(struct linux_binprm *bprm, struct file *file,
674
+ bool *effective, bool *has_fcap)
674675 {
675676 int rc = 0;
676677 struct cpu_vfs_cap_data vcaps;
....@@ -680,7 +681,7 @@
680681 if (!file_caps_enabled)
681682 return 0;
682683
683
- if (!mnt_may_suid(bprm->file->f_path.mnt))
684
+ if (!mnt_may_suid(file->f_path.mnt))
684685 return 0;
685686
686687 /*
....@@ -688,10 +689,10 @@
688689 * explicit that capability bits are limited to s_user_ns and its
689690 * descendants.
690691 */
691
- if (!current_in_userns(bprm->file->f_path.mnt->mnt_sb->s_user_ns))
692
+ if (!current_in_userns(file->f_path.mnt->mnt_sb->s_user_ns))
692693 return 0;
693694
694
- rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
695
+ rc = get_vfs_caps_from_disk(file->f_path.dentry, &vcaps);
695696 if (rc < 0) {
696697 if (rc == -EINVAL)
697698 printk(KERN_NOTICE "Invalid argument reading file caps for %s\n",
....@@ -702,9 +703,6 @@
702703 }
703704
704705 rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_fcap);
705
- if (rc == -EINVAL)
706
- printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
707
- __func__, rc, bprm->filename);
708706
709707 out:
710708 if (rc)
....@@ -823,26 +821,27 @@
823821 }
824822
825823 /**
826
- * cap_bprm_set_creds - Set up the proposed credentials for execve().
824
+ * cap_bprm_creds_from_file - Set up the proposed credentials for execve().
827825 * @bprm: The execution parameters, including the proposed creds
826
+ * @file: The file to pull the credentials from
828827 *
829828 * Set up the proposed credentials for a new execution context being
830829 * constructed by execve(). The proposed creds in @bprm->cred is altered,
831830 * which won't take effect immediately. Returns 0 if successful, -ve on error.
832831 */
833
-int cap_bprm_set_creds(struct linux_binprm *bprm)
832
+int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
834833 {
834
+ /* Process setpcap binaries and capabilities for uid 0 */
835835 const struct cred *old = current_cred();
836836 struct cred *new = bprm->cred;
837837 bool effective = false, has_fcap = false, is_setid;
838838 int ret;
839839 kuid_t root_uid;
840840
841
- new->cap_ambient = old->cap_ambient;
842841 if (WARN_ON(!cap_ambient_invariant_ok(old)))
843842 return -EPERM;
844843
845
- ret = get_file_caps(bprm, &effective, &has_fcap);
844
+ ret = get_file_caps(bprm, file, &effective, &has_fcap);
846845 if (ret < 0)
847846 return ret;
848847
....@@ -911,12 +910,11 @@
911910 return -EPERM;
912911
913912 /* Check for privilege-elevated exec. */
914
- bprm->cap_elevated = 0;
915913 if (is_setid ||
916914 (!__is_real(root_uid, new) &&
917915 (effective ||
918916 __cap_grew(permitted, ambient, new))))
919
- bprm->cap_elevated = 1;
917
+ bprm->secureexec = 1;
920918
921919 return 0;
922920 }
....@@ -942,7 +940,7 @@
942940
943941 /* Ignore non-security xattrs */
944942 if (strncmp(name, XATTR_SECURITY_PREFIX,
945
- sizeof(XATTR_SECURITY_PREFIX) - 1) != 0)
943
+ XATTR_SECURITY_PREFIX_LEN) != 0)
946944 return 0;
947945
948946 /*
....@@ -974,7 +972,7 @@
974972
975973 /* Ignore non-security xattrs */
976974 if (strncmp(name, XATTR_SECURITY_PREFIX,
977
- sizeof(XATTR_SECURITY_PREFIX) - 1) != 0)
975
+ XATTR_SECURITY_PREFIX_LEN) != 0)
978976 return 0;
979977
980978 if (strcmp(name, XATTR_NAME_CAPS) == 0) {
....@@ -1366,14 +1364,14 @@
13661364
13671365 #ifdef CONFIG_SECURITY
13681366
1369
-struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
1367
+static struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
13701368 LSM_HOOK_INIT(capable, cap_capable),
13711369 LSM_HOOK_INIT(settime, cap_settime),
13721370 LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
13731371 LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
13741372 LSM_HOOK_INIT(capget, cap_capget),
13751373 LSM_HOOK_INIT(capset, cap_capset),
1376
- LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
1374
+ LSM_HOOK_INIT(bprm_creds_from_file, cap_bprm_creds_from_file),
13771375 LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
13781376 LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
13791377 LSM_HOOK_INIT(inode_getsecurity, cap_inode_getsecurity),
....@@ -1387,10 +1385,17 @@
13871385 LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory),
13881386 };
13891387
1390
-void __init capability_add_hooks(void)
1388
+static int __init capability_init(void)
13911389 {
13921390 security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks),
13931391 "capability");
1392
+ return 0;
13941393 }
13951394
1395
+DEFINE_LSM(capability) = {
1396
+ .name = "capability",
1397
+ .order = LSM_ORDER_FIRST,
1398
+ .init = capability_init,
1399
+};
1400
+
13961401 #endif /* CONFIG_SECURITY */