Capabilities update for 6.17

This branch contains two patches:
 
   cdd73b1666 uapi: fix broken link in linux/capability.h
 
 This updates documentation in capability.h.
 
   337490f000 exec: Correct the permission check for unsafe exec
 
 This is not a trivial patch, but fixes a real problem where 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.
 
 These are available at:
 
    git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux.git #caps-pr-20250729
 
 on top of commit 19272b37aa (tag: v6.16-rc1)
 
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEqb0/8XByttt4D8+UNXDaFycKziQFAmiJHCIACgkQNXDaFycK
 ziRz0QgAqDCdWBrwS/icfXnkV+fcB8J/p/JP+5DO4stn9vV97j+RC3WLc/Wlj5tl
 jLbGGd8eWnCYyTaUHlhE81Qw4b5iQKkd6umGSIBoQVu00YiJ3pLaYsIkEaEMDIkG
 2qS5oNyDEFho8g05++mmTfGMeFQJ4mUEwUmcnsCcTH3bkvcVinlZwP6Lfitmt0lH
 yS0xeMf+gBINou1yTPLdMCCv8LAac2qBcMWhWk4NBEFZJoM0S/Rg5RhdiYYNYYAj
 fi96cTG7qbv80a3M6e/7ta4hU+XdU6JuzQRQJeZstFj2oRfTx2CRR1Wgbus4KdlP
 x/5Sc3bT/ovdPwDc/5HTeFXAlqIqmQ==
 =uKJr
 -----END PGP SIGNATURE-----
 
 commit cdd73b1666
 Author: Ariel Otilibili <ariel.otilibili-anieli@eurecom.fr>
 Date:   Wed Jul 2 12:00:21 2025 +0200
 
     uapi: fix broken link in linux/capability.h
 
     The link to the libcap library is outdated. Instead, use a link to the
     libcap2 library.
 
     As well, give the complete reference of the POSIX compliance.
 
     Signed-off-by: Ariel Otilibili <ariel.otilibili-anieli@eurecom.fr>
     Acked-by: Andrew G. Morgan <morgan@kernel.org>
     Reviewed-by: Paul Moore <paul@paul-moore.com>
     Signed-off-by: Serge Hallyn <sergeh@kernel.org>
 
 diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
 index 2e21b5594f81..ea5a0899ecf0 100644
 --- a/include/uapi/linux/capability.h
 +++ b/include/uapi/linux/capability.h
 @@ -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
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEqb0/8XByttt4D8+UNXDaFycKziQFAmiJHhoACgkQNXDaFycK
 ziQXVQgAn7931CkRAKZXcukfluPWFsanPGoBKqT+UFVjjUenDtd/GXZQwahRwweS
 k7zDDa/JE59yMHKNenslLgV1PYb3/ZtBMDq+8/LXQ/JMkaZYpNhPPo0lUa70s3pM
 EdY4qbB+aNWeAoHTltRkRkbDHWak3sNjlRyavQj2n7uCOXdSHp4yAVOgiMqxAUX8
 o/V6M6dHA2iN0HEKV+Mp5vHY+9TTFv8dTygNxb1995n1QfHT/AFOTOO598FHkYxA
 aSR8kSpdULdGExk+7Q2NsJoX38zsZIaaI75MQw9Tz5iRkYFZG3hcJVYNbZyT10s+
 NwteAaDfTqTz78QB3PcG794CQls8vQ==
 =yLTV
 -----END PGP SIGNATURE-----

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:
Linus Torvalds 2025-07-31 11:19:54 -07:00
commit 12ed593ee8
2 changed files with 11 additions and 14 deletions

View File

@ -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

View File

@ -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))))