Branch data Line data Source code
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 : :
19 : : #include "ebitmap.h"
20 : : #include "mls_types.h"
21 : : #include "security.h"
22 : :
23 : : /*
24 : : * A security context consists of an authenticated user
25 : : * identity, a role, a type and a MLS range.
26 : : */
27 : : struct context {
28 : : u32 user;
29 : : u32 role;
30 : : u32 type;
31 : : u32 len; /* length of string in bytes */
32 : : struct mls_range range;
33 : : char *str; /* string representation if context cannot be mapped. */
34 : : u32 hash; /* a hash of the string representation */
35 : : };
36 : :
37 : 0 : static inline void mls_context_init(struct context *c)
38 : : {
39 : 0 : memset(&c->range, 0, sizeof(c->range));
40 : : }
41 : :
42 : 0 : static inline int mls_context_cpy(struct context *dst, struct context *src)
43 : : {
44 : 0 : int rc;
45 : :
46 : 0 : dst->range.level[0].sens = src->range.level[0].sens;
47 : 0 : rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
48 [ # # ]: 0 : if (rc)
49 : 0 : goto out;
50 : :
51 : 0 : dst->range.level[1].sens = src->range.level[1].sens;
52 : 0 : rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
53 [ # # ]: 0 : if (rc)
54 : 0 : ebitmap_destroy(&dst->range.level[0].cat);
55 : 0 : out:
56 : 0 : return rc;
57 : : }
58 : :
59 : : /*
60 : : * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
61 : : */
62 : 0 : static inline int mls_context_cpy_low(struct context *dst, struct context *src)
63 : : {
64 : 0 : int rc;
65 : :
66 : 0 : dst->range.level[0].sens = src->range.level[0].sens;
67 : 0 : rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
68 [ # # ]: 0 : if (rc)
69 : 0 : goto out;
70 : :
71 : 0 : dst->range.level[1].sens = src->range.level[0].sens;
72 : 0 : rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
73 [ # # ]: 0 : if (rc)
74 : 0 : ebitmap_destroy(&dst->range.level[0].cat);
75 : 0 : out:
76 : 0 : return rc;
77 : : }
78 : :
79 : : /*
80 : : * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
81 : : */
82 : 0 : static inline int mls_context_cpy_high(struct context *dst, struct context *src)
83 : : {
84 : 0 : int rc;
85 : :
86 : 0 : dst->range.level[0].sens = src->range.level[1].sens;
87 : 0 : rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
88 [ # # ]: 0 : if (rc)
89 : 0 : goto out;
90 : :
91 : 0 : dst->range.level[1].sens = src->range.level[1].sens;
92 : 0 : rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
93 [ # # ]: 0 : if (rc)
94 : 0 : ebitmap_destroy(&dst->range.level[0].cat);
95 : 0 : out:
96 : 0 : return rc;
97 : : }
98 : :
99 : :
100 : 0 : static inline int mls_context_glblub(struct context *dst,
101 : : struct context *c1, struct context *c2)
102 : : {
103 : 0 : struct mls_range *dr = &dst->range, *r1 = &c1->range, *r2 = &c2->range;
104 : 0 : int rc = 0;
105 : :
106 [ # # ]: 0 : if (r1->level[1].sens < r2->level[0].sens ||
107 [ # # ]: 0 : r2->level[1].sens < r1->level[0].sens)
108 : : /* These ranges have no common sensitivities */
109 : : return -EINVAL;
110 : :
111 : : /* Take the greatest of the low */
112 : 0 : dr->level[0].sens = max(r1->level[0].sens, r2->level[0].sens);
113 : :
114 : : /* Take the least of the high */
115 : 0 : dr->level[1].sens = min(r1->level[1].sens, r2->level[1].sens);
116 : :
117 : 0 : rc = ebitmap_and(&dr->level[0].cat,
118 : : &r1->level[0].cat, &r2->level[0].cat);
119 [ # # ]: 0 : if (rc)
120 : 0 : goto out;
121 : :
122 : 0 : rc = ebitmap_and(&dr->level[1].cat,
123 : : &r1->level[1].cat, &r2->level[1].cat);
124 [ # # ]: 0 : if (rc)
125 : 0 : goto out;
126 : :
127 : 0 : out:
128 : : return rc;
129 : : }
130 : :
131 : 0 : static inline int mls_context_cmp(struct context *c1, struct context *c2)
132 : : {
133 [ # # ]: 0 : return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
134 : 0 : ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
135 [ # # # # : 0 : (c1->range.level[1].sens == c2->range.level[1].sens) &&
# # ]
136 : 0 : ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
137 : : }
138 : :
139 : 0 : static inline void mls_context_destroy(struct context *c)
140 : : {
141 : 0 : ebitmap_destroy(&c->range.level[0].cat);
142 : 0 : ebitmap_destroy(&c->range.level[1].cat);
143 : 0 : mls_context_init(c);
144 : 0 : }
145 : :
146 : 0 : static inline void context_init(struct context *c)
147 : : {
148 : 0 : memset(c, 0, sizeof(*c));
149 : : }
150 : :
151 : 0 : static inline int context_cpy(struct context *dst, struct context *src)
152 : : {
153 : 0 : int rc;
154 : :
155 : 0 : dst->user = src->user;
156 : 0 : dst->role = src->role;
157 : 0 : dst->type = src->type;
158 [ # # ]: 0 : if (src->str) {
159 : 0 : dst->str = kstrdup(src->str, GFP_ATOMIC);
160 [ # # ]: 0 : if (!dst->str)
161 : : return -ENOMEM;
162 : 0 : dst->len = src->len;
163 : : } else {
164 : 0 : dst->str = NULL;
165 : 0 : dst->len = 0;
166 : : }
167 : 0 : rc = mls_context_cpy(dst, src);
168 [ # # ]: 0 : if (rc) {
169 : 0 : kfree(dst->str);
170 : 0 : return rc;
171 : : }
172 : 0 : dst->hash = src->hash;
173 : 0 : return 0;
174 : : }
175 : :
176 : 0 : static inline void context_destroy(struct context *c)
177 : : {
178 : 0 : c->user = c->role = c->type = c->hash = 0;
179 : 0 : kfree(c->str);
180 : 0 : c->str = NULL;
181 : 0 : c->len = 0;
182 : 0 : mls_context_destroy(c);
183 : 0 : }
184 : :
185 : 0 : static inline int context_cmp(struct context *c1, struct context *c2)
186 : : {
187 [ # # # # : 0 : if (c1->hash && c2->hash && (c1->hash != c2->hash))
# # ]
188 : : return 0;
189 [ # # # # ]: 0 : if (c1->len && c2->len)
190 [ # # # # ]: 0 : return (c1->len == c2->len && !strcmp(c1->str, c2->str));
191 [ # # # # ]: 0 : if (c1->len || c2->len)
192 : : return 0;
193 : 0 : return ((c1->user == c2->user) &&
194 : 0 : (c1->role == c2->role) &&
195 [ # # # # : 0 : (c1->type == c2->type) &&
# # ]
196 : 0 : mls_context_cmp(c1, c2));
197 : : }
198 : :
199 : 0 : static inline unsigned int context_compute_hash(const char *s)
200 : : {
201 : 0 : return full_name_hash(NULL, s, strlen(s));
202 : : }
203 : :
204 : : #endif /* _SS_CONTEXT_H_ */
205 : :
|