Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'caps-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux

Pull capabilities updates from Serge Hallyn:

- remove the cap_mmap_file() hook, as it simply returned the default
return value and so doesn't need to exist (Paul Moore)

- add a trace event for cap_capable() (Jordan Rome)

* tag 'caps-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux:
security: add trace event for cap_capable
capabilities: remove cap_mmap_file()

+99 -20
+1
MAINTAINERS
··· 5182 5182 L: linux-security-module@vger.kernel.org 5183 5183 S: Supported 5184 5184 F: include/linux/capability.h 5185 + F: include/trace/events/capability.h 5185 5186 F: include/uapi/linux/capability.h 5186 5187 F: kernel/capability.c 5187 5188 F: security/commoncap.c
+57
include/trace/events/capability.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #undef TRACE_SYSTEM 3 + #define TRACE_SYSTEM capability 4 + 5 + #if !defined(_TRACE_CAPABILITY_H) || defined(TRACE_HEADER_MULTI_READ) 6 + #define _TRACE_CAPABILITY_H 7 + 8 + #include <linux/cred.h> 9 + #include <linux/tracepoint.h> 10 + #include <linux/user_namespace.h> 11 + 12 + /** 13 + * cap_capable - called after it's determined if a task has a particular 14 + * effective capability 15 + * 16 + * @cred: The credentials used 17 + * @target_ns: The user namespace of the resource being accessed 18 + * @capable_ns: The user namespace in which the credential provides the 19 + * capability to access the targeted resource. 20 + * This will be NULL if ret is not 0. 21 + * @cap: The capability to check for 22 + * @ret: The return value of the check: 0 if it does, -ve if it does not 23 + * 24 + * Allows to trace calls to cap_capable in commoncap.c 25 + */ 26 + TRACE_EVENT(cap_capable, 27 + 28 + TP_PROTO(const struct cred *cred, struct user_namespace *target_ns, 29 + const struct user_namespace *capable_ns, int cap, int ret), 30 + 31 + TP_ARGS(cred, target_ns, capable_ns, cap, ret), 32 + 33 + TP_STRUCT__entry( 34 + __field(const struct cred *, cred) 35 + __field(struct user_namespace *, target_ns) 36 + __field(const struct user_namespace *, capable_ns) 37 + __field(int, cap) 38 + __field(int, ret) 39 + ), 40 + 41 + TP_fast_assign( 42 + __entry->cred = cred; 43 + __entry->target_ns = target_ns; 44 + __entry->capable_ns = ret == 0 ? capable_ns : NULL; 45 + __entry->cap = cap; 46 + __entry->ret = ret; 47 + ), 48 + 49 + TP_printk("cred %p, target_ns %p, capable_ns %p, cap %d, ret %d", 50 + __entry->cred, __entry->target_ns, __entry->capable_ns, __entry->cap, 51 + __entry->ret) 52 + ); 53 + 54 + #endif /* _TRACE_CAPABILITY_H */ 55 + 56 + /* This part must be outside protection */ 57 + #include <trace/define_trace.h>
+41 -20
security/commoncap.c
··· 27 27 #include <linux/mnt_idmapping.h> 28 28 #include <uapi/linux/lsm.h> 29 29 30 + #define CREATE_TRACE_POINTS 31 + #include <trace/events/capability.h> 32 + 30 33 /* 31 34 * If a non-root user executes a setuid-root binary in 32 35 * !secure(SECURE_NOROOT) mode, then we raise capabilities. ··· 53 50 } 54 51 55 52 /** 56 - * cap_capable - Determine whether a task has a particular effective capability 53 + * cap_capable_helper - Determine whether a task has a particular effective 54 + * capability. 57 55 * @cred: The credentials to use 58 - * @targ_ns: The user namespace in which we need the capability 56 + * @target_ns: The user namespace of the resource being accessed 57 + * @cred_ns: The user namespace of the credentials 59 58 * @cap: The capability to check for 60 - * @opts: Bitmask of options defined in include/linux/security.h 61 59 * 62 60 * Determine whether the nominated task has the specified capability amongst 63 61 * its effective set, returning 0 if it does, -ve if it does not. 64 62 * 65 - * NOTE WELL: cap_has_capability() cannot be used like the kernel's capable() 66 - * and has_capability() functions. That is, it has the reverse semantics: 67 - * cap_has_capability() returns 0 when a task has a capability, but the 68 - * kernel's capable() and has_capability() returns 1 for this case. 63 + * See cap_capable for more details. 69 64 */ 70 - int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, 71 - int cap, unsigned int opts) 65 + static inline int cap_capable_helper(const struct cred *cred, 66 + struct user_namespace *target_ns, 67 + const struct user_namespace *cred_ns, 68 + int cap) 72 69 { 73 - struct user_namespace *ns = targ_ns; 70 + struct user_namespace *ns = target_ns; 74 71 75 72 /* See if cred has the capability in the target user namespace 76 73 * by examining the target user namespace and all of the target ··· 78 75 */ 79 76 for (;;) { 80 77 /* Do we have the necessary capabilities? */ 81 - if (ns == cred->user_ns) 78 + if (likely(ns == cred_ns)) 82 79 return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; 83 80 84 81 /* 85 82 * If we're already at a lower level than we're looking for, 86 83 * we're done searching. 87 84 */ 88 - if (ns->level <= cred->user_ns->level) 85 + if (ns->level <= cred_ns->level) 89 86 return -EPERM; 90 87 91 88 /* 92 89 * The owner of the user namespace in the parent of the 93 90 * user namespace has all caps. 94 91 */ 95 - if ((ns->parent == cred->user_ns) && uid_eq(ns->owner, cred->euid)) 92 + if ((ns->parent == cred_ns) && uid_eq(ns->owner, cred->euid)) 96 93 return 0; 97 94 98 95 /* ··· 103 100 } 104 101 105 102 /* We never get here */ 103 + } 104 + 105 + /** 106 + * cap_capable - Determine whether a task has a particular effective capability 107 + * @cred: The credentials to use 108 + * @target_ns: The user namespace of the resource being accessed 109 + * @cap: The capability to check for 110 + * @opts: Bitmask of options defined in include/linux/security.h (unused) 111 + * 112 + * Determine whether the nominated task has the specified capability amongst 113 + * its effective set, returning 0 if it does, -ve if it does not. 114 + * 115 + * NOTE WELL: cap_has_capability() cannot be used like the kernel's capable() 116 + * and has_capability() functions. That is, it has the reverse semantics: 117 + * cap_has_capability() returns 0 when a task has a capability, but the 118 + * kernel's capable() and has_capability() returns 1 for this case. 119 + */ 120 + int cap_capable(const struct cred *cred, struct user_namespace *target_ns, 121 + int cap, unsigned int opts) 122 + { 123 + const struct user_namespace *cred_ns = cred->user_ns; 124 + int ret = cap_capable_helper(cred, target_ns, cred_ns, cap); 125 + 126 + trace_cap_capable(cred, target_ns, cred_ns, cap, ret); 127 + return ret; 106 128 } 107 129 108 130 /** ··· 1473 1445 return ret; 1474 1446 } 1475 1447 1476 - int cap_mmap_file(struct file *file, unsigned long reqprot, 1477 - unsigned long prot, unsigned long flags) 1478 - { 1479 - return 0; 1480 - } 1481 - 1482 1448 #ifdef CONFIG_SECURITY 1483 1449 1484 1450 static const struct lsm_id capability_lsmid = { ··· 1492 1470 LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), 1493 1471 LSM_HOOK_INIT(inode_getsecurity, cap_inode_getsecurity), 1494 1472 LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), 1495 - LSM_HOOK_INIT(mmap_file, cap_mmap_file), 1496 1473 LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid), 1497 1474 LSM_HOOK_INIT(task_prctl, cap_task_prctl), 1498 1475 LSM_HOOK_INIT(task_setscheduler, cap_task_setscheduler),