context.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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, <sds@tycho.nsa.gov>
  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, 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, 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, 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_cmp(struct context *c1, struct context *c2)
  86. {
  87. return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
  88. ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
  89. (c1->range.level[1].sens == c2->range.level[1].sens) &&
  90. ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
  91. }
  92. static inline void mls_context_destroy(struct context *c)
  93. {
  94. ebitmap_destroy(&c->range.level[0].cat);
  95. ebitmap_destroy(&c->range.level[1].cat);
  96. mls_context_init(c);
  97. }
  98. static inline void context_init(struct context *c)
  99. {
  100. memset(c, 0, sizeof(*c));
  101. }
  102. static inline int context_cpy(struct context *dst, struct context *src)
  103. {
  104. int rc;
  105. dst->user = src->user;
  106. dst->role = src->role;
  107. dst->type = src->type;
  108. if (src->str) {
  109. dst->str = kstrdup(src->str, GFP_ATOMIC);
  110. if (!dst->str)
  111. return -ENOMEM;
  112. dst->len = src->len;
  113. } else {
  114. dst->str = NULL;
  115. dst->len = 0;
  116. }
  117. rc = mls_context_cpy(dst, src);
  118. if (rc) {
  119. kfree(dst->str);
  120. return rc;
  121. }
  122. return 0;
  123. }
  124. static inline void context_destroy(struct context *c)
  125. {
  126. c->user = c->role = c->type = 0;
  127. kfree(c->str);
  128. c->str = NULL;
  129. c->len = 0;
  130. mls_context_destroy(c);
  131. }
  132. static inline int context_cmp(struct context *c1, struct context *c2)
  133. {
  134. if (c1->len && c2->len)
  135. return (c1->len == c2->len && !strcmp(c1->str, c2->str));
  136. if (c1->len || c2->len)
  137. return 0;
  138. return ((c1->user == c2->user) &&
  139. (c1->role == c2->role) &&
  140. (c1->type == c2->type) &&
  141. mls_context_cmp(c1, c2));
  142. }
  143. #endif /* _SS_CONTEXT_H_ */