context.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * A security context is a set of security attributes
  4. * associated with each subject and object controlled
  5. * by the security policy. Security contexts are
  6. * externally represented as variable-length strings
  7. * that can be interpreted by a user or application
  8. * with an understanding of the security policy.
  9. * Internally, the security server uses a simple
  10. * structure. This structure is private to the
  11. * security server and can be changed without affecting
  12. * clients of the security server.
  13. *
  14. * Author : Stephen Smalley, <[email protected]>
  15. */
  16. #ifndef _SS_CONTEXT_H_
  17. #define _SS_CONTEXT_H_
  18. #include "ebitmap.h"
  19. #include "mls_types.h"
  20. #include "security.h"
  21. /*
  22. * A security context consists of an authenticated user
  23. * identity, a role, a type and a MLS range.
  24. */
  25. struct context {
  26. u32 user;
  27. u32 role;
  28. u32 type;
  29. u32 len; /* length of string in bytes */
  30. struct mls_range range;
  31. char *str; /* string representation if context cannot be mapped. */
  32. };
  33. static inline void mls_context_init(struct context *c)
  34. {
  35. memset(&c->range, 0, sizeof(c->range));
  36. }
  37. static inline int mls_context_cpy(struct context *dst, const struct context *src)
  38. {
  39. int rc;
  40. dst->range.level[0].sens = src->range.level[0].sens;
  41. rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
  42. if (rc)
  43. goto out;
  44. dst->range.level[1].sens = src->range.level[1].sens;
  45. rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
  46. if (rc)
  47. ebitmap_destroy(&dst->range.level[0].cat);
  48. out:
  49. return rc;
  50. }
  51. /*
  52. * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
  53. */
  54. static inline int mls_context_cpy_low(struct context *dst, const struct context *src)
  55. {
  56. int rc;
  57. dst->range.level[0].sens = src->range.level[0].sens;
  58. rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
  59. if (rc)
  60. goto out;
  61. dst->range.level[1].sens = src->range.level[0].sens;
  62. rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
  63. if (rc)
  64. ebitmap_destroy(&dst->range.level[0].cat);
  65. out:
  66. return rc;
  67. }
  68. /*
  69. * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
  70. */
  71. static inline int mls_context_cpy_high(struct context *dst, const struct context *src)
  72. {
  73. int rc;
  74. dst->range.level[0].sens = src->range.level[1].sens;
  75. rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
  76. if (rc)
  77. goto out;
  78. dst->range.level[1].sens = src->range.level[1].sens;
  79. rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
  80. if (rc)
  81. ebitmap_destroy(&dst->range.level[0].cat);
  82. out:
  83. return rc;
  84. }
  85. static inline int mls_context_glblub(struct context *dst,
  86. const struct context *c1, const struct context *c2)
  87. {
  88. struct mls_range *dr = &dst->range;
  89. const struct mls_range *r1 = &c1->range, *r2 = &c2->range;
  90. int rc = 0;
  91. if (r1->level[1].sens < r2->level[0].sens ||
  92. r2->level[1].sens < r1->level[0].sens)
  93. /* These ranges have no common sensitivities */
  94. return -EINVAL;
  95. /* Take the greatest of the low */
  96. dr->level[0].sens = max(r1->level[0].sens, r2->level[0].sens);
  97. /* Take the least of the high */
  98. dr->level[1].sens = min(r1->level[1].sens, r2->level[1].sens);
  99. rc = ebitmap_and(&dr->level[0].cat,
  100. &r1->level[0].cat, &r2->level[0].cat);
  101. if (rc)
  102. goto out;
  103. rc = ebitmap_and(&dr->level[1].cat,
  104. &r1->level[1].cat, &r2->level[1].cat);
  105. if (rc)
  106. goto out;
  107. out:
  108. return rc;
  109. }
  110. static inline int mls_context_cmp(const struct context *c1, const struct context *c2)
  111. {
  112. return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
  113. ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
  114. (c1->range.level[1].sens == c2->range.level[1].sens) &&
  115. ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
  116. }
  117. static inline void mls_context_destroy(struct context *c)
  118. {
  119. ebitmap_destroy(&c->range.level[0].cat);
  120. ebitmap_destroy(&c->range.level[1].cat);
  121. mls_context_init(c);
  122. }
  123. static inline void context_init(struct context *c)
  124. {
  125. memset(c, 0, sizeof(*c));
  126. }
  127. static inline int context_cpy(struct context *dst, const struct context *src)
  128. {
  129. int rc;
  130. dst->user = src->user;
  131. dst->role = src->role;
  132. dst->type = src->type;
  133. if (src->str) {
  134. dst->str = kstrdup(src->str, GFP_ATOMIC);
  135. if (!dst->str)
  136. return -ENOMEM;
  137. dst->len = src->len;
  138. } else {
  139. dst->str = NULL;
  140. dst->len = 0;
  141. }
  142. rc = mls_context_cpy(dst, src);
  143. if (rc) {
  144. kfree(dst->str);
  145. return rc;
  146. }
  147. return 0;
  148. }
  149. static inline void context_destroy(struct context *c)
  150. {
  151. c->user = c->role = c->type = 0;
  152. kfree(c->str);
  153. c->str = NULL;
  154. c->len = 0;
  155. mls_context_destroy(c);
  156. }
  157. static inline int context_cmp(const struct context *c1, const struct context *c2)
  158. {
  159. if (c1->len && c2->len)
  160. return (c1->len == c2->len && !strcmp(c1->str, c2->str));
  161. if (c1->len || c2->len)
  162. return 0;
  163. return ((c1->user == c2->user) &&
  164. (c1->role == c2->role) &&
  165. (c1->type == c2->type) &&
  166. mls_context_cmp(c1, c2));
  167. }
  168. u32 context_compute_hash(const struct context *c);
  169. #endif /* _SS_CONTEXT_H_ */