cap_alloc.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
  3. *
  4. * This file deals with allocation and deallocation of internal
  5. * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
  6. */
  7. #include "libcap.h"
  8. /*
  9. * Obtain a blank set of capabilities
  10. */
  11. cap_t cap_init(void)
  12. {
  13. __u32 *raw_data;
  14. cap_t result;
  15. raw_data = malloc( sizeof(__u32) + sizeof(*result) );
  16. if (raw_data == NULL) {
  17. _cap_debug("out of memory");
  18. errno = ENOMEM;
  19. return NULL;
  20. }
  21. *raw_data = CAP_T_MAGIC;
  22. result = (cap_t) (raw_data + 1);
  23. memset(result, 0, sizeof(*result));
  24. result->head.version = _LIBCAP_CAPABILITY_VERSION;
  25. capget(&result->head, NULL); /* load the kernel-capability version */
  26. switch (result->head.version) {
  27. #ifdef _LINUX_CAPABILITY_VERSION_1
  28. case _LINUX_CAPABILITY_VERSION_1:
  29. break;
  30. #endif
  31. #ifdef _LINUX_CAPABILITY_VERSION_2
  32. case _LINUX_CAPABILITY_VERSION_2:
  33. break;
  34. #endif
  35. #ifdef _LINUX_CAPABILITY_VERSION_3
  36. case _LINUX_CAPABILITY_VERSION_3:
  37. break;
  38. #endif
  39. default: /* No idea what to do */
  40. cap_free(result);
  41. result = NULL;
  42. break;
  43. }
  44. return result;
  45. }
  46. /*
  47. * This is an internal library function to duplicate a string and
  48. * tag the result as something cap_free can handle.
  49. */
  50. char *_libcap_strdup(const char *old)
  51. {
  52. __u32 *raw_data;
  53. if (old == NULL) {
  54. errno = EINVAL;
  55. return NULL;
  56. }
  57. raw_data = malloc( sizeof(__u32) + strlen(old) + 1 );
  58. if (raw_data == NULL) {
  59. errno = ENOMEM;
  60. return NULL;
  61. }
  62. *(raw_data++) = CAP_S_MAGIC;
  63. strcpy((char *) raw_data, old);
  64. return ((char *) raw_data);
  65. }
  66. /*
  67. * This function duplicates an internal capability set with
  68. * malloc()'d memory. It is the responsibility of the user to call
  69. * cap_free() to liberate it.
  70. */
  71. cap_t cap_dup(cap_t cap_d)
  72. {
  73. cap_t result;
  74. if (!good_cap_t(cap_d)) {
  75. _cap_debug("bad argument");
  76. errno = EINVAL;
  77. return NULL;
  78. }
  79. result = cap_init();
  80. if (result == NULL) {
  81. _cap_debug("out of memory");
  82. return NULL;
  83. }
  84. memcpy(result, cap_d, sizeof(*cap_d));
  85. return result;
  86. }
  87. /*
  88. * Scrub and then liberate an internal capability set.
  89. */
  90. int cap_free(void *data_p)
  91. {
  92. if ( !data_p )
  93. return 0;
  94. if ( good_cap_t(data_p) ) {
  95. data_p = -1 + (__u32 *) data_p;
  96. memset(data_p, 0, sizeof(__u32) + sizeof(struct _cap_struct));
  97. free(data_p);
  98. data_p = NULL;
  99. return 0;
  100. }
  101. if ( good_cap_string(data_p) ) {
  102. size_t length = strlen(data_p) + sizeof(__u32);
  103. data_p = -1 + (__u32 *) data_p;
  104. memset(data_p, 0, length);
  105. free(data_p);
  106. data_p = NULL;
  107. return 0;
  108. }
  109. _cap_debug("don't recognize what we're supposed to liberate");
  110. errno = EINVAL;
  111. return -1;
  112. }