16cd6a6acSopenharmony_ci/*
26cd6a6acSopenharmony_ci * This file describes the internal interface used by the AVC
36cd6a6acSopenharmony_ci * for calling the user-supplied memory allocation, supplemental
46cd6a6acSopenharmony_ci * auditing, and locking routine, as well as incrementing the
56cd6a6acSopenharmony_ci * statistics fields.
66cd6a6acSopenharmony_ci *
76cd6a6acSopenharmony_ci * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil>
86cd6a6acSopenharmony_ci */
96cd6a6acSopenharmony_ci#ifndef _SELINUX_AVC_INTERNAL_H_
106cd6a6acSopenharmony_ci#define _SELINUX_AVC_INTERNAL_H_
116cd6a6acSopenharmony_ci
126cd6a6acSopenharmony_ci#include <stdio.h>
136cd6a6acSopenharmony_ci#include <stdlib.h>
146cd6a6acSopenharmony_ci#include <string.h>
156cd6a6acSopenharmony_ci#include <selinux/avc.h>
166cd6a6acSopenharmony_ci#include "callbacks.h"
176cd6a6acSopenharmony_ci
186cd6a6acSopenharmony_ci/* callback pointers */
196cd6a6acSopenharmony_ciextern void *(*avc_func_malloc) (size_t) ;
206cd6a6acSopenharmony_ciextern void (*avc_func_free) (void *);
216cd6a6acSopenharmony_ci
226cd6a6acSopenharmony_ciextern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) ;
236cd6a6acSopenharmony_ciextern void (*avc_func_audit) (void *, security_class_t, char *, size_t);
246cd6a6acSopenharmony_ci
256cd6a6acSopenharmony_ciextern int avc_using_threads ;
266cd6a6acSopenharmony_ciextern int avc_app_main_loop ;
276cd6a6acSopenharmony_ciextern void *(*avc_func_create_thread) (void (*)(void));
286cd6a6acSopenharmony_ciextern void (*avc_func_stop_thread) (void *);
296cd6a6acSopenharmony_ci
306cd6a6acSopenharmony_ciextern void *(*avc_func_alloc_lock) (void);
316cd6a6acSopenharmony_ciextern void (*avc_func_get_lock) (void *);
326cd6a6acSopenharmony_ciextern void (*avc_func_release_lock) (void *);
336cd6a6acSopenharmony_ciextern void (*avc_func_free_lock) (void *);
346cd6a6acSopenharmony_ci
356cd6a6acSopenharmony_ci/* selinux status processing for netlink and sestatus */
366cd6a6acSopenharmony_ciextern int avc_process_setenforce(int enforcing);
376cd6a6acSopenharmony_ciextern int avc_process_policyload(uint32_t seqno);
386cd6a6acSopenharmony_ci
396cd6a6acSopenharmony_cistatic inline void set_callbacks(const struct avc_memory_callback *mem_cb,
406cd6a6acSopenharmony_ci				 const struct avc_log_callback *log_cb,
416cd6a6acSopenharmony_ci				 const struct avc_thread_callback *thread_cb,
426cd6a6acSopenharmony_ci				 const struct avc_lock_callback *lock_cb)
436cd6a6acSopenharmony_ci{
446cd6a6acSopenharmony_ci	if (mem_cb) {
456cd6a6acSopenharmony_ci		avc_func_malloc = mem_cb->func_malloc;
466cd6a6acSopenharmony_ci		avc_func_free = mem_cb->func_free;
476cd6a6acSopenharmony_ci	}
486cd6a6acSopenharmony_ci	if (log_cb) {
496cd6a6acSopenharmony_ci		avc_func_log = log_cb->func_log;
506cd6a6acSopenharmony_ci		avc_func_audit = log_cb->func_audit;
516cd6a6acSopenharmony_ci	}
526cd6a6acSopenharmony_ci	if (thread_cb) {
536cd6a6acSopenharmony_ci		avc_using_threads = 1;
546cd6a6acSopenharmony_ci		avc_func_create_thread = thread_cb->func_create_thread;
556cd6a6acSopenharmony_ci		avc_func_stop_thread = thread_cb->func_stop_thread;
566cd6a6acSopenharmony_ci	}
576cd6a6acSopenharmony_ci	if (lock_cb) {
586cd6a6acSopenharmony_ci		avc_func_alloc_lock = lock_cb->func_alloc_lock;
596cd6a6acSopenharmony_ci		avc_func_get_lock = lock_cb->func_get_lock;
606cd6a6acSopenharmony_ci		avc_func_release_lock = lock_cb->func_release_lock;
616cd6a6acSopenharmony_ci		avc_func_free_lock = lock_cb->func_free_lock;
626cd6a6acSopenharmony_ci	}
636cd6a6acSopenharmony_ci}
646cd6a6acSopenharmony_ci
656cd6a6acSopenharmony_ci/* message prefix and enforcing mode*/
666cd6a6acSopenharmony_ci#define AVC_PREFIX_SIZE 16
676cd6a6acSopenharmony_ciextern char avc_prefix[AVC_PREFIX_SIZE] ;
686cd6a6acSopenharmony_ciextern int avc_running ;
696cd6a6acSopenharmony_ciextern int avc_enforcing ;
706cd6a6acSopenharmony_ciextern int avc_setenforce ;
716cd6a6acSopenharmony_ci
726cd6a6acSopenharmony_ci/* user-supplied callback interface for avc */
736cd6a6acSopenharmony_cistatic inline void *avc_malloc(size_t size)
746cd6a6acSopenharmony_ci{
756cd6a6acSopenharmony_ci	return avc_func_malloc ? avc_func_malloc(size) : malloc(size);
766cd6a6acSopenharmony_ci}
776cd6a6acSopenharmony_ci
786cd6a6acSopenharmony_cistatic inline void avc_free(void *ptr)
796cd6a6acSopenharmony_ci{
806cd6a6acSopenharmony_ci	if (avc_func_free)
816cd6a6acSopenharmony_ci		avc_func_free(ptr);
826cd6a6acSopenharmony_ci	else
836cd6a6acSopenharmony_ci		free(ptr);
846cd6a6acSopenharmony_ci}
856cd6a6acSopenharmony_ci
866cd6a6acSopenharmony_ci/* this is a macro in order to use the variadic capability. */
876cd6a6acSopenharmony_ci#define avc_log(type, format...) \
886cd6a6acSopenharmony_ci  do { \
896cd6a6acSopenharmony_ci    if (avc_func_log) \
906cd6a6acSopenharmony_ci      avc_func_log(format); \
916cd6a6acSopenharmony_ci    else \
926cd6a6acSopenharmony_ci      selinux_log(type, format); \
936cd6a6acSopenharmony_ci  } while (0)
946cd6a6acSopenharmony_ci
956cd6a6acSopenharmony_cistatic inline void avc_suppl_audit(void *ptr, security_class_t class,
966cd6a6acSopenharmony_ci				   char *buf, size_t len)
976cd6a6acSopenharmony_ci{
986cd6a6acSopenharmony_ci	if (avc_func_audit)
996cd6a6acSopenharmony_ci		avc_func_audit(ptr, class, buf, len);
1006cd6a6acSopenharmony_ci	else
1016cd6a6acSopenharmony_ci		selinux_audit(ptr, class, buf, len);
1026cd6a6acSopenharmony_ci}
1036cd6a6acSopenharmony_ci
1046cd6a6acSopenharmony_cistatic inline void *avc_create_thread(void (*run) (void))
1056cd6a6acSopenharmony_ci{
1066cd6a6acSopenharmony_ci	return avc_func_create_thread ? avc_func_create_thread(run) : NULL;
1076cd6a6acSopenharmony_ci}
1086cd6a6acSopenharmony_ci
1096cd6a6acSopenharmony_cistatic inline void avc_stop_thread(void *thread)
1106cd6a6acSopenharmony_ci{
1116cd6a6acSopenharmony_ci	if (avc_func_stop_thread)
1126cd6a6acSopenharmony_ci		avc_func_stop_thread(thread);
1136cd6a6acSopenharmony_ci}
1146cd6a6acSopenharmony_ci
1156cd6a6acSopenharmony_cistatic inline void *avc_alloc_lock(void)
1166cd6a6acSopenharmony_ci{
1176cd6a6acSopenharmony_ci	return avc_func_alloc_lock ? avc_func_alloc_lock() : NULL;
1186cd6a6acSopenharmony_ci}
1196cd6a6acSopenharmony_ci
1206cd6a6acSopenharmony_cistatic inline void avc_get_lock(void *lock)
1216cd6a6acSopenharmony_ci{
1226cd6a6acSopenharmony_ci	if (avc_func_get_lock)
1236cd6a6acSopenharmony_ci		avc_func_get_lock(lock);
1246cd6a6acSopenharmony_ci}
1256cd6a6acSopenharmony_ci
1266cd6a6acSopenharmony_cistatic inline void avc_release_lock(void *lock)
1276cd6a6acSopenharmony_ci{
1286cd6a6acSopenharmony_ci	if (avc_func_release_lock)
1296cd6a6acSopenharmony_ci		avc_func_release_lock(lock);
1306cd6a6acSopenharmony_ci}
1316cd6a6acSopenharmony_ci
1326cd6a6acSopenharmony_cistatic inline void avc_free_lock(void *lock)
1336cd6a6acSopenharmony_ci{
1346cd6a6acSopenharmony_ci	if (avc_func_free_lock)
1356cd6a6acSopenharmony_ci		avc_func_free_lock(lock);
1366cd6a6acSopenharmony_ci}
1376cd6a6acSopenharmony_ci
1386cd6a6acSopenharmony_ci/* statistics helper routines */
1396cd6a6acSopenharmony_ci#ifdef AVC_CACHE_STATS
1406cd6a6acSopenharmony_ci
1416cd6a6acSopenharmony_ci#define avc_cache_stats_incr(field) \
1426cd6a6acSopenharmony_ci  do { \
1436cd6a6acSopenharmony_ci    cache_stats.field ++; \
1446cd6a6acSopenharmony_ci  } while (0)
1456cd6a6acSopenharmony_ci#define avc_cache_stats_add(field, num) \
1466cd6a6acSopenharmony_ci  do { \
1476cd6a6acSopenharmony_ci    cache_stats.field += num; \
1486cd6a6acSopenharmony_ci  } while (0)
1496cd6a6acSopenharmony_ci
1506cd6a6acSopenharmony_ci#else
1516cd6a6acSopenharmony_ci
1526cd6a6acSopenharmony_ci#define avc_cache_stats_incr(field) do {} while (0)
1536cd6a6acSopenharmony_ci#define avc_cache_stats_add(field, num) do {} while (0)
1546cd6a6acSopenharmony_ci
1556cd6a6acSopenharmony_ci#endif
1566cd6a6acSopenharmony_ci
1576cd6a6acSopenharmony_ci/* logging helper routines */
1586cd6a6acSopenharmony_ci#define AVC_AUDIT_BUFSIZE 1024
1596cd6a6acSopenharmony_ci
1606cd6a6acSopenharmony_ci/* again, we need the variadic capability here */
1616cd6a6acSopenharmony_ci#define log_append(buf,format...) \
1626cd6a6acSopenharmony_ci  snprintf(buf+strlen(buf), AVC_AUDIT_BUFSIZE-strlen(buf), format)
1636cd6a6acSopenharmony_ci
1646cd6a6acSopenharmony_ci/* internal callbacks */
1656cd6a6acSopenharmony_ciint avc_ss_grant(security_id_t ssid, security_id_t tsid,
1666cd6a6acSopenharmony_ci		 security_class_t tclass, access_vector_t perms,
1676cd6a6acSopenharmony_ci		 uint32_t seqno) ;
1686cd6a6acSopenharmony_ciint avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
1696cd6a6acSopenharmony_ci		      security_class_t tclass,
1706cd6a6acSopenharmony_ci		      access_vector_t perms, uint32_t seqno,
1716cd6a6acSopenharmony_ci		      access_vector_t * out_retained) ;
1726cd6a6acSopenharmony_ciint avc_ss_revoke(security_id_t ssid, security_id_t tsid,
1736cd6a6acSopenharmony_ci		  security_class_t tclass, access_vector_t perms,
1746cd6a6acSopenharmony_ci		  uint32_t seqno) ;
1756cd6a6acSopenharmony_ciint avc_ss_reset(uint32_t seqno) ;
1766cd6a6acSopenharmony_ciint avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
1776cd6a6acSopenharmony_ci			  security_class_t tclass, access_vector_t perms,
1786cd6a6acSopenharmony_ci			  uint32_t seqno, uint32_t enable) ;
1796cd6a6acSopenharmony_ciint avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
1806cd6a6acSopenharmony_ci			 security_class_t tclass, access_vector_t perms,
1816cd6a6acSopenharmony_ci			 uint32_t seqno, uint32_t enable) ;
1826cd6a6acSopenharmony_ci
1836cd6a6acSopenharmony_ci#endif				/* _SELINUX_AVC_INTERNAL_H_ */
184