Projects
Mega:24.03
util-linux
_service:tar_scm:backport-unshare-Move-implemen...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-unshare-Move-implementation-of-keep-caps-option-to-l.patch of Package util-linux
From acb72212eb41ca862b8bc29b0106a46a83297fcb Mon Sep 17 00:00:00 2001 From: David Gibson <david@gibson.dropbear.id.au> Date: Wed, 29 Mar 2023 13:36:15 +1100 Subject: [PATCH] unshare: Move implementation of --keep-caps option to library function unshare.c open codes some logic to copy the permitted capability set to the ambient set in order to implement the --keep-caps option. Move this logic to lib/caputils.c so that we can reuse it in nsenter. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- include/caputils.h | 2 ++ lib/caputils.c | 38 ++++++++++++++++++++++++++++++++++++++ sys-utils/unshare.c | 38 ++------------------------------------ 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/include/caputils.h b/include/caputils.h index 852903a6e..8fc214e7f 100644 --- a/include/caputils.h +++ b/include/caputils.h @@ -31,4 +31,6 @@ extern int capget(cap_user_header_t header, const cap_user_data_t data); extern int cap_last_cap(void); +extern void cap_permitted_to_ambient(void); + #endif /* CAPUTILS_H */ diff --git a/lib/caputils.c b/lib/caputils.c index 987533a34..3041c3078 100644 --- a/lib/caputils.c +++ b/lib/caputils.c @@ -24,6 +24,7 @@ #include "caputils.h" #include "pathnames.h" #include "procfs.h" +#include "nls.h" static int test_cap(unsigned int cap) { @@ -87,6 +88,43 @@ int cap_last_cap(void) return cap; } +void cap_permitted_to_ambient(void) +{ + /* We use capabilities system calls to propagate the permitted + * capabilities into the ambient set because we may have + * already forked so be in async-signal-safe context. */ + struct __user_cap_header_struct header = { + .version = _LINUX_CAPABILITY_VERSION_3, + .pid = 0, + }; + struct __user_cap_data_struct payload[_LINUX_CAPABILITY_U32S_3] = {{ 0 }}; + uint64_t effective, cap; + + if (capget(&header, payload) < 0) + err(EXIT_FAILURE, _("capget failed")); + + /* In order the make capabilities ambient, we first need to ensure + * that they are all inheritable. */ + payload[0].inheritable = payload[0].permitted; + payload[1].inheritable = payload[1].permitted; + + if (capset(&header, payload) < 0) + err(EXIT_FAILURE, _("capset failed")); + + effective = ((uint64_t)payload[1].effective << 32) | (uint64_t)payload[0].effective; + + for (cap = 0; cap < (sizeof(effective) * 8); cap++) { + /* This is the same check as cap_valid(), but using + * the runtime value for the last valid cap. */ + if (cap > (uint64_t) cap_last_cap()) + continue; + + if ((effective & (1 << cap)) + && prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) < 0) + err(EXIT_FAILURE, _("prctl(PR_CAP_AMBIENT) failed")); + } +} + #ifdef TEST_PROGRAM_CAPUTILS int main(int argc, char *argv[]) { diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c index 2aa239eff..13aefa96c 100644 --- a/sys-utils/unshare.c +++ b/sys-utils/unshare.c @@ -1089,42 +1089,8 @@ int main(int argc, char *argv[]) if (force_uid && setuid(uid) < 0) /* change UID */ err(EXIT_FAILURE, _("setuid failed")); - /* We use capabilities system calls to propagate the permitted - * capabilities into the ambient set because we have already - * forked so are in async-signal-safe context. */ - if (keepcaps && (unshare_flags & CLONE_NEWUSER)) { - struct __user_cap_header_struct header = { - .version = _LINUX_CAPABILITY_VERSION_3, - .pid = 0, - }; - - struct __user_cap_data_struct payload[_LINUX_CAPABILITY_U32S_3] = {{ 0 }}; - uint64_t effective, cap; - - if (capget(&header, payload) < 0) - err(EXIT_FAILURE, _("capget failed")); - - /* In order the make capabilities ambient, we first need to ensure - * that they are all inheritable. */ - payload[0].inheritable = payload[0].permitted; - payload[1].inheritable = payload[1].permitted; - - if (capset(&header, payload) < 0) - err(EXIT_FAILURE, _("capset failed")); - - effective = ((uint64_t)payload[1].effective << 32) | (uint64_t)payload[0].effective; - - for (cap = 0; cap < (sizeof(effective) * 8); cap++) { - /* This is the same check as cap_valid(), but using - * the runtime value for the last valid cap. */ - if (cap > (uint64_t) cap_last_cap()) - continue; - - if ((effective & (1 << cap)) - && prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) < 0) - err(EXIT_FAILURE, _("prctl(PR_CAP_AMBIENT) failed")); - } - } + if (keepcaps && (unshare_flags & CLONE_NEWUSER)) + cap_permitted_to_ambient(); if (optind < argc) { execvp(argv[optind], argv + optind); -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2