/* Compute a decision for a transition from @src to @dst under @policy. */ enum sid_policy_type _setid_policy_lookup(struct setid_ruleset *policy,
kid_t src, kid_t dst)
{ struct setid_rule *rule; enum sid_policy_type result = SIDPOL_DEFAULT;
if (policy->type == UID) {
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;
}
} elseif (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;
}
rcu_read_lock(); if (new_type == UID)
pol = rcu_dereference(safesetid_setuid_rules); elseif (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;
}
staticint safesetid_security_capable(conststruct cred *cred, struct user_namespace *ns, int cap, unsignedint opts)
{ /* We're only interested in CAP_SETUID and CAP_SETGID. */ if (cap != CAP_SETUID && cap != CAP_SETGID) return0;
switch (cap) { case CAP_SETUID: /* *Ifnopolicyappliestothistask,allowtheuseofCAP_SETUIDfor *otherpurposes.
*/ if (setid_policy_lookup((kid_t){.uid = cred->uid}, INVALID_ID, UID) == SIDPOL_DEFAULT) return0; /* *RejectuseofCAP_SETUIDforfunctionalityotherthancalling *set*uid()(e.g.settingupusernsuidmappings).
*/
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: /* *Ifnopolicyappliestothistask,allowtheuseofCAP_SETGIDfor *otherpurposes.
*/ if (setid_policy_lookup((kid_t){.gid = cred->gid}, INVALID_ID, GID) == SIDPOL_DEFAULT) return0; /* *RejectuseofCAP_SETUIDforfunctionalityotherthancalling *set*gid()(e.g.settingupusernsgidmappings).
*/
pr_warn("Operation requires CAP_SETGID, which is not available to GID %u for operations besides approved set*gid transitions\n",
__kgid_val(cred->gid)); return -EPERM; default: /* Error, the only capabilities were checking for is CAP_SETUID/GID */ return0;
} return0;
}
/* If our old creds already had this ID in it, it's fine. */ if (new_type == UID) { if (uid_eq(new_id.uid, old->uid) || uid_eq(new_id.uid, old->euid) ||
uid_eq(new_id.uid, old->suid)) returntrue;
} elseif (new_type == GID){ if (gid_eq(new_id.gid, old->gid) || gid_eq(new_id.gid, old->egid) ||
gid_eq(new_id.gid, old->sgid)) returntrue;
} else/* Error, new_type is an invalid type */ returnfalse;
/* Do nothing if there are no setuid restrictions for our old RUID. */ if (setid_policy_lookup((kid_t){.uid = old->uid}, INVALID_ID, UID) == SIDPOL_DEFAULT) return0;
staticint safesetid_task_fix_setgid(struct cred *new, conststruct cred *old, int flags)
{
/* Do nothing if there are no setgid restrictions for our old RGID. */ if (setid_policy_lookup((kid_t){.gid = old->gid}, INVALID_ID, GID) == SIDPOL_DEFAULT) return0;
staticint safesetid_task_fix_setgroups(struct cred *new, conststruct cred *old)
{ int i;
/* Do nothing if there are no setgid restrictions for our old RGID. */ if (setid_policy_lookup((kid_t){.gid = old->gid}, INVALID_ID, GID) == SIDPOL_DEFAULT) return0;
get_group_info(new->group_info); for (i = 0; i < new->group_info->ngroups; i++) { if (!id_permitted_for_cred(old, (kid_t){.gid = new->group_info->gid[i]}, GID)) {
put_group_info(new->group_info); /* *Killthisprocesstoavoidpotentialsecurityvulnerabilities *thatcouldarisefromamissingallowlistentrypreventinga *privilegedprocessfromdroppingtoalesser-privilegedone.
*/
force_sig(SIGKILL); return -EACCES;
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.