security/safesetid/lsm.c
Source file repositories/reference/linux-study-clean/security/safesetid/lsm.c
File Facts
- System
- Linux kernel
- Corpus path
security/safesetid/lsm.c- Extension
.c- Size
- 8875 bytes
- Lines
- 294
- Domain
- Core OS
- Bucket
- Security And Isolation
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/lsm_hooks.hlinux/module.hlinux/ptrace.hlinux/sched/task_stack.hlinux/security.huapi/linux/lsm.hlsm.h
Detected Declarations
function _setid_policy_lookupfunction hash_for_each_possiblefunction setid_policy_lookupfunction safesetid_security_capablefunction id_permitted_for_credfunction setid_policy_lookupfunction safesetid_task_fix_setuidfunction safesetid_task_fix_setgidfunction safesetid_task_fix_setgroupsfunction safesetid_security_init
Annotated Snippet
hash_for_each_possible(policy->rules, rule, next, __kuid_val(src.uid)) {
if (!uid_eq(rule->src_id.uid, src.uid))
continue;
if (uid_eq(rule->dst_id.uid, dst.uid))
return SIDPOL_ALLOWED;
result = SIDPOL_CONSTRAINED;
}
} else if (policy->type == GID) {
hash_for_each_possible(policy->rules, rule, next, __kgid_val(src.gid)) {
if (!gid_eq(rule->src_id.gid, src.gid))
continue;
if (gid_eq(rule->dst_id.gid, dst.gid)){
return SIDPOL_ALLOWED;
}
result = SIDPOL_CONSTRAINED;
}
} else {
/* Should not reach here, report the ID as contrainsted */
result = SIDPOL_CONSTRAINED;
}
return result;
}
/*
* Compute a decision for a transition from @src to @dst under the active
* policy.
*/
static enum sid_policy_type setid_policy_lookup(kid_t src, kid_t dst, enum setid_type new_type)
{
enum sid_policy_type result = SIDPOL_DEFAULT;
struct setid_ruleset *pol;
rcu_read_lock();
if (new_type == UID)
pol = rcu_dereference(safesetid_setuid_rules);
else if (new_type == GID)
pol = rcu_dereference(safesetid_setgid_rules);
else { /* Should not reach here */
result = SIDPOL_CONSTRAINED;
rcu_read_unlock();
return result;
}
if (pol) {
pol->type = new_type;
result = _setid_policy_lookup(pol, src, dst);
}
rcu_read_unlock();
return result;
}
static int safesetid_security_capable(const struct cred *cred,
struct user_namespace *ns,
int cap,
unsigned int opts)
{
/* We're only interested in CAP_SETUID and CAP_SETGID. */
if (cap != CAP_SETUID && cap != CAP_SETGID)
return 0;
/*
* If CAP_SET{U/G}ID is currently used for a setid or setgroups syscall, we
* want to let it go through here; the real security check happens later, in
* the task_fix_set{u/g}id or task_fix_setgroups hooks.
*/
if ((opts & CAP_OPT_INSETID) != 0)
return 0;
switch (cap) {
case CAP_SETUID:
/*
* If no policy applies to this task, allow the use of CAP_SETUID for
* other purposes.
*/
if (setid_policy_lookup((kid_t){.uid = cred->uid}, INVALID_ID, UID) == SIDPOL_DEFAULT)
return 0;
/*
* Reject use of CAP_SETUID for functionality other than calling
* set*uid() (e.g. setting up userns uid mappings).
*/
pr_warn("Operation requires CAP_SETUID, which is not available to UID %u for operations besides approved set*uid transitions\n",
__kuid_val(cred->uid));
return -EPERM;
case CAP_SETGID:
/*
* If no policy applies to this task, allow the use of CAP_SETGID for
* other purposes.
*/
if (setid_policy_lookup((kid_t){.gid = cred->gid}, INVALID_ID, GID) == SIDPOL_DEFAULT)
return 0;
Annotation
- Immediate include surface: `linux/lsm_hooks.h`, `linux/module.h`, `linux/ptrace.h`, `linux/sched/task_stack.h`, `linux/security.h`, `uapi/linux/lsm.h`, `lsm.h`.
- Detected declarations: `function _setid_policy_lookup`, `function hash_for_each_possible`, `function setid_policy_lookup`, `function safesetid_security_capable`, `function id_permitted_for_cred`, `function setid_policy_lookup`, `function safesetid_task_fix_setuid`, `function safesetid_task_fix_setgid`, `function safesetid_task_fix_setgroups`, `function safesetid_security_init`.
- Atlas domain: Core OS / Security And Isolation.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.