xref: /linux/security/selinux/ss/context.h (revision aa893269de6277b44be88e25dcd5331c934c29c4)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * A security context is a set of security attributes
31da177e4SLinus Torvalds  * associated with each subject and object controlled
41da177e4SLinus Torvalds  * by the security policy.  Security contexts are
51da177e4SLinus Torvalds   * externally represented as variable-length strings
61da177e4SLinus Torvalds  * that can be interpreted by a user or application
71da177e4SLinus Torvalds  * with an understanding of the security policy.
81da177e4SLinus Torvalds  * Internally, the security server uses a simple
91da177e4SLinus Torvalds  * structure.  This structure is private to the
101da177e4SLinus Torvalds  * security server and can be changed without affecting
111da177e4SLinus Torvalds  * clients of the security server.
121da177e4SLinus Torvalds  *
131da177e4SLinus Torvalds  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
141da177e4SLinus Torvalds  */
151da177e4SLinus Torvalds #ifndef _SS_CONTEXT_H_
161da177e4SLinus Torvalds #define _SS_CONTEXT_H_
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds #include "ebitmap.h"
191da177e4SLinus Torvalds #include "mls_types.h"
201da177e4SLinus Torvalds #include "security.h"
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds /*
231da177e4SLinus Torvalds  * A security context consists of an authenticated user
241da177e4SLinus Torvalds  * identity, a role, a type and a MLS range.
251da177e4SLinus Torvalds  */
261da177e4SLinus Torvalds struct context {
271da177e4SLinus Torvalds 	u32 user;
281da177e4SLinus Torvalds 	u32 role;
291da177e4SLinus Torvalds 	u32 type;
3076f7ba35SEric Paris 	u32 len;        /* length of string in bytes */
311da177e4SLinus Torvalds 	struct mls_range range;
3212b29f34SStephen Smalley 	char *str;	/* string representation if context cannot be mapped. */
331da177e4SLinus Torvalds };
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds static inline void mls_context_init(struct context *c)
361da177e4SLinus Torvalds {
371da177e4SLinus Torvalds 	memset(&c->range, 0, sizeof(c->range));
381da177e4SLinus Torvalds }
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds static inline int mls_context_cpy(struct context *dst, struct context *src)
411da177e4SLinus Torvalds {
421da177e4SLinus Torvalds 	int rc;
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds 	dst->range.level[0].sens = src->range.level[0].sens;
451da177e4SLinus Torvalds 	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
461da177e4SLinus Torvalds 	if (rc)
471da177e4SLinus Torvalds 		goto out;
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds 	dst->range.level[1].sens = src->range.level[1].sens;
501da177e4SLinus Torvalds 	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
511da177e4SLinus Torvalds 	if (rc)
521da177e4SLinus Torvalds 		ebitmap_destroy(&dst->range.level[0].cat);
531da177e4SLinus Torvalds out:
541da177e4SLinus Torvalds 	return rc;
551da177e4SLinus Torvalds }
561da177e4SLinus Torvalds 
570efc61eaSVenkat Yekkirala /*
580efc61eaSVenkat Yekkirala  * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
590efc61eaSVenkat Yekkirala  */
600efc61eaSVenkat Yekkirala static inline int mls_context_cpy_low(struct context *dst, struct context *src)
610efc61eaSVenkat Yekkirala {
620efc61eaSVenkat Yekkirala 	int rc;
630efc61eaSVenkat Yekkirala 
640efc61eaSVenkat Yekkirala 	dst->range.level[0].sens = src->range.level[0].sens;
650efc61eaSVenkat Yekkirala 	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
660efc61eaSVenkat Yekkirala 	if (rc)
670efc61eaSVenkat Yekkirala 		goto out;
680efc61eaSVenkat Yekkirala 
690efc61eaSVenkat Yekkirala 	dst->range.level[1].sens = src->range.level[0].sens;
700efc61eaSVenkat Yekkirala 	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
710efc61eaSVenkat Yekkirala 	if (rc)
720efc61eaSVenkat Yekkirala 		ebitmap_destroy(&dst->range.level[0].cat);
730efc61eaSVenkat Yekkirala out:
740efc61eaSVenkat Yekkirala 	return rc;
750efc61eaSVenkat Yekkirala }
760efc61eaSVenkat Yekkirala 
77*aa893269SEric Paris /*
78*aa893269SEric Paris  * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
79*aa893269SEric Paris  */
80*aa893269SEric Paris static inline int mls_context_cpy_high(struct context *dst, struct context *src)
81*aa893269SEric Paris {
82*aa893269SEric Paris 	int rc;
83*aa893269SEric Paris 
84*aa893269SEric Paris 	dst->range.level[0].sens = src->range.level[1].sens;
85*aa893269SEric Paris 	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
86*aa893269SEric Paris 	if (rc)
87*aa893269SEric Paris 		goto out;
88*aa893269SEric Paris 
89*aa893269SEric Paris 	dst->range.level[1].sens = src->range.level[1].sens;
90*aa893269SEric Paris 	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
91*aa893269SEric Paris 	if (rc)
92*aa893269SEric Paris 		ebitmap_destroy(&dst->range.level[0].cat);
93*aa893269SEric Paris out:
94*aa893269SEric Paris 	return rc;
95*aa893269SEric Paris }
96*aa893269SEric Paris 
971da177e4SLinus Torvalds static inline int mls_context_cmp(struct context *c1, struct context *c2)
981da177e4SLinus Torvalds {
991da177e4SLinus Torvalds 	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
1001da177e4SLinus Torvalds 		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
1011da177e4SLinus Torvalds 		(c1->range.level[1].sens == c2->range.level[1].sens) &&
1021da177e4SLinus Torvalds 		ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
1031da177e4SLinus Torvalds }
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds static inline void mls_context_destroy(struct context *c)
1061da177e4SLinus Torvalds {
1071da177e4SLinus Torvalds 	ebitmap_destroy(&c->range.level[0].cat);
1081da177e4SLinus Torvalds 	ebitmap_destroy(&c->range.level[1].cat);
1091da177e4SLinus Torvalds 	mls_context_init(c);
1101da177e4SLinus Torvalds }
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds static inline void context_init(struct context *c)
1131da177e4SLinus Torvalds {
1141da177e4SLinus Torvalds 	memset(c, 0, sizeof(*c));
1151da177e4SLinus Torvalds }
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds static inline int context_cpy(struct context *dst, struct context *src)
1181da177e4SLinus Torvalds {
11912b29f34SStephen Smalley 	int rc;
12012b29f34SStephen Smalley 
1211da177e4SLinus Torvalds 	dst->user = src->user;
1221da177e4SLinus Torvalds 	dst->role = src->role;
1231da177e4SLinus Torvalds 	dst->type = src->type;
12412b29f34SStephen Smalley 	if (src->str) {
12512b29f34SStephen Smalley 		dst->str = kstrdup(src->str, GFP_ATOMIC);
12612b29f34SStephen Smalley 		if (!dst->str)
12712b29f34SStephen Smalley 			return -ENOMEM;
12812b29f34SStephen Smalley 		dst->len = src->len;
12912b29f34SStephen Smalley 	} else {
13012b29f34SStephen Smalley 		dst->str = NULL;
13112b29f34SStephen Smalley 		dst->len = 0;
13212b29f34SStephen Smalley 	}
13312b29f34SStephen Smalley 	rc = mls_context_cpy(dst, src);
13412b29f34SStephen Smalley 	if (rc) {
13512b29f34SStephen Smalley 		kfree(dst->str);
13612b29f34SStephen Smalley 		return rc;
13712b29f34SStephen Smalley 	}
13812b29f34SStephen Smalley 	return 0;
1391da177e4SLinus Torvalds }
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds static inline void context_destroy(struct context *c)
1421da177e4SLinus Torvalds {
1431da177e4SLinus Torvalds 	c->user = c->role = c->type = 0;
14412b29f34SStephen Smalley 	kfree(c->str);
14512b29f34SStephen Smalley 	c->str = NULL;
14612b29f34SStephen Smalley 	c->len = 0;
1471da177e4SLinus Torvalds 	mls_context_destroy(c);
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds static inline int context_cmp(struct context *c1, struct context *c2)
1511da177e4SLinus Torvalds {
15212b29f34SStephen Smalley 	if (c1->len && c2->len)
15312b29f34SStephen Smalley 		return (c1->len == c2->len && !strcmp(c1->str, c2->str));
15412b29f34SStephen Smalley 	if (c1->len || c2->len)
15512b29f34SStephen Smalley 		return 0;
1561da177e4SLinus Torvalds 	return ((c1->user == c2->user) &&
1571da177e4SLinus Torvalds 		(c1->role == c2->role) &&
1581da177e4SLinus Torvalds 		(c1->type == c2->type) &&
1591da177e4SLinus Torvalds 		mls_context_cmp(c1, c2));
1601da177e4SLinus Torvalds }
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds #endif	/* _SS_CONTEXT_H_ */
1631da177e4SLinus Torvalds 
164