0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef _SS_CONTEXT_H_
0017 #define _SS_CONTEXT_H_
0018
0019 #include "ebitmap.h"
0020 #include "mls_types.h"
0021 #include "security.h"
0022
0023
0024
0025
0026
0027 struct context {
0028 u32 user;
0029 u32 role;
0030 u32 type;
0031 u32 len;
0032 struct mls_range range;
0033 char *str;
0034 };
0035
0036 static inline void mls_context_init(struct context *c)
0037 {
0038 memset(&c->range, 0, sizeof(c->range));
0039 }
0040
0041 static inline int mls_context_cpy(struct context *dst, struct context *src)
0042 {
0043 int rc;
0044
0045 dst->range.level[0].sens = src->range.level[0].sens;
0046 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
0047 if (rc)
0048 goto out;
0049
0050 dst->range.level[1].sens = src->range.level[1].sens;
0051 rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
0052 if (rc)
0053 ebitmap_destroy(&dst->range.level[0].cat);
0054 out:
0055 return rc;
0056 }
0057
0058
0059
0060
0061 static inline int mls_context_cpy_low(struct context *dst, struct context *src)
0062 {
0063 int rc;
0064
0065 dst->range.level[0].sens = src->range.level[0].sens;
0066 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
0067 if (rc)
0068 goto out;
0069
0070 dst->range.level[1].sens = src->range.level[0].sens;
0071 rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
0072 if (rc)
0073 ebitmap_destroy(&dst->range.level[0].cat);
0074 out:
0075 return rc;
0076 }
0077
0078
0079
0080
0081 static inline int mls_context_cpy_high(struct context *dst, struct context *src)
0082 {
0083 int rc;
0084
0085 dst->range.level[0].sens = src->range.level[1].sens;
0086 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
0087 if (rc)
0088 goto out;
0089
0090 dst->range.level[1].sens = src->range.level[1].sens;
0091 rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
0092 if (rc)
0093 ebitmap_destroy(&dst->range.level[0].cat);
0094 out:
0095 return rc;
0096 }
0097
0098
0099 static inline int mls_context_glblub(struct context *dst,
0100 struct context *c1, struct context *c2)
0101 {
0102 struct mls_range *dr = &dst->range, *r1 = &c1->range, *r2 = &c2->range;
0103 int rc = 0;
0104
0105 if (r1->level[1].sens < r2->level[0].sens ||
0106 r2->level[1].sens < r1->level[0].sens)
0107
0108 return -EINVAL;
0109
0110
0111 dr->level[0].sens = max(r1->level[0].sens, r2->level[0].sens);
0112
0113
0114 dr->level[1].sens = min(r1->level[1].sens, r2->level[1].sens);
0115
0116 rc = ebitmap_and(&dr->level[0].cat,
0117 &r1->level[0].cat, &r2->level[0].cat);
0118 if (rc)
0119 goto out;
0120
0121 rc = ebitmap_and(&dr->level[1].cat,
0122 &r1->level[1].cat, &r2->level[1].cat);
0123 if (rc)
0124 goto out;
0125
0126 out:
0127 return rc;
0128 }
0129
0130 static inline int mls_context_cmp(struct context *c1, struct context *c2)
0131 {
0132 return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
0133 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
0134 (c1->range.level[1].sens == c2->range.level[1].sens) &&
0135 ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
0136 }
0137
0138 static inline void mls_context_destroy(struct context *c)
0139 {
0140 ebitmap_destroy(&c->range.level[0].cat);
0141 ebitmap_destroy(&c->range.level[1].cat);
0142 mls_context_init(c);
0143 }
0144
0145 static inline void context_init(struct context *c)
0146 {
0147 memset(c, 0, sizeof(*c));
0148 }
0149
0150 static inline int context_cpy(struct context *dst, struct context *src)
0151 {
0152 int rc;
0153
0154 dst->user = src->user;
0155 dst->role = src->role;
0156 dst->type = src->type;
0157 if (src->str) {
0158 dst->str = kstrdup(src->str, GFP_ATOMIC);
0159 if (!dst->str)
0160 return -ENOMEM;
0161 dst->len = src->len;
0162 } else {
0163 dst->str = NULL;
0164 dst->len = 0;
0165 }
0166 rc = mls_context_cpy(dst, src);
0167 if (rc) {
0168 kfree(dst->str);
0169 return rc;
0170 }
0171 return 0;
0172 }
0173
0174 static inline void context_destroy(struct context *c)
0175 {
0176 c->user = c->role = c->type = 0;
0177 kfree(c->str);
0178 c->str = NULL;
0179 c->len = 0;
0180 mls_context_destroy(c);
0181 }
0182
0183 static inline int context_cmp(struct context *c1, struct context *c2)
0184 {
0185 if (c1->len && c2->len)
0186 return (c1->len == c2->len && !strcmp(c1->str, c2->str));
0187 if (c1->len || c2->len)
0188 return 0;
0189 return ((c1->user == c2->user) &&
0190 (c1->role == c2->role) &&
0191 (c1->type == c2->type) &&
0192 mls_context_cmp(c1, c2));
0193 }
0194
0195 u32 context_compute_hash(const struct context *c);
0196
0197 #endif
0198