capability.c 2.9 KB

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