From 0c92194eeee9c1fd58580ef852c11eb1861d6dee Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Sat, 24 Jun 2017 16:04:34 +0200 Subject: setpriv: support modifying the set of ambient capabilities Right now, we do not support modifying the set of ambient capabilities, which has been introduced quite recently with Linux 4.3. As libcap-ng does not yet provide any ability to modify this set, we do have to roll our own support via `prctl`, which is now easy to do due to the indirections introduced in the preceding commits. We add a new command line argument "--ambient-caps", which uses the same syntax as both "--inh-caps" and "--bounding-set" to specify either adding or dropping capabilities. This commit also adjusts documentation to mention the newly introduced ability to modify the ambient capability set. Based on a patch by Andy Lutomirski. Reviewed-by: Andy Lutomirski Signed-off-by: Patrick Steinhardt --- sys-utils/setpriv.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'sys-utils/setpriv.c') diff --git a/sys-utils/setpriv.c b/sys-utils/setpriv.c index 5216f98ef..a029a8a44 100644 --- a/sys-utils/setpriv.c +++ b/sys-utils/setpriv.c @@ -49,6 +49,8 @@ #ifndef PR_CAP_AMBIENT # define PR_CAP_AMBIENT 47 # define PR_CAP_AMBIENT_IS_SET 1 +# define PR_CAP_AMBIENT_RAISE 2 +# define PR_CAP_AMBIENT_LOWER 3 #endif #define SETPRIV_EXIT_PRIVERR 127 /* how we exit when we fail to set privs */ @@ -95,6 +97,7 @@ struct privctx { /* caps */ const char *caps_to_inherit; + const char *ambient_caps; const char *bounding_set; /* securebits */ @@ -479,6 +482,19 @@ static int cap_update(capng_act_t action, case CAP_TYPE_INHERITABLE: case CAP_TYPE_PERMITTED: return capng_update(action, (capng_type_t) type, cap); + case CAP_TYPE_AMBIENT: + { + int ret; + + if (action == CAPNG_ADD) + ret = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, + (unsigned long) cap, 0UL, 0UL); + else + ret = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, + (unsigned long) cap, 0UL, 0UL); + + return ret; + } default: errx(EXIT_FAILURE, _("unsupported capability type")); return -1; @@ -687,6 +703,7 @@ int main(int argc, char **argv) INIT_GROUPS, GROUPS, INHCAPS, + AMBCAPS, LISTCAPS, CAPBSET, SECUREBITS, @@ -699,6 +716,7 @@ int main(int argc, char **argv) { "nnp", no_argument, NULL, NNP }, { "no-new-privs", no_argument, NULL, NNP }, { "inh-caps", required_argument, NULL, INHCAPS }, + { "ambient-caps", required_argument, NULL, AMBCAPS }, { "list-caps", no_argument, NULL, LISTCAPS }, { "ruid", required_argument, NULL, RUID }, { "euid", required_argument, NULL, EUID }, @@ -831,6 +849,12 @@ int main(int argc, char **argv) _("duplicate --inh-caps option")); opts.caps_to_inherit = optarg; break; + case AMBCAPS: + if (opts.ambient_caps) + errx(EXIT_FAILURE, + _("duplicate --ambient-caps option")); + opts.ambient_caps = optarg; + break; case CAPBSET: if (opts.bounding_set) errx(EXIT_FAILURE, @@ -957,6 +981,10 @@ int main(int argc, char **argv) err(SETPRIV_EXIT_PRIVERR, _("apply capabilities")); } + if (opts.ambient_caps) { + do_caps(CAP_TYPE_AMBIENT, opts.ambient_caps); + } + execvp(argv[optind], argv + optind); err(EXIT_FAILURE, _("cannot execute: %s"), argv[optind]); -- cgit v1.2.3-55-g7522