Commit 99db52ed authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent fe9abf1a
......@@ -16,27 +16,72 @@
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// Program xexec does what exec in shell does but as standalone program.
// It is used as trampoline to run a script under setcap environment.
// `capdo prog ...` executes prog with inherited capabilities.
// It is used as trampoline to run script under setcap environment.
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/capability.h>
#include <sys/prctl.h>
static int die(const char *fmt, ...);
static int die_err(const char *msg);
int main(int argc, const char *argv[]) {
if (argc < 2) {
fprintf(stderr, "E: usage: xexec prog arguments...\n");
exit(128);
cap_t caps;
cap_value_t cap;
cap_flag_value_t flag;
uint64_t capbits = 0;
if (argc < 2)
die("usage: capdo prog arguments...");
// permitted -> inheritable (so that we can raise ambient)
caps = cap_get_proc();
if (!caps)
die("cap_get_proc failed");
for (cap = 0; cap < CAP_LAST_CAP; cap++) {
cap_get_flag(caps, cap, CAP_PERMITTED, &flag) && die_err("cap_get_flag");
if (flag) {
cap_set_flag(caps, CAP_INHERITABLE, 1, &cap, flag) && die_err("cap_set_flag");
capbits |= (1ULL << cap);
}
}
cap_set_proc(caps) && die_err("cap_set_proc");
argv++;
// raise ambient capabities to what is permitted/inheritable
for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
if (capbits & (1ULL << cap))
prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) && die_err("prctl ambient raise");
}
// tail to exec target
argv++;
execv(argv[0], argv);
// the only chance we are here is due to error
fprintf(stderr, "xexec: %s: %s\n", argv[0], strerror(errno));
// the only chance we are here is due to exec error
die_err(argv[0]);
}
static int die(const char* fmt, ...) {
va_list ap;
fprintf(stderr, "E: capdo: ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(128);
return 0;
}
static int die_err(const char* msg) {
return die("%s: %s", msg, strerror(errno));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment