Skip to content

Commit 12ed593

Browse files
committed
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
2 parents f1aa129 + cdd73b1 commit 12ed593

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed

include/uapi/linux/capability.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
* Alexander Kjeldaas <[email protected]>
77
* with help from Aleph1, Roland Buresund and Andrew Main.
88
*
9-
* See here for the libcap library ("POSIX draft" compliance):
9+
* See here for the libcap2 library (compliant with Section 25 of
10+
* the withdrawn POSIX 1003.1e Draft 17):
1011
*
11-
* ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
12+
* https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/
1213
*/
1314

1415
#ifndef _UAPI_LINUX_CAPABILITY_H

security/commoncap.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -856,12 +856,6 @@ static void handle_privileged_root(struct linux_binprm *bprm, bool has_fcap,
856856
#define __cap_full(field, cred) \
857857
cap_issubset(CAP_FULL_SET, cred->cap_##field)
858858

859-
static inline bool __is_setuid(struct cred *new, const struct cred *old)
860-
{ return !uid_eq(new->euid, old->uid); }
861-
862-
static inline bool __is_setgid(struct cred *new, const struct cred *old)
863-
{ return !gid_eq(new->egid, old->gid); }
864-
865859
/*
866860
* 1) Audit candidate if current->cap_effective is set
867861
*
@@ -891,7 +885,7 @@ static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old,
891885
(root_privileged() &&
892886
__is_suid(root, new) &&
893887
!__cap_full(effective, new)) ||
894-
(!__is_setuid(new, old) &&
888+
(uid_eq(new->euid, old->euid) &&
895889
((has_fcap &&
896890
__cap_gained(permitted, new, old)) ||
897891
__cap_gained(ambient, new, old))))
@@ -917,7 +911,7 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
917911
/* Process setpcap binaries and capabilities for uid 0 */
918912
const struct cred *old = current_cred();
919913
struct cred *new = bprm->cred;
920-
bool effective = false, has_fcap = false, is_setid;
914+
bool effective = false, has_fcap = false, id_changed;
921915
int ret;
922916
kuid_t root_uid;
923917

@@ -941,9 +935,9 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
941935
*
942936
* In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
943937
*/
944-
is_setid = __is_setuid(new, old) || __is_setgid(new, old);
938+
id_changed = !uid_eq(new->euid, old->euid) || !in_group_p(new->egid);
945939

946-
if ((is_setid || __cap_gained(permitted, new, old)) &&
940+
if ((id_changed || __cap_gained(permitted, new, old)) &&
947941
((bprm->unsafe & ~LSM_UNSAFE_PTRACE) ||
948942
!ptracer_capable(current, new->user_ns))) {
949943
/* 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)
960954
new->sgid = new->fsgid = new->egid;
961955

962956
/* File caps or setid cancels ambient. */
963-
if (has_fcap || is_setid)
957+
if (has_fcap || id_changed)
964958
cap_clear(new->cap_ambient);
965959

966960
/*
@@ -993,7 +987,9 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
993987
return -EPERM;
994988

995989
/* Check for privilege-elevated exec. */
996-
if (is_setid ||
990+
if (id_changed ||
991+
!uid_eq(new->euid, old->uid) ||
992+
!gid_eq(new->egid, old->gid) ||
997993
(!__is_real(root_uid, new) &&
998994
(effective ||
999995
__cap_grew(permitted, ambient, new))))

0 commit comments

Comments
 (0)