cap_extint.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
  3. *
  4. * This file deals with exchanging internal and external
  5. * representations of capability sets.
  6. */
  7. #include "libcap.h"
  8. /*
  9. * External representation for capabilities. (exported as a fixed
  10. * length)
  11. */
  12. #define CAP_EXT_MAGIC "\220\302\001\121"
  13. #define CAP_EXT_MAGIC_SIZE 4
  14. const static __u8 external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC;
  15. struct cap_ext_struct {
  16. __u8 magic[CAP_EXT_MAGIC_SIZE];
  17. __u8 length_of_capset;
  18. /*
  19. * note, we arrange these so the caps are stacked with byte-size
  20. * resolution
  21. */
  22. __u8 bytes[CAP_SET_SIZE][NUMBER_OF_CAP_SETS];
  23. };
  24. /*
  25. * return size of external capability set
  26. */
  27. ssize_t cap_size(cap_t caps)
  28. {
  29. return ssizeof(struct cap_ext_struct);
  30. }
  31. /*
  32. * Copy the internal (cap_d) capability set into an external
  33. * representation. The external representation is portable to other
  34. * Linux architectures.
  35. */
  36. ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length)
  37. {
  38. struct cap_ext_struct *result = (struct cap_ext_struct *) cap_ext;
  39. int i;
  40. /* valid arguments? */
  41. if (!good_cap_t(cap_d) || length < ssizeof(struct cap_ext_struct)
  42. || cap_ext == NULL) {
  43. errno = EINVAL;
  44. return -1;
  45. }
  46. /* fill external capability set */
  47. memcpy(&result->magic, external_magic, CAP_EXT_MAGIC_SIZE);
  48. result->length_of_capset = CAP_SET_SIZE;
  49. for (i=0; i<NUMBER_OF_CAP_SETS; ++i) {
  50. size_t j;
  51. for (j=0; j<CAP_SET_SIZE; ) {
  52. __u32 val;
  53. val = cap_d->u[j/sizeof(__u32)].flat[i];
  54. result->bytes[j++][i] = val & 0xFF;
  55. result->bytes[j++][i] = (val >>= 8) & 0xFF;
  56. result->bytes[j++][i] = (val >>= 8) & 0xFF;
  57. result->bytes[j++][i] = (val >> 8) & 0xFF;
  58. }
  59. }
  60. /* All done: return length of external representation */
  61. return (ssizeof(struct cap_ext_struct));
  62. }
  63. /*
  64. * Import an external representation to produce an internal rep.
  65. * the internal rep should be liberated with cap_free().
  66. */
  67. cap_t cap_copy_int(const void *cap_ext)
  68. {
  69. const struct cap_ext_struct *export =
  70. (const struct cap_ext_struct *) cap_ext;
  71. cap_t cap_d;
  72. int set, blen;
  73. /* Does the external representation make sense? */
  74. if ((export == NULL)
  75. || memcmp(export->magic, external_magic, CAP_EXT_MAGIC_SIZE)) {
  76. errno = EINVAL;
  77. return NULL;
  78. }
  79. /* Obtain a new internal capability set */
  80. if (!(cap_d = cap_init()))
  81. return NULL;
  82. blen = export->length_of_capset;
  83. for (set=0; set<NUMBER_OF_CAP_SETS; ++set) {
  84. unsigned blk;
  85. int bno = 0;
  86. for (blk=0; blk<(CAP_SET_SIZE/sizeof(__u32)); ++blk) {
  87. __u32 val = 0;
  88. if (bno != blen)
  89. val = export->bytes[bno++][set];
  90. if (bno != blen)
  91. val |= export->bytes[bno++][set] << 8;
  92. if (bno != blen)
  93. val |= export->bytes[bno++][set] << 16;
  94. if (bno != blen)
  95. val |= export->bytes[bno++][set] << 24;
  96. cap_d->u[blk].flat[set] = val;
  97. }
  98. }
  99. /* all done */
  100. return cap_d;
  101. }