busybox/libbb/capability.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2017 by  <assafgordon@gmail.com>
   3 *
   4 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   5 */
   6//kbuild:lib-$(CONFIG_FEATURE_SETPRIV_CAPABILITIES) += capability.o
   7//kbuild:lib-$(CONFIG_RUN_INIT) += capability.o
   8
   9#include <linux/capability.h>
  10// #include <sys/capability.h>
  11// This header is in libcap, but the functions are in libc.
  12// Comment in the header says this above capset/capget:
  13/* system calls - look to libc for function to system call mapping */
  14extern int capset(cap_user_header_t header, cap_user_data_t data);
  15extern int capget(cap_user_header_t header, const cap_user_data_t data);
  16// so for bbox, let's just repeat the declarations.
  17// This way, libcap needs not be installed in build environment.
  18#include "libbb.h"
  19
  20static const char *const capabilities[] = {
  21        "chown",
  22        "dac_override",
  23        "dac_read_search",
  24        "fowner",
  25        "fsetid",
  26        "kill",
  27        "setgid",
  28        "setuid",
  29        "setpcap",
  30        "linux_immutable",
  31        "net_bind_service",
  32        "net_broadcast",
  33        "net_admin",
  34        "net_raw",
  35        "ipc_lock",
  36        "ipc_owner",
  37        "sys_module",
  38        "sys_rawio",
  39        "sys_chroot",
  40        "sys_ptrace",
  41        "sys_pacct",
  42        "sys_admin",
  43        "sys_boot",
  44        "sys_nice",
  45        "sys_resource",
  46        "sys_time",
  47        "sys_tty_config",
  48        "mknod",
  49        "lease",
  50        "audit_write",
  51        "audit_control",
  52        "setfcap",
  53        "mac_override",
  54        "mac_admin",
  55        "syslog",
  56        "wake_alarm",
  57        "block_suspend",
  58        "audit_read",
  59};
  60
  61unsigned FAST_FUNC cap_name_to_number(const char *cap)
  62{
  63        unsigned i, n;
  64
  65        if ((sscanf(cap, "cap_%u", &n)) == 1) {
  66                i = n;
  67                goto found;
  68        }
  69        for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
  70                if (strcasecmp(capabilities[i], cap) == 0)
  71                        goto found;
  72        }
  73        bb_error_msg_and_die("unknown capability '%s'", cap);
  74
  75 found:
  76        if (!cap_valid(i))
  77                bb_error_msg_and_die("unknown capability '%s'", cap);
  78        return i;
  79}
  80
  81void FAST_FUNC printf_cap(const char *pfx, unsigned cap_no)
  82{
  83        if (cap_no < ARRAY_SIZE(capabilities)) {
  84                printf("%s%s", pfx, capabilities[cap_no]);
  85                return;
  86        }
  87        printf("%scap_%u", pfx, cap_no);
  88}
  89
  90DEFINE_STRUCT_CAPS;
  91
  92void FAST_FUNC getcaps(void *arg)
  93{
  94        static const uint8_t versions[] = {
  95                _LINUX_CAPABILITY_U32S_3, /* = 2 (fits into byte) */
  96                _LINUX_CAPABILITY_U32S_2, /* = 2 */
  97                _LINUX_CAPABILITY_U32S_1, /* = 1 */
  98        };
  99        int i;
 100        struct caps *caps = arg;
 101
 102        caps->header.pid = 0;
 103        for (i = 0; i < ARRAY_SIZE(versions); i++) {
 104                caps->header.version = versions[i];
 105                if (capget(&caps->header, NULL) == 0)
 106                        goto got_it;
 107        }
 108        bb_simple_perror_msg_and_die("capget");
 109 got_it:
 110
 111        switch (caps->header.version) {
 112                case _LINUX_CAPABILITY_VERSION_1:
 113                        caps->u32s = _LINUX_CAPABILITY_U32S_1;
 114                        break;
 115                case _LINUX_CAPABILITY_VERSION_2:
 116                        caps->u32s = _LINUX_CAPABILITY_U32S_2;
 117                        break;
 118                case _LINUX_CAPABILITY_VERSION_3:
 119                        caps->u32s = _LINUX_CAPABILITY_U32S_3;
 120                        break;
 121                default:
 122                        bb_error_msg_and_die("unsupported capability version");
 123        }
 124
 125        if (capget(&caps->header, caps->data) != 0)
 126                bb_simple_perror_msg_and_die("capget");
 127}
 128