1/*
2 * This file describes the internal interface used by the AVC
3 * for calling the user-supplied memory allocation, supplemental
4 * auditing, and locking routine, as well as incrementing the
5 * statistics fields.
6 *
7 * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil>
8 */
9#ifndef _SELINUX_AVC_INTERNAL_H_
10#define _SELINUX_AVC_INTERNAL_H_
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <selinux/avc.h>
16#include "callbacks.h"
17
18/* callback pointers */
19extern void *(*avc_func_malloc) (size_t) ;
20extern void (*avc_func_free) (void *);
21
22extern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) ;
23extern void (*avc_func_audit) (void *, security_class_t, char *, size_t);
24
25extern int avc_using_threads ;
26extern int avc_app_main_loop ;
27extern void *(*avc_func_create_thread) (void (*)(void));
28extern void (*avc_func_stop_thread) (void *);
29
30extern void *(*avc_func_alloc_lock) (void);
31extern void (*avc_func_get_lock) (void *);
32extern void (*avc_func_release_lock) (void *);
33extern void (*avc_func_free_lock) (void *);
34
35/* selinux status processing for netlink and sestatus */
36extern int avc_process_setenforce(int enforcing);
37extern int avc_process_policyload(uint32_t seqno);
38
39static inline void set_callbacks(const struct avc_memory_callback *mem_cb,
40				 const struct avc_log_callback *log_cb,
41				 const struct avc_thread_callback *thread_cb,
42				 const struct avc_lock_callback *lock_cb)
43{
44	if (mem_cb) {
45		avc_func_malloc = mem_cb->func_malloc;
46		avc_func_free = mem_cb->func_free;
47	}
48	if (log_cb) {
49		avc_func_log = log_cb->func_log;
50		avc_func_audit = log_cb->func_audit;
51	}
52	if (thread_cb) {
53		avc_using_threads = 1;
54		avc_func_create_thread = thread_cb->func_create_thread;
55		avc_func_stop_thread = thread_cb->func_stop_thread;
56	}
57	if (lock_cb) {
58		avc_func_alloc_lock = lock_cb->func_alloc_lock;
59		avc_func_get_lock = lock_cb->func_get_lock;
60		avc_func_release_lock = lock_cb->func_release_lock;
61		avc_func_free_lock = lock_cb->func_free_lock;
62	}
63}
64
65/* message prefix and enforcing mode*/
66#define AVC_PREFIX_SIZE 16
67extern char avc_prefix[AVC_PREFIX_SIZE] ;
68extern int avc_running ;
69extern int avc_enforcing ;
70extern int avc_setenforce ;
71
72/* user-supplied callback interface for avc */
73static inline void *avc_malloc(size_t size)
74{
75	return avc_func_malloc ? avc_func_malloc(size) : malloc(size);
76}
77
78static inline void avc_free(void *ptr)
79{
80	if (avc_func_free)
81		avc_func_free(ptr);
82	else
83		free(ptr);
84}
85
86/* this is a macro in order to use the variadic capability. */
87#define avc_log(type, format...) \
88  do { \
89    if (avc_func_log) \
90      avc_func_log(format); \
91    else \
92      selinux_log(type, format); \
93  } while (0)
94
95static inline void avc_suppl_audit(void *ptr, security_class_t class,
96				   char *buf, size_t len)
97{
98	if (avc_func_audit)
99		avc_func_audit(ptr, class, buf, len);
100	else
101		selinux_audit(ptr, class, buf, len);
102}
103
104static inline void *avc_create_thread(void (*run) (void))
105{
106	return avc_func_create_thread ? avc_func_create_thread(run) : NULL;
107}
108
109static inline void avc_stop_thread(void *thread)
110{
111	if (avc_func_stop_thread)
112		avc_func_stop_thread(thread);
113}
114
115static inline void *avc_alloc_lock(void)
116{
117	return avc_func_alloc_lock ? avc_func_alloc_lock() : NULL;
118}
119
120static inline void avc_get_lock(void *lock)
121{
122	if (avc_func_get_lock)
123		avc_func_get_lock(lock);
124}
125
126static inline void avc_release_lock(void *lock)
127{
128	if (avc_func_release_lock)
129		avc_func_release_lock(lock);
130}
131
132static inline void avc_free_lock(void *lock)
133{
134	if (avc_func_free_lock)
135		avc_func_free_lock(lock);
136}
137
138/* statistics helper routines */
139#ifdef AVC_CACHE_STATS
140
141#define avc_cache_stats_incr(field) \
142  do { \
143    cache_stats.field ++; \
144  } while (0)
145#define avc_cache_stats_add(field, num) \
146  do { \
147    cache_stats.field += num; \
148  } while (0)
149
150#else
151
152#define avc_cache_stats_incr(field) do {} while (0)
153#define avc_cache_stats_add(field, num) do {} while (0)
154
155#endif
156
157/* logging helper routines */
158#define AVC_AUDIT_BUFSIZE 1024
159
160/* again, we need the variadic capability here */
161#define log_append(buf,format...) \
162  snprintf(buf+strlen(buf), AVC_AUDIT_BUFSIZE-strlen(buf), format)
163
164/* internal callbacks */
165int avc_ss_grant(security_id_t ssid, security_id_t tsid,
166		 security_class_t tclass, access_vector_t perms,
167		 uint32_t seqno) ;
168int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
169		      security_class_t tclass,
170		      access_vector_t perms, uint32_t seqno,
171		      access_vector_t * out_retained) ;
172int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
173		  security_class_t tclass, access_vector_t perms,
174		  uint32_t seqno) ;
175int avc_ss_reset(uint32_t seqno) ;
176int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
177			  security_class_t tclass, access_vector_t perms,
178			  uint32_t seqno, uint32_t enable) ;
179int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
180			 security_class_t tclass, access_vector_t perms,
181			 uint32_t seqno, uint32_t enable) ;
182
183#endif				/* _SELINUX_AVC_INTERNAL_H_ */
184