summaryrefslogtreecommitdiff
path: root/security/selinux/include/security.h
blob: d91a5672de99114ee05d57fcd6d0c07fe80864a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Security server interface.
 *
 * Author : Stephen Smalley, <sds@tycho.nsa.gov>
 *
 */

#ifndef _SELINUX_SECURITY_H_
#define _SELINUX_SECURITY_H_

#include <linux/compiler.h>
#include <linux/dcache.h>
#include <linux/magic.h>
#include <linux/types.h>
#include <linux/rcupdate.h>
#include <linux/refcount.h>
#include <linux/workqueue.h>
#include "flask.h"
#include "policycap.h"

#define SECSID_NULL			0x00000000 /* unspecified SID */
#define SECSID_WILD			0xffffffff /* wildcard SID */
#define SECCLASS_NULL			0x0000 /* no class */

/* Identify specific policy version changes */
#define POLICYDB_VERSION_BASE		15
#define POLICYDB_VERSION_BOOL		16
#define POLICYDB_VERSION_IPV6		17
#define POLICYDB_VERSION_NLCLASS	18
#define POLICYDB_VERSION_VALIDATETRANS	19
#define POLICYDB_VERSION_MLS		19
#define POLICYDB_VERSION_AVTAB		20
#define POLICYDB_VERSION_RANGETRANS	21
#define POLICYDB_VERSION_POLCAP		22
#define POLICYDB_VERSION_PERMISSIVE	23
#define POLICYDB_VERSION_BOUNDARY	24
#define POLICYDB_VERSION_FILENAME_TRANS	25
#define POLICYDB_VERSION_ROLETRANS	26
#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27
#define POLICYDB_VERSION_DEFAULT_TYPE	28
#define POLICYDB_VERSION_CONSTRAINT_NAMES	29
#define POLICYDB_VERSION_XPERMS_IOCTL	30
#define POLICYDB_VERSION_INFINIBAND		31
#define POLICYDB_VERSION_GLBLUB		32
#define POLICYDB_VERSION_COMP_FTRANS	33 /* compressed filename transitions */

/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_COMP_FTRANS

/* Mask for just the mount related flags */
#define SE_MNTMASK	0x0f
/* Super block security struct flags for mount options */
/* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */
#define CONTEXT_MNT	0x01
#define FSCONTEXT_MNT	0x02
#define ROOTCONTEXT_MNT	0x04
#define DEFCONTEXT_MNT	0x08
#define SBLABEL_MNT	0x10
/* Non-mount related flags */
#define SE_SBINITIALIZED	0x0100
#define SE_SBPROC		0x0200
#define SE_SBGENFS		0x0400
#define SE_SBGENFS_XATTR	0x0800

#define CONTEXT_STR	"context"
#define FSCONTEXT_STR	"fscontext"
#define ROOTCONTEXT_STR	"rootcontext"
#define DEFCONTEXT_STR	"defcontext"
#define SECLABEL_STR "seclabel"

struct netlbl_lsm_secattr;

extern int selinux_enabled_boot;

/*
 * type_datum properties
 * available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY
 */
#define TYPEDATUM_PROPERTY_PRIMARY	0x0001
#define TYPEDATUM_PROPERTY_ATTRIBUTE	0x0002

/* limitation of boundary depth  */
#define POLICYDB_BOUNDS_MAXDEPTH	4

struct selinux_avc;
struct selinux_policy;

struct selinux_state {
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
	bool disabled;
#endif
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
	bool enforcing;
#endif
	bool checkreqprot;
	bool initialized;
	bool policycap[__POLICYDB_CAPABILITY_MAX];

	struct page *status_page;
	struct mutex status_lock;

	struct selinux_avc *avc;
	struct selinux_policy __rcu *policy;
	struct mutex policy_mutex;
} __randomize_layout;

void selinux_avc_init(struct selinux_avc **avc);

extern struct selinux_state selinux_state;

static inline bool selinux_initialized(const struct selinux_state *state)
{
	/* do a synchronized load to avoid race conditions */
	return smp_load_acquire(&state->initialized);
}

static inline void selinux_mark_initialized(struct selinux_state *state)
{
	/* do a synchronized write to avoid race conditions */
	smp_store_release(&state->initialized, true);
}

#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
static inline bool enforcing_enabled(struct selinux_state *state)
{
	return READ_ONCE(state->enforcing);
}

static inline void enforcing_set(struct selinux_state *state, bool value)
{
	WRITE_ONCE(state->enforcing, value);
}
#else
static inline bool enforcing_enabled(struct selinux_state *state)
{
	return true;
}

static inline void enforcing_set(struct selinux_state *state, bool value)
{
}
#endif

static inline bool checkreqprot_get(const struct selinux_state *state)
{
	return READ_ONCE(state->checkreqprot);
}

static inline void checkreqprot_set(struct selinux_state *state, bool value)
{
	WRITE_ONCE(state->checkreqprot, value);
}

#ifdef CONFIG_SECURITY_SELINUX_DISABLE
static inline bool selinux_disabled(struct selinux_state *state)
{
	return READ_ONCE(state->disabled);
}

static inline void selinux_mark_disabled(struct selinux_state *state)
{
	WRITE_ONCE(state->disabled, true);
}
#else
static inline bool selinux_disabled(struct selinux_state *state)
{
	return false;
}
#endif

static inline bool selinux_policycap_netpeer(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NETPEER]);
}

static inline bool selinux_policycap_openperm(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_OPENPERM]);
}

static inline bool selinux_policycap_extsockclass(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS]);
}

static inline bool selinux_policycap_alwaysnetwork(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK]);
}

static inline bool selinux_policycap_cgroupseclabel(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL]);
}

static inline bool selinux_policycap_nnp_nosuid_transition(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION]);
}

static inline bool selinux_policycap_genfs_seclabel_symlinks(void)
{
	struct selinux_state *state = &selinux_state;

	return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]);
}

struct selinux_policy_convert_data;

struct selinux_load_state {
	struct selinux_policy *policy;
	struct selinux_policy_convert_data *convert_data;
};

int security_mls_enabled(struct selinux_state *state);
int security_load_policy(struct selinux_state *state,
			 void *data, size_t len,
			 struct selinux_load_state *load_state);
void selinux_policy_commit(struct selinux_state *state,
			   struct selinux_load_state *load_state);
void selinux_policy_cancel(struct selinux_state *state,
			   struct selinux_load_state *load_state);
int security_read_policy(struct selinux_state *state,
			 void **data, size_t *len);
int security_read_state_kernel(struct selinux_state *state,
			       void **data, size_t *len);
int security_policycap_supported(struct selinux_state *state,
				 unsigned int req_cap);

#define SEL_VEC_MAX 32
struct av_decision {
	u32 allowed;
	u32 auditallow;
	u32 auditdeny;
	u32 seqno;
	u32 flags;
};

#define XPERMS_ALLOWED 1
#define XPERMS_AUDITALLOW 2
#define XPERMS_DONTAUDIT 4

#define security_xperm_set(perms, x) ((perms)[(x) >> 5] |= 1 << ((x) & 0x1f))
#define security_xperm_test(perms, x) (1 & ((perms)[(x) >> 5] >> ((x) & 0x1f)))
struct extended_perms_data {
	u32 p[8];
};

struct extended_perms_decision {
	u8 used;
	u8 driver;
	struct extended_perms_data *allowed;
	struct extended_perms_data *auditallow;
	struct extended_perms_data *dontaudit;
};

struct extended_perms {
	u16 len;	/* length associated decision chain */
	struct extended_perms_data drivers; /* flag drivers that are used */
};

/* definitions of av_decision.flags */
#define AVD_FLAGS_PERMISSIVE	0x0001

void security_compute_av(struct selinux_state *state,
			 u32 ssid, u32 tsid,
			 u16 tclass, struct av_decision *avd,
			 struct extended_perms *xperms);

void security_compute_xperms_decision(struct selinux_state *state,
				      u32 ssid, u32 tsid, u16 tclass,
				      u8 driver,
				      struct extended_perms_decision *xpermd);

void security_compute_av_user(struct selinux_state *state,
			      u32 ssid, u32 tsid,
			      u16 tclass, struct av_decision *avd);

int security_transition_sid(struct selinux_state *state,
			    u32 ssid, u32 tsid, u16 tclass,
			    const struct qstr *qstr, u32 *out_sid);

int security_transition_sid_user(struct selinux_state *state,
				 u32 ssid, u32 tsid, u16 tclass,
				 const char *objname, u32 *out_sid);

int security_member_sid(struct selinux_state *state, u32 ssid, u32 tsid,
			u16 tclass, u32 *out_sid);

int security_change_sid(struct selinux_state *state, u32 ssid, u32 tsid,
			u16 tclass, u32 *out_sid);

int security_sid_to_context(struct selinux_state *state, u32 sid,
			    char **scontext, u32 *scontext_len);

int security_sid_to_context_force(struct selinux_state *state,
				  u32 sid, char **scontext, u32 *scontext_len);

int security_sid_to_context_inval(struct selinux_state *state,
				  u32 sid, char **scontext, u32 *scontext_len);

int security_context_to_sid(struct selinux_state *state,
			    const char *scontext, u32 scontext_len,
			    u32 *out_sid, gfp_t gfp);

int security_context_str_to_sid(struct selinux_state *state,
				const char *scontext, u32 *out_sid, gfp_t gfp);

int security_context_to_sid_default(struct selinux_state *state,
				    const char *scontext, u32 scontext_len,
				    u32 *out_sid, u32 def_sid, gfp_t gfp_flags);

int security_context_to_sid_force(struct selinux_state *state,
				  const char *scontext, u32 scontext_len,
				  u32 *sid);

int security_get_user_sids(struct selinux_state *state,
			   u32 callsid, char *username,
			   u32 **sids, u32 *nel);

int security_port_sid(struct selinux_state *state,
		      u8 protocol, u16 port, u32 *out_sid);

int security_ib_pkey_sid(struct selinux_state *state,
			 u64 subnet_prefix, u16 pkey_num, u32 *out_sid);

int security_ib_endport_sid(struct selinux_state *state,
			    const char *dev_name, u8 port_num, u32 *out_sid);

int security_netif_sid(struct selinux_state *state,
		       char *name, u32 *if_sid);

int security_node_sid(struct selinux_state *state,
		      u16 domain, void *addr, u32 addrlen,
		      u32 *out_sid);

int security_validate_transition(struct selinux_state *state,
				 u32 oldsid, u32 newsid, u32 tasksid,
				 u16 tclass);

int security_validate_transition_user(struct selinux_state *state,
				      u32 oldsid, u32 newsid, u32 tasksid,
				      u16 tclass);

int security_bounded_transition(struct selinux_state *state,
				u32 oldsid, u32 newsid);

int security_sid_mls_copy(struct selinux_state *state,
			  u32 sid, u32 mls_sid, u32 *new_sid);

int security_net_peersid_resolve(struct selinux_state *state,
				 u32 nlbl_sid, u32 nlbl_type,
				 u32 xfrm_sid,
				 u32 *peer_sid);

int security_get_classes(struct selinux_policy *policy,
			 char ***classes, int *nclasses);
int security_get_permissions(struct selinux_policy *policy,
			     char *class, char ***perms, int *nperms);
int security_get_reject_unknown(struct selinux_state *state);
int security_get_allow_unknown(struct selinux_state *state);

#define SECURITY_FS_USE_XATTR		1 /* use xattr */
#define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
#define SECURITY_FS_USE_TASK		3 /* use task SIDs, e.g. pipefs/sockfs */
#define SECURITY_FS_USE_GENFS		4 /* use the genfs support */
#define SECURITY_FS_USE_NONE		5 /* no labeling support */
#define SECURITY_FS_USE_MNTPOINT	6 /* use mountpoint labeling */
#define SECURITY_FS_USE_NATIVE		7 /* use native label support */
#define SECURITY_FS_USE_MAX		7 /* Highest SECURITY_FS_USE_XXX */

int security_fs_use(struct selinux_state *state, struct super_block *sb);

int security_genfs_sid(struct selinux_state *state,
		       const char *fstype, const char *path, u16 sclass,
		       u32 *sid);

int selinux_policy_genfs_sid(struct selinux_policy *policy,
		       const char *fstype, const char *path, u16 sclass,
		       u32 *sid);

#ifdef CONFIG_NETLABEL
int security_netlbl_secattr_to_sid(struct selinux_state *state,
				   struct netlbl_lsm_secattr *secattr,
				   u32 *sid);

int security_netlbl_sid_to_secattr(struct selinux_state *state,
				   u32 sid,
				   struct netlbl_lsm_secattr *secattr);
#else
static inline int security_netlbl_secattr_to_sid(struct selinux_state *state,
					    struct netlbl_lsm_secattr *secattr,
					    u32 *sid)
{
	return -EIDRM;
}

static inline int security_netlbl_sid_to_secattr(struct selinux_state *state,
					 u32 sid,
					 struct netlbl_lsm_secattr *secattr)
{
	return -ENOENT;
}
#endif /* CONFIG_NETLABEL */

const char *security_get_initial_sid_context(u32 sid);

/*
 * status notifier using mmap interface
 */
extern struct page *selinux_kernel_status_page(struct selinux_state *state);

#define SELINUX_KERNEL_STATUS_VERSION	1
struct selinux_kernel_status {
	u32	version;	/* version number of the structure */
	u32	sequence;	/* sequence number of seqlock logic */
	u32	enforcing;	/* current setting of enforcing mode */
	u32	policyload;	/* times of policy reloaded */
	u32	deny_unknown;	/* current setting of deny_unknown */
	/*
	 * The version > 0 supports above members.
	 */
} __packed;

extern void selinux_status_update_setenforce(struct selinux_state *state,
					     int enforcing);
extern void selinux_status_update_policyload(struct selinux_state *state,
					     int seqno);
extern void selinux_complete_init(void);
extern int selinux_disable(struct selinux_state *state);
extern void exit_sel_fs(void);
extern struct path selinux_null;
extern void selnl_notify_setenforce(int val);
extern void selnl_notify_policyload(u32 seqno);
extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);

extern void avtab_cache_init(void);
extern void ebitmap_cache_init(void);
extern void hashtab_cache_init(void);
extern int security_sidtab_hash_stats(struct selinux_state *state, char *page);

#endif /* _SELINUX_SECURITY_H_ */