Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * A security context is a set of security attributes
0004  * associated with each subject and object controlled
0005  * by the security policy.  Security contexts are
0006   * externally represented as variable-length strings
0007  * that can be interpreted by a user or application
0008  * with an understanding of the security policy.
0009  * Internally, the security server uses a simple
0010  * structure.  This structure is private to the
0011  * security server and can be changed without affecting
0012  * clients of the security server.
0013  *
0014  * Author : Stephen Smalley, <sds@tycho.nsa.gov>
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  * A security context consists of an authenticated user
0025  * identity, a role, a type and a MLS range.
0026  */
0027 struct context {
0028     u32 user;
0029     u32 role;
0030     u32 type;
0031     u32 len;        /* length of string in bytes */
0032     struct mls_range range;
0033     char *str;  /* string representation if context cannot be mapped. */
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  * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
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  * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
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         /* These ranges have no common sensitivities */
0108         return -EINVAL;
0109 
0110     /* Take the greatest of the low */
0111     dr->level[0].sens = max(r1->level[0].sens, r2->level[0].sens);
0112 
0113     /* Take the least of the high */
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  /* _SS_CONTEXT_H_ */
0198