mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
Merge tag 'caps-pr-20250729' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux
Pull capabilities update from Serge Hallyn: - Fix broken link in documentation in capability.h - Correct the permission check for unsafe exec During exec, different effective and real credentials were assumed to mean changed credentials, making it impossible in the no-new-privs case to keep different uid and euid * tag 'caps-pr-20250729' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux: uapi: fix broken link in linux/capability.h exec: Correct the permission check for unsafe exec
This commit is contained in:
@@ -6,9 +6,10 @@
|
||||
* Alexander Kjeldaas <astor@guardian.no>
|
||||
* with help from Aleph1, Roland Buresund and Andrew Main.
|
||||
*
|
||||
* See here for the libcap library ("POSIX draft" compliance):
|
||||
* See here for the libcap2 library (compliant with Section 25 of
|
||||
* the withdrawn POSIX 1003.1e Draft 17):
|
||||
*
|
||||
* ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
|
||||
* https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/
|
||||
*/
|
||||
|
||||
#ifndef _UAPI_LINUX_CAPABILITY_H
|
||||
|
||||
@@ -856,12 +856,6 @@ static void handle_privileged_root(struct linux_binprm *bprm, bool has_fcap,
|
||||
#define __cap_full(field, cred) \
|
||||
cap_issubset(CAP_FULL_SET, cred->cap_##field)
|
||||
|
||||
static inline bool __is_setuid(struct cred *new, const struct cred *old)
|
||||
{ return !uid_eq(new->euid, old->uid); }
|
||||
|
||||
static inline bool __is_setgid(struct cred *new, const struct cred *old)
|
||||
{ return !gid_eq(new->egid, old->gid); }
|
||||
|
||||
/*
|
||||
* 1) Audit candidate if current->cap_effective is set
|
||||
*
|
||||
@@ -891,7 +885,7 @@ static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old,
|
||||
(root_privileged() &&
|
||||
__is_suid(root, new) &&
|
||||
!__cap_full(effective, new)) ||
|
||||
(!__is_setuid(new, old) &&
|
||||
(uid_eq(new->euid, old->euid) &&
|
||||
((has_fcap &&
|
||||
__cap_gained(permitted, new, old)) ||
|
||||
__cap_gained(ambient, new, old))))
|
||||
@@ -917,7 +911,7 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
|
||||
/* Process setpcap binaries and capabilities for uid 0 */
|
||||
const struct cred *old = current_cred();
|
||||
struct cred *new = bprm->cred;
|
||||
bool effective = false, has_fcap = false, is_setid;
|
||||
bool effective = false, has_fcap = false, id_changed;
|
||||
int ret;
|
||||
kuid_t root_uid;
|
||||
|
||||
@@ -941,9 +935,9 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
|
||||
*
|
||||
* In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
|
||||
*/
|
||||
is_setid = __is_setuid(new, old) || __is_setgid(new, old);
|
||||
id_changed = !uid_eq(new->euid, old->euid) || !in_group_p(new->egid);
|
||||
|
||||
if ((is_setid || __cap_gained(permitted, new, old)) &&
|
||||
if ((id_changed || __cap_gained(permitted, new, old)) &&
|
||||
((bprm->unsafe & ~LSM_UNSAFE_PTRACE) ||
|
||||
!ptracer_capable(current, new->user_ns))) {
|
||||
/* downgrade; they get no more than they had, and maybe less */
|
||||
@@ -960,7 +954,7 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
|
||||
new->sgid = new->fsgid = new->egid;
|
||||
|
||||
/* File caps or setid cancels ambient. */
|
||||
if (has_fcap || is_setid)
|
||||
if (has_fcap || id_changed)
|
||||
cap_clear(new->cap_ambient);
|
||||
|
||||
/*
|
||||
@@ -993,7 +987,9 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
|
||||
return -EPERM;
|
||||
|
||||
/* Check for privilege-elevated exec. */
|
||||
if (is_setid ||
|
||||
if (id_changed ||
|
||||
!uid_eq(new->euid, old->uid) ||
|
||||
!gid_eq(new->egid, old->gid) ||
|
||||
(!__is_real(root_uid, new) &&
|
||||
(effective ||
|
||||
__cap_grew(permitted, ambient, new))))
|
||||
|
||||
Reference in New Issue
Block a user