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