diff options
Diffstat (limited to 'include')
40 files changed, 3269 insertions, 0 deletions
diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..0cd00ab --- /dev/null +++ b/include/Makefile @@ -0,0 +1,12 @@ +# Installation directories. +PREFIX ?= $(DESTDIR)/usr +INCDIR ?= $(PREFIX)/include/sepol + +install: + test -d $(INCDIR) || install -m 755 -d $(INCDIR) + test -d $(INCDIR)/policydb || install -m 755 -d $(INCDIR)/policydb + install -m 644 $(wildcard sepol/*.h) $(INCDIR) + install -m 644 $(wildcard sepol/policydb/*.h) $(INCDIR)/policydb + +indent: + ../../scripts/Lindent $(wildcard sepol/*.h) diff --git a/include/sepol/boolean_record.h b/include/sepol/boolean_record.h new file mode 100644 index 0000000..54ca021 --- /dev/null +++ b/include/sepol/boolean_record.h @@ -0,0 +1,51 @@ +#ifndef _SEPOL_BOOLEAN_RECORD_H_ +#define _SEPOL_BOOLEAN_RECORD_H_ + +#include <stddef.h> +#include <sepol/handle.h> + +struct sepol_bool; +struct sepol_bool_key; +typedef struct sepol_bool sepol_bool_t; +typedef struct sepol_bool_key sepol_bool_key_t; + +/* Key */ +extern int sepol_bool_key_create(sepol_handle_t * handle, + const char *name, sepol_bool_key_t ** key); + +extern void sepol_bool_key_unpack(const sepol_bool_key_t * key, + const char **name); + +extern int sepol_bool_key_extract(sepol_handle_t * handle, + const sepol_bool_t * boolean, + sepol_bool_key_t ** key_ptr); + +extern void sepol_bool_key_free(sepol_bool_key_t * key); + +extern int sepol_bool_compare(const sepol_bool_t * boolean, + const sepol_bool_key_t * key); + +extern int sepol_bool_compare2(const sepol_bool_t * boolean, + const sepol_bool_t * boolean2); + +/* Name */ +extern const char *sepol_bool_get_name(const sepol_bool_t * boolean); + +extern int sepol_bool_set_name(sepol_handle_t * handle, + sepol_bool_t * boolean, const char *name); + +/* Value */ +extern int sepol_bool_get_value(const sepol_bool_t * boolean); + +extern void sepol_bool_set_value(sepol_bool_t * boolean, int value); + +/* Create/Clone/Destroy */ +extern int sepol_bool_create(sepol_handle_t * handle, sepol_bool_t ** bool_ptr); + +extern int sepol_bool_clone(sepol_handle_t * handle, + const sepol_bool_t * boolean, + sepol_bool_t ** bool_ptr); + +extern void sepol_bool_free(sepol_bool_t * boolean); + +#endif diff --git a/include/sepol/booleans.h b/include/sepol/booleans.h new file mode 100644 index 0000000..95ee7de --- /dev/null +++ b/include/sepol/booleans.h @@ -0,0 +1,59 @@ +#ifndef _SEPOL_BOOLEANS_H_ +#define _SEPOL_BOOLEANS_H_ + +#include <stddef.h> +#include <sepol/policydb.h> +#include <sepol/boolean_record.h> +#include <sepol/handle.h> + +/*--------------compatibility--------------*/ + +/* Given an existing binary policy (starting at 'data', with length 'len') + and a boolean configuration file named by 'boolpath', rewrite the binary + policy for the boolean settings in the boolean configuration file. + The binary policy is rewritten in place in memory. + Returns 0 upon success, or -1 otherwise. */ +extern int sepol_genbools(void *data, size_t len, char *boolpath); + +/* Given an existing binary policy (starting at 'data', with length 'len') + and boolean settings specified by the parallel arrays ('names', 'values') + with 'nel' elements, rewrite the binary policy for the boolean settings. + The binary policy is rewritten in place in memory. + Returns 0 upon success or -1 otherwise. */ +extern int sepol_genbools_array(void *data, size_t len, + char **names, int *values, int nel); +/*---------------end compatbility------------*/ + +/* Set the specified boolean */ +extern int sepol_bool_set(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_bool_key_t * key, + const sepol_bool_t * data); + +/* Return the number of booleans */ +extern int sepol_bool_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if the specified boolean exists */ +extern int sepol_bool_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_bool_key_t * key, int *response); + +/* Query a boolean - returns the boolean, or NULL if not found */ +extern int sepol_bool_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_bool_key_t * key, + sepol_bool_t ** response); + +/* Iterate the booleans + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_bool_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_bool_t * boolean, + void *fn_arg), void *arg); + +#endif diff --git a/include/sepol/context.h b/include/sepol/context.h new file mode 100644 index 0000000..c1eadca --- /dev/null +++ b/include/sepol/context.h @@ -0,0 +1,25 @@ +#ifndef _SEPOL_CONTEXT_H_ +#define _SEPOL_CONTEXT_H_ + +#include <sepol/context_record.h> +#include <sepol/policydb.h> +#include <sepol/handle.h> + +/* -- Deprecated -- */ + +extern int sepol_check_context(const char *context); + +/* -- End deprecated -- */ + +extern int sepol_context_check(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_context_t * context); + +extern int sepol_mls_contains(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const char *mls1, + const char *mls2, int *response); + +extern int sepol_mls_check(sepol_handle_t * handle, + const sepol_policydb_t * policydb, const char *mls); +#endif diff --git a/include/sepol/context_record.h b/include/sepol/context_record.h new file mode 100644 index 0000000..c305480 --- /dev/null +++ b/include/sepol/context_record.h @@ -0,0 +1,53 @@ +#ifndef _SEPOL_CONTEXT_RECORD_H_ +#define _SEPOL_CONTEXT_RECORD_H_ + +#include <sepol/handle.h> + +struct sepol_context; +typedef struct sepol_context sepol_context_t; + +/* We don't need a key, because the context is never stored + * in a data collection by itself */ + +/* User */ +extern const char *sepol_context_get_user(const sepol_context_t * con); + +extern int sepol_context_set_user(sepol_handle_t * handle, + sepol_context_t * con, const char *user); + +/* Role */ +extern const char *sepol_context_get_role(const sepol_context_t * con); + +extern int sepol_context_set_role(sepol_handle_t * handle, + sepol_context_t * con, const char *role); + +/* Type */ +extern const char *sepol_context_get_type(const sepol_context_t * con); + +extern int sepol_context_set_type(sepol_handle_t * handle, + sepol_context_t * con, const char *type); + +/* MLS */ +extern const char *sepol_context_get_mls(const sepol_context_t * con); + +extern int sepol_context_set_mls(sepol_handle_t * handle, + sepol_context_t * con, const char *mls_range); + +/* Create/Clone/Destroy */ +extern int sepol_context_create(sepol_handle_t * handle, + sepol_context_t ** con_ptr); + +extern int sepol_context_clone(sepol_handle_t * handle, + const sepol_context_t * con, + sepol_context_t ** con_ptr); + +extern void sepol_context_free(sepol_context_t * con); + +/* Parse to/from string */ +extern int sepol_context_from_string(sepol_handle_t * handle, + const char *str, sepol_context_t ** con); + +extern int sepol_context_to_string(sepol_handle_t * handle, + const sepol_context_t * con, char **str_ptr); + +#endif diff --git a/include/sepol/debug.h b/include/sepol/debug.h new file mode 100644 index 0000000..3370845 --- /dev/null +++ b/include/sepol/debug.h @@ -0,0 +1,34 @@ +#ifndef _SEPOL_DEBUG_H_ +#define _SEPOL_DEBUG_H_ + +#include <sepol/handle.h> + +/* Deprecated */ +extern void sepol_debug(int on); +/* End deprecated */ + +#define SEPOL_MSG_ERR 1 +#define SEPOL_MSG_WARN 2 +#define SEPOL_MSG_INFO 3 + +extern int sepol_msg_get_level(sepol_handle_t * handle); + +extern const char *sepol_msg_get_channel(sepol_handle_t * handle); + +extern const char *sepol_msg_get_fname(sepol_handle_t * handle); + +/* Set the messaging callback. + * By the default, the callback will print + * the message on standard output, in a + * particular format. Passing NULL here + * indicates that messaging should be suppressed */ +extern void sepol_msg_set_callback(sepol_handle_t * handle, +#ifdef __GNUC__ + __attribute__ ((format(printf, 3, 4))) +#endif + void (*msg_callback) (void *varg, + sepol_handle_t * + handle, + const char *fmt, ...), + void *msg_callback_arg); +#endif diff --git a/include/sepol/errcodes.h b/include/sepol/errcodes.h new file mode 100644 index 0000000..c6f3a8b --- /dev/null +++ b/include/sepol/errcodes.h @@ -0,0 +1,25 @@ +/* Author: Karl MacMillan <kmacmillan@mentalrootkit.com> */ + +#ifndef __sepol_errno_h__ +#define __sepol_errno_h__ + +#include <errno.h> + +#define SEPOL_OK 0 + +/* These first error codes are defined for compatibility with + * previous version of libsepol. In the future, custome error + * codes that don't map to system error codes should be defined + * outside of the range of system error codes. + */ +#define SEPOL_ERR -1 +#define SEPOL_ENOTSUP -2 /* feature not supported in module language */ +#define SEPOL_EREQ -3 /* requirements not met */ + +/* Error codes that map to system error codes */ +#define SEPOL_ENOMEM -ENOMEM +#define SEPOL_ERANGE -ERANGE +#define SEPOL_EEXIST -EEXIST +#define SEPOL_ENOENT -ENOENT + +#endif diff --git a/include/sepol/handle.h b/include/sepol/handle.h new file mode 100644 index 0000000..19be326 --- /dev/null +++ b/include/sepol/handle.h @@ -0,0 +1,27 @@ +#ifndef _SEPOL_HANDLE_H_ +#define _SEPOL_HANDLE_H_ + +struct sepol_handle; +typedef struct sepol_handle sepol_handle_t; + +/* Create and return a sepol handle. */ +sepol_handle_t *sepol_handle_create(void); + +/* Get whether or not dontaudits will be disabled, same values as + * specified by set_disable_dontaudit. This value reflects the state + * your system will be set to upon commit, not necessarily its + * current state.*/ +int sepol_get_disable_dontaudit(sepol_handle_t * sh); + +/* Set whether or not to disable dontaudits, 0 is default and does + * not disable dontaudits, 1 disables them */ +void sepol_set_disable_dontaudit(sepol_handle_t * sh, int disable_dontaudit); + +/* Set whether module_expand() should consume the base policy passed in. + * This should reduce the amount of memory required to expand the policy. */ +void sepol_set_expand_consume_base(sepol_handle_t * sh, int consume_base); + +/* Destroy a sepol handle. */ +void sepol_handle_destroy(sepol_handle_t *); + +#endif diff --git a/include/sepol/iface_record.h b/include/sepol/iface_record.h new file mode 100644 index 0000000..a72678c --- /dev/null +++ b/include/sepol/iface_record.h @@ -0,0 +1,59 @@ +#ifndef _SEPOL_IFACE_RECORD_H_ +#define _SEPOL_IFACE_RECORD_H_ + +#include <sepol/handle.h> +#include <sepol/context_record.h> + +struct sepol_iface; +struct sepol_iface_key; +typedef struct sepol_iface sepol_iface_t; +typedef struct sepol_iface_key sepol_iface_key_t; + +/* Key */ +extern int sepol_iface_compare(const sepol_iface_t * iface, + const sepol_iface_key_t * key); + +extern int sepol_iface_compare2(const sepol_iface_t * iface, + const sepol_iface_t * iface2); + +extern void sepol_iface_key_unpack(const sepol_iface_key_t * key, + const char **name); + +extern int sepol_iface_key_create(sepol_handle_t * handle, + const char *name, + sepol_iface_key_t ** key_ptr); + +extern int sepol_iface_key_extract(sepol_handle_t * handle, + const sepol_iface_t * iface, + sepol_iface_key_t ** key_ptr); + +extern void sepol_iface_key_free(sepol_iface_key_t * key); + +/* Name */ +extern const char *sepol_iface_get_name(const sepol_iface_t * iface); + +extern int sepol_iface_set_name(sepol_handle_t * handle, + sepol_iface_t * iface, const char *name); + +/* Context */ +extern sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface); + +extern int sepol_iface_set_ifcon(sepol_handle_t * handle, + sepol_iface_t * iface, sepol_context_t * con); + +extern sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface); + +extern int sepol_iface_set_msgcon(sepol_handle_t * handle, + sepol_iface_t * iface, sepol_context_t * con); + +/* Create/Clone/Destroy */ +extern int sepol_iface_create(sepol_handle_t * handle, + sepol_iface_t ** iface_ptr); + +extern int sepol_iface_clone(sepol_handle_t * handle, + const sepol_iface_t * iface, + sepol_iface_t ** iface_ptr); + +extern void sepol_iface_free(sepol_iface_t * iface); + +#endif diff --git a/include/sepol/interfaces.h b/include/sepol/interfaces.h new file mode 100644 index 0000000..9849e13 --- /dev/null +++ b/include/sepol/interfaces.h @@ -0,0 +1,43 @@ +#ifndef __SEPOL_INTERFACES_H_ +#define __SEPOL_INTERFACES_H_ + +#include <sepol/policydb.h> +#include <sepol/iface_record.h> +#include <sepol/handle.h> + +/* Return the number of interfaces */ +extern int sepol_iface_count(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + unsigned int *response); + +/* Check if an interface exists */ +extern int sepol_iface_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_iface_key_t * key, int *response); + +/* Query an interface - returns the interface, + * or NULL if not found */ +extern int sepol_iface_query(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_iface_key_t * key, + sepol_iface_t ** response); + +/* Modify an interface, or add it, if the key + * is not found */ +extern int sepol_iface_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_iface_key_t * key, + const sepol_iface_t * data); + +/* Iterate the interfaces + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_iface_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_iface_t * iface, + void *fn_arg), void *arg); + +#endif diff --git a/include/sepol/module.h b/include/sepol/module.h new file mode 100644 index 0000000..35f5cb7 --- /dev/null +++ b/include/sepol/module.h @@ -0,0 +1,82 @@ +#ifndef _SEPOL_MODULE_H_ +#define _SEPOL_MODULE_H_ + +#include <stddef.h> +#include <stdio.h> +#include <stdint.h> + +#include <sepol/handle.h> +#include <sepol/policydb.h> + +struct sepol_module_package; +typedef struct sepol_module_package sepol_module_package_t; + +/* Module package public interfaces. */ + +extern int sepol_module_package_create(sepol_module_package_t ** p); + +extern void sepol_module_package_free(sepol_module_package_t * p); + +extern char *sepol_module_package_get_file_contexts(sepol_module_package_t * p); + +extern size_t sepol_module_package_get_file_contexts_len(sepol_module_package_t + * p); + +extern int sepol_module_package_set_file_contexts(sepol_module_package_t * p, + char *data, size_t len); + +extern char *sepol_module_package_get_seusers(sepol_module_package_t * p); + +extern size_t sepol_module_package_get_seusers_len(sepol_module_package_t * p); + +extern int sepol_module_package_set_seusers(sepol_module_package_t * p, + char *data, size_t len); + +extern char *sepol_module_package_get_user_extra(sepol_module_package_t * p); + +extern size_t sepol_module_package_get_user_extra_len(sepol_module_package_t * + p); + +extern int sepol_module_package_set_user_extra(sepol_module_package_t * p, + char *data, size_t len); + +extern char *sepol_module_package_get_netfilter_contexts(sepol_module_package_t + * p); + +extern size_t +sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t * p); + +extern int sepol_module_package_set_netfilter_contexts(sepol_module_package_t * + p, char *data, + size_t len); + +extern sepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t + * p); + +extern int sepol_link_packages(sepol_handle_t * handle, + sepol_module_package_t * base, + sepol_module_package_t ** modules, + int num_modules, int verbose); + +extern int sepol_module_package_read(sepol_module_package_t * mod, + struct sepol_policy_file *file, + int verbose); + +extern int sepol_module_package_info(struct sepol_policy_file *file, + int *type, char **name, char **version); + +extern int sepol_module_package_write(sepol_module_package_t * p, + struct sepol_policy_file *file); + +/* Module linking/expanding public interfaces. */ + +extern int sepol_link_modules(sepol_handle_t * handle, + sepol_policydb_t * base, + sepol_policydb_t ** modules, + size_t len, int verbose); + +extern int sepol_expand_module(sepol_handle_t * handle, + sepol_policydb_t * base, + sepol_policydb_t * out, int verbose, int check); + +#endif diff --git a/include/sepol/node_record.h b/include/sepol/node_record.h new file mode 100644 index 0000000..9f61ac7 --- /dev/null +++ b/include/sepol/node_record.h @@ -0,0 +1,92 @@ +#ifndef _SEPOL_NODE_RECORD_H_ +#define _SEPOL_NODE_RECORD_H_ + +#include <stddef.h> +#include <sepol/context_record.h> +#include <sepol/handle.h> + +struct sepol_node; +struct sepol_node_key; +typedef struct sepol_node sepol_node_t; +typedef struct sepol_node_key sepol_node_key_t; + +#define SEPOL_PROTO_IP4 0 +#define SEPOL_PROTO_IP6 1 + +/* Key */ +extern int sepol_node_compare(const sepol_node_t * node, + const sepol_node_key_t * key); + +extern int sepol_node_compare2(const sepol_node_t * node, + const sepol_node_t * node2); + +extern int sepol_node_key_create(sepol_handle_t * handle, + const char *addr, + const char *mask, + int proto, sepol_node_key_t ** key_ptr); + +extern void sepol_node_key_unpack(const sepol_node_key_t * key, + const char **addr, + const char **mask, int *proto); + +extern int sepol_node_key_extract(sepol_handle_t * handle, + const sepol_node_t * node, + sepol_node_key_t ** key_ptr); + +extern void sepol_node_key_free(sepol_node_key_t * key); + +/* Address */ +extern int sepol_node_get_addr(sepol_handle_t * handle, + const sepol_node_t * node, char **addr); + +extern int sepol_node_get_addr_bytes(sepol_handle_t * handle, + const sepol_node_t * node, + char **addr, size_t * addr_sz); + +extern int sepol_node_set_addr(sepol_handle_t * handle, + sepol_node_t * node, + int proto, const char *addr); + +extern int sepol_node_set_addr_bytes(sepol_handle_t * handle, + sepol_node_t * node, + const char *addr, size_t addr_sz); + +/* Netmask */ +extern int sepol_node_get_mask(sepol_handle_t * handle, + const sepol_node_t * node, char **mask); + +extern int sepol_node_get_mask_bytes(sepol_handle_t * handle, + const sepol_node_t * node, + char **mask, size_t * mask_sz); + +extern int sepol_node_set_mask(sepol_handle_t * handle, + sepol_node_t * node, + int proto, const char *mask); + +extern int sepol_node_set_mask_bytes(sepol_handle_t * handle, + sepol_node_t * node, + const char *mask, size_t mask_sz); + +/* Protocol */ +extern int sepol_node_get_proto(const sepol_node_t * node); + +extern void sepol_node_set_proto(sepol_node_t * node, int proto); + +extern const char *sepol_node_get_proto_str(int proto); + +/* Context */ +extern sepol_context_t *sepol_node_get_con(const sepol_node_t * node); + +extern int sepol_node_set_con(sepol_handle_t * handle, + sepol_node_t * node, sepol_context_t * con); + +/* Create/Clone/Destroy */ +extern int sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node_ptr); + +extern int sepol_node_clone(sepol_handle_t * handle, + const sepol_node_t * node, + sepol_node_t ** node_ptr); + +extern void sepol_node_free(sepol_node_t * node); + +#endif diff --git a/include/sepol/nodes.h b/include/sepol/nodes.h new file mode 100644 index 0000000..1e0ac4f --- /dev/null +++ b/include/sepol/nodes.h @@ -0,0 +1,40 @@ +#ifndef _SEPOL_NODES_H_ +#define _SEPOL_NODES_H_ + +#include <sepol/handle.h> +#include <sepol/policydb.h> +#include <sepol/node_record.h> + +/* Return the number of nodes */ +extern int sepol_node_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if a node exists */ +extern int sepol_node_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_node_key_t * key, int *response); + +/* Query a node - returns the node, or NULL if not found */ +extern int sepol_node_query(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_node_key_t * key, + sepol_node_t ** response); + +/* Modify a node, or add it, if the key is not found */ +extern int sepol_node_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_node_key_t * key, + const sepol_node_t * data); + +/* Iterate the nodes + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_node_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_node_t * node, + void *fn_arg), void *arg); + +#endif diff --git a/include/sepol/policydb.h b/include/sepol/policydb.h new file mode 100644 index 0000000..43e23b3 --- /dev/null +++ b/include/sepol/policydb.h @@ -0,0 +1,138 @@ +#ifndef _SEPOL_POLICYDB_H_ +#define _SEPOL_POLICYDB_H_ + +#include <stddef.h> +#include <stdio.h> + +#include <sepol/handle.h> + +struct sepol_policy_file; +typedef struct sepol_policy_file sepol_policy_file_t; + +struct sepol_policydb; +typedef struct sepol_policydb sepol_policydb_t; + +/* Policy file public interfaces. */ + +/* Create and free memory associated with a policy file. */ +extern int sepol_policy_file_create(sepol_policy_file_t ** pf); +extern void sepol_policy_file_free(sepol_policy_file_t * pf); + +/* + * Set the policy file to represent a binary policy memory image. + * Subsequent operations using the policy file will read and write + * the image located at the specified address with the specified length. + * If 'len' is 0, then merely compute the necessary length upon + * subsequent policydb write operations in order to determine the + * necessary buffer size to allocate. + */ +extern void sepol_policy_file_set_mem(sepol_policy_file_t * pf, + char *data, size_t len); + +/* + * Get the size of the buffer needed to store a policydb write + * previously done on this policy file. + */ +extern int sepol_policy_file_get_len(sepol_policy_file_t * pf, size_t * len); + +/* + * Set the policy file to represent a FILE. + * Subsequent operations using the policy file will read and write + * to the FILE. + */ +extern void sepol_policy_file_set_fp(sepol_policy_file_t * pf, FILE * fp); + +/* + * Associate a handle with a policy file, for use in + * error reporting from subsequent calls that take the + * policy file as an argument. + */ +extern void sepol_policy_file_set_handle(sepol_policy_file_t * pf, + sepol_handle_t * handle); + +/* Policydb public interfaces. */ + +/* Create and free memory associated with a policydb. */ +extern int sepol_policydb_create(sepol_policydb_t ** p); +extern void sepol_policydb_free(sepol_policydb_t * p); + +/* Legal types of policies that the policydb can represent. */ +#define SEPOL_POLICY_KERN 0 +#define SEPOL_POLICY_BASE 1 +#define SEPOL_POLICY_MOD 2 + +/* + * Range of policy versions for the kernel policy type supported + * by this library. + */ +extern int sepol_policy_kern_vers_min(void); +extern int sepol_policy_kern_vers_max(void); + +/* + * Set the policy type as specified, and automatically initialize the + * policy version accordingly to the maximum version supported for the + * policy type. + * Returns -1 if the policy type is not legal. + */ +extern int sepol_policydb_set_typevers(sepol_policydb_t * p, unsigned int type); + +/* + * Set the policy version to a different value. + * Returns -1 if the policy version is not in the supported range for + * the (previously set) policy type. + */ +extern int sepol_policydb_set_vers(sepol_policydb_t * p, unsigned int vers); + +/* Set how to handle unknown class/perms. */ +#define SEPOL_DENY_UNKNOWN 0 +#define SEPOL_REJECT_UNKNOWN 2 +#define SEPOL_ALLOW_UNKNOWN 4 +extern int sepol_policydb_set_handle_unknown(sepol_policydb_t * p, + unsigned int handle_unknown); + +/* + * Read a policydb from a policy file. + * This automatically sets the type and version based on the + * image contents. + */ +extern int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf); + +/* + * Write a policydb to a policy file. + * The generated image will be in the binary format corresponding + * to the policy version associated with the policydb. + */ +extern int sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf); + +/* + * Extract a policydb from a binary policy memory image. + * This is equivalent to sepol_policydb_read with a policy file + * set to refer to memory. + */ +extern int sepol_policydb_from_image(sepol_handle_t * handle, + void *data, size_t len, + sepol_policydb_t * p); + +/* + * Generate a binary policy memory image from a policydb. + * This is equivalent to sepol_policydb_write with a policy file + * set to refer to memory, but internally handles computing the + * necessary length and allocating an appropriately sized memory + * buffer for the caller. + */ +extern int sepol_policydb_to_image(sepol_handle_t * handle, + sepol_policydb_t * p, + void **newdata, size_t * newlen); + +/* + * Check whether the policydb has MLS enabled. + */ +extern int sepol_policydb_mls_enabled(const sepol_policydb_t * p); + +/* + * Check whether the compatibility mode for SELinux network + * checks should be enabled when using this policy. + */ +extern int sepol_policydb_compat_net(const sepol_policydb_t * p); + +#endif diff --git a/include/sepol/policydb/avrule_block.h b/include/sepol/policydb/avrule_block.h new file mode 100644 index 0000000..dc926e5 --- /dev/null +++ b/include/sepol/policydb/avrule_block.h @@ -0,0 +1,37 @@ +/* Authors: Jason Tang <jtang@tresys.com> + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_AVRULE_BLOCK_H_ +#define _SEPOL_AVRULE_BLOCK_H_ + +#include <sepol/policydb/policydb.h> + +extern avrule_block_t *avrule_block_create(void); +extern void avrule_block_destroy(avrule_block_t * x); +extern avrule_decl_t *avrule_decl_create(uint32_t decl_id); +extern void avrule_decl_destroy(avrule_decl_t * x); +extern void avrule_block_list_destroy(avrule_block_t * x); +extern avrule_decl_t *get_avrule_decl(policydb_t * p, uint32_t decl_id); +extern cond_list_t *get_decl_cond_list(policydb_t * p, + avrule_decl_t * decl, + cond_list_t * cond); +extern int is_id_enabled(char *id, policydb_t * p, int symbol_table); +extern int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p); + +#endif diff --git a/include/sepol/policydb/avtab.h b/include/sepol/policydb/avtab.h new file mode 100644 index 0000000..6955ecf --- /dev/null +++ b/include/sepol/policydb/avtab.h @@ -0,0 +1,127 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* + * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> + * Tuned number of hash slots for avtab to reduce memory usage + */ + +/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> + * + * Added conditional policy language extensions + * + * Copyright (C) 2003 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * An access vector table (avtab) is a hash table + * of access vectors and transition types indexed + * by a type pair and a class. An access vector + * table is used to represent the type enforcement + * tables. + */ + +#ifndef _SEPOL_POLICYDB_AVTAB_H_ +#define _SEPOL_POLICYDB_AVTAB_H_ + +#include <sys/types.h> +#include <stdint.h> + +typedef struct avtab_key { + uint16_t source_type; + uint16_t target_type; + uint16_t target_class; +#define AVTAB_ALLOWED 1 +#define AVTAB_AUDITALLOW 2 +#define AVTAB_AUDITDENY 4 +#define AVTAB_NEVERALLOW 128 +#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) +#define AVTAB_TRANSITION 16 +#define AVTAB_MEMBER 32 +#define AVTAB_CHANGE 64 +#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) +#define AVTAB_ENABLED_OLD 0x80000000 +#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ + uint16_t specified; /* what fields are specified */ +} avtab_key_t; + +typedef struct avtab_datum { + uint32_t data; /* access vector or type */ +} avtab_datum_t; + +typedef struct avtab_node *avtab_ptr_t; + +struct avtab_node { + avtab_key_t key; + avtab_datum_t datum; + avtab_ptr_t next; + void *parse_context; /* generic context pointer used by parser; + * not saved in binary policy */ + unsigned merged; /* flag for avtab_write only; + not saved in binary policy */ +}; + +typedef struct avtab { + avtab_ptr_t *htable; + uint32_t nel; /* number of elements */ + uint32_t nslot; /* number of hash slots */ + uint16_t mask; /* mask to compute hash func */ +} avtab_t; + +extern int avtab_init(avtab_t *); +extern int avtab_alloc(avtab_t *, uint32_t); +extern int avtab_insert(avtab_t * h, avtab_key_t * k, avtab_datum_t * d); + +extern avtab_datum_t *avtab_search(avtab_t * h, avtab_key_t * k); + +extern void avtab_destroy(avtab_t * h); + +extern int avtab_map(avtab_t * h, + int (*apply) (avtab_key_t * k, + avtab_datum_t * d, void *args), void *args); + +extern void avtab_hash_eval(avtab_t * h, char *tag); + +struct policy_file; +extern int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a, + int (*insert) (avtab_t * a, avtab_key_t * k, + avtab_datum_t * d, void *p), void *p); + +extern int avtab_read(avtab_t * a, struct policy_file *fp, uint32_t vers); + +extern avtab_ptr_t avtab_insert_nonunique(avtab_t * h, avtab_key_t * key, + avtab_datum_t * datum); + +extern avtab_ptr_t avtab_insert_with_parse_context(avtab_t * h, + avtab_key_t * key, + avtab_datum_t * datum, + void *parse_context); + +extern avtab_ptr_t avtab_search_node(avtab_t * h, avtab_key_t * key); + +extern avtab_ptr_t avtab_search_node_next(avtab_ptr_t node, int specified); + +#define MAX_AVTAB_HASH_BITS 13 +#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) +#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) +#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS + +#endif /* _AVTAB_H_ */ + +/* FLASK */ diff --git a/include/sepol/policydb/conditional.h b/include/sepol/policydb/conditional.h new file mode 100644 index 0000000..a8ed694 --- /dev/null +++ b/include/sepol/policydb/conditional.h @@ -0,0 +1,134 @@ +/* Authors: Karl MacMillan <kmacmillan@tresys.com> + * Frank Mayer <mayerf@tresys.com> + * + * Copyright (C) 2003 - 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_CONDITIONAL_H_ +#define _SEPOL_POLICYDB_CONDITIONAL_H_ + +#include <sepol/policydb/flask_types.h> +#include <sepol/policydb/avtab.h> +#include <sepol/policydb/symtab.h> +#include <sepol/policydb/policydb.h> + +#define COND_EXPR_MAXDEPTH 10 + +/* this is the max unique bools in a conditional expression + * for which we precompute all outcomes for the expression. + * + * NOTE - do _NOT_ use value greater than 5 because + * cond_node_t->expr_pre_comp can only hold at most 32 values + */ +#define COND_MAX_BOOLS 5 + +/* + * A conditional expression is a list of operators and operands + * in reverse polish notation. + */ +typedef struct cond_expr { +#define COND_BOOL 1 /* plain bool */ +#define COND_NOT 2 /* !bool */ +#define COND_OR 3 /* bool || bool */ +#define COND_AND 4 /* bool && bool */ +#define COND_XOR 5 /* bool ^ bool */ +#define COND_EQ 6 /* bool == bool */ +#define COND_NEQ 7 /* bool != bool */ +#define COND_LAST COND_NEQ + uint32_t expr_type; + uint32_t bool; + struct cond_expr *next; +} cond_expr_t; + +/* + * Each cond_node_t contains a list of rules to be enabled/disabled + * depending on the current value of the conditional expression. This + * struct is for that list. + */ +typedef struct cond_av_list { + avtab_ptr_t node; + struct cond_av_list *next; +} cond_av_list_t; + +/* + * A cond node represents a conditional block in a policy. It + * contains a conditional expression, the current state of the expression, + * two lists of rules to enable/disable depending on the value of the + * expression (the true list corresponds to if and the false list corresponds + * to else).. + */ +typedef struct cond_node { + int cur_state; + cond_expr_t *expr; + /* these true/false lists point into te_avtab when that is used */ + cond_av_list_t *true_list; + cond_av_list_t *false_list; + /* and these are using during parsing and for modules */ + avrule_t *avtrue_list; + avrule_t *avfalse_list; + /* these fields are not written to binary policy */ + unsigned int nbools; + uint32_t bool_ids[COND_MAX_BOOLS]; + uint32_t expr_pre_comp; + /* */ + struct cond_node *next; +} cond_node_t; + +extern int cond_evaluate_expr(policydb_t * p, cond_expr_t * expr); +extern cond_expr_t *cond_copy_expr(cond_expr_t * expr); + +extern int cond_expr_equal(cond_node_t * a, cond_node_t * b); +extern int cond_normalize_expr(policydb_t * p, cond_node_t * cn); +extern void cond_node_destroy(cond_node_t * node); +extern void cond_expr_destroy(cond_expr_t * expr); + +extern cond_node_t *cond_node_find(policydb_t * p, + cond_node_t * needle, cond_node_t * haystack, + int *was_created); + +extern cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node); + +extern cond_node_t *cond_node_search(policydb_t * p, cond_node_t * list, + cond_node_t * cn); + +extern int evaluate_conds(policydb_t * p); + +extern avtab_datum_t *cond_av_list_search(avtab_key_t * key, + cond_av_list_t * cond_list); + +extern void cond_av_list_destroy(cond_av_list_t * list); + +extern void cond_optimize_lists(cond_list_t * cl); + +extern int cond_policydb_init(policydb_t * p); +extern void cond_policydb_destroy(policydb_t * p); +extern void cond_list_destroy(cond_list_t * list); + +extern int cond_init_bool_indexes(policydb_t * p); +extern int cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p); + +extern int cond_index_bool(hashtab_key_t key, hashtab_datum_t datum, + void *datap); + +extern int cond_read_bool(policydb_t * p, hashtab_t h, struct policy_file *fp); + +extern int cond_read_list(policydb_t * p, cond_list_t ** list, void *fp); + +extern void cond_compute_av(avtab_t * ctab, avtab_key_t * key, + struct sepol_av_decision *avd); + +#endif /* _CONDITIONAL_H_ */ diff --git a/include/sepol/policydb/constraint.h b/include/sepol/policydb/constraint.h new file mode 100644 index 0000000..4c16ab0 --- /dev/null +++ b/include/sepol/policydb/constraint.h @@ -0,0 +1,77 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* FLASK */ + +/* + * A constraint is a condition that must be satisfied in + * order for one or more permissions to be granted. + * Constraints are used to impose additional restrictions + * beyond the type-based rules in `te' or the role-based + * transition rules in `rbac'. Constraints are typically + * used to prevent a process from transitioning to a new user + * identity or role unless it is in a privileged type. + * Constraints are likewise typically used to prevent a + * process from labeling an object with a different user + * identity. + */ + +#ifndef _SEPOL_POLICYDB_CONSTRAINT_H_ +#define _SEPOL_POLICYDB_CONSTRAINT_H_ + +#include <sepol/policydb/policydb.h> +#include <sepol/policydb/ebitmap.h> +#include <sepol/policydb/flask_types.h> + +#define CEXPR_MAXDEPTH 5 + +struct type_set; + +typedef struct constraint_expr { +#define CEXPR_NOT 1 /* not expr */ +#define CEXPR_AND 2 /* expr and expr */ +#define CEXPR_OR 3 /* expr or expr */ +#define CEXPR_ATTR 4 /* attr op attr */ +#define CEXPR_NAMES 5 /* attr op names */ + uint32_t expr_type; /* expression type */ + +#define CEXPR_USER 1 /* user */ +#define CEXPR_ROLE 2 /* role */ +#define CEXPR_TYPE 4 /* type */ +#define CEXPR_TARGET 8 /* target if set, source otherwise */ +#define CEXPR_XTARGET 16 /* special 3rd target for validatetrans rule */ +#define CEXPR_L1L2 32 /* low level 1 vs. low level 2 */ +#define CEXPR_L1H2 64 /* low level 1 vs. high level 2 */ +#define CEXPR_H1L2 128 /* high level 1 vs. low level 2 */ +#define CEXPR_H1H2 256 /* high level 1 vs. high level 2 */ +#define CEXPR_L1H1 512 /* low level 1 vs. high level 1 */ +#define CEXPR_L2H2 1024 /* low level 2 vs. high level 2 */ + uint32_t attr; /* attribute */ + +#define CEXPR_EQ 1 /* == or eq */ +#define CEXPR_NEQ 2 /* != */ +#define CEXPR_DOM 3 /* dom */ +#define CEXPR_DOMBY 4 /* domby */ +#define CEXPR_INCOMP 5 /* incomp */ + uint32_t op; /* operator */ + + ebitmap_t names; /* names */ + struct type_set *type_names; + + struct constraint_expr *next; /* next expression */ +} constraint_expr_t; + +typedef struct constraint_node { + sepol_access_vector_t permissions; /* constrained permissions */ + constraint_expr_t *expr; /* constraint on permissions */ + struct constraint_node *next; /* next constraint */ +} constraint_node_t; + +struct policydb; + +extern int constraint_expr_init(constraint_expr_t * expr); +extern void constraint_expr_destroy(constraint_expr_t * expr); + +#endif /* _CONSTRAINT_H_ */ + +/* FLASK */ diff --git a/include/sepol/policydb/context.h b/include/sepol/policydb/context.h new file mode 100644 index 0000000..8d74a25 --- /dev/null +++ b/include/sepol/policydb/context.h @@ -0,0 +1,97 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* FLASK */ + +/* + * A security context is a set of security attributes + * associated with each subject and object controlled + * by the security policy. Security contexts are + * externally represented as variable-length strings + * that can be interpreted by a user or application + * with an understanding of the security policy. + * Internally, the security server uses a simple + * structure. This structure is private to the + * security server and can be changed without affecting + * clients of the security server. + */ + +#ifndef _SEPOL_POLICYDB_CONTEXT_H_ +#define _SEPOL_POLICYDB_CONTEXT_H_ + +#include <stddef.h> +#include <sepol/policydb/ebitmap.h> +#include <sepol/policydb/mls_types.h> + +/* + * A security context consists of an authenticated user + * identity, a role, a type and a MLS range. + */ +typedef struct context_struct { + uint32_t user; + uint32_t role; + uint32_t type; + mls_range_t range; +} context_struct_t; + +static inline void mls_context_init(context_struct_t * c) +{ + mls_range_init(&c->range); +} + +static inline int mls_context_cpy(context_struct_t * dst, + context_struct_t * src) +{ + + if (mls_range_cpy(&dst->range, &src->range) < 0) + return -1; + + return 0; +} + +static inline int mls_context_cmp(context_struct_t * c1, context_struct_t * c2) +{ + return (mls_level_eq(&c1->range.level[0], &c2->range.level[0]) && + mls_level_eq(&c1->range.level[1], &c2->range.level[1])); + +} + +static inline void mls_context_destroy(context_struct_t * c) +{ + if (c == NULL) + return; + + mls_range_destroy(&c->range); + mls_context_init(c); +} + +static inline void context_init(context_struct_t * c) +{ + memset(c, 0, sizeof(*c)); +} + +static inline int context_cpy(context_struct_t * dst, context_struct_t * src) +{ + dst->user = src->user; + dst->role = src->role; + dst->type = src->type; + return mls_context_cpy(dst, src); +} + +static inline void context_destroy(context_struct_t * c) +{ + if (c == NULL) + return; + + c->user = c->role = c->type = 0; + mls_context_destroy(c); +} + +static inline int context_cmp(context_struct_t * c1, context_struct_t * c2) +{ + return ((c1->user == c2->user) && + (c1->role == c2->role) && + (c1->type == c2->type) && mls_context_cmp(c1, c2)); +} + +#endif diff --git a/include/sepol/policydb/ebitmap.h b/include/sepol/policydb/ebitmap.h new file mode 100644 index 0000000..410c15c --- /dev/null +++ b/include/sepol/policydb/ebitmap.h @@ -0,0 +1,88 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* FLASK */ + +/* + * An extensible bitmap is a bitmap that supports an + * arbitrary number of bits. Extensible bitmaps are + * used to represent sets of values, such as types, + * roles, categories, and classes. + * + * Each extensible bitmap is implemented as a linked + * list of bitmap nodes, where each bitmap node has + * an explicitly specified starting bit position within + * the total bitmap. + */ + +#ifndef _SEPOL_POLICYDB_EBITMAP_H_ +#define _SEPOL_POLICYDB_EBITMAP_H_ + +#include <stdint.h> +#include <string.h> + +#define MAPTYPE uint64_t /* portion of bitmap in each node */ +#define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */ +#define MAPBIT 1ULL /* a bit in the node bitmap */ + +typedef struct ebitmap_node { + uint32_t startbit; /* starting position in the total bitmap */ + MAPTYPE map; /* this node's portion of the bitmap */ + struct ebitmap_node *next; +} ebitmap_node_t; + +typedef struct ebitmap { + ebitmap_node_t *node; /* first node in the bitmap */ + uint32_t highbit; /* highest position in the total bitmap */ +} ebitmap_t; + +#define ebitmap_length(e) ((e)->highbit) +#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) +#define ebitmap_startnode(e) ((e)->node) + +static inline unsigned int ebitmap_start(const ebitmap_t * e, + ebitmap_node_t ** n) +{ + + *n = e->node; + return ebitmap_startbit(e); +} + +static inline void ebitmap_init(ebitmap_t * e) +{ + memset(e, 0, sizeof(*e)); +} + +static inline unsigned int ebitmap_next(ebitmap_node_t ** n, unsigned int bit) +{ + if ((bit == ((*n)->startbit + MAPSIZE - 1)) && (*n)->next) { + *n = (*n)->next; + return (*n)->startbit; + } + + return (bit + 1); +} + +static inline int ebitmap_node_get_bit(ebitmap_node_t * n, unsigned int bit) +{ + if (n->map & (MAPBIT << (bit - n->startbit))) + return 1; + return 0; +} + +#define ebitmap_for_each_bit(e, n, bit) \ + for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \ + +extern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1); +extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src); +extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit); +extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value); +extern void ebitmap_destroy(ebitmap_t * e); +extern int ebitmap_read(ebitmap_t * e, void *fp); + +#endif /* _EBITMAP_H_ */ + +/* FLASK */ diff --git a/include/sepol/policydb/expand.h b/include/sepol/policydb/expand.h new file mode 100644 index 0000000..31e25ec --- /dev/null +++ b/include/sepol/policydb/expand.h @@ -0,0 +1,79 @@ +/* Authors: Jason Tang <jtang@tresys.com> + * Joshua Brindle <jbrindle@tresys.com> + * Karl MacMillan <kmacmillan@tresys.com> + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal items. + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_EXPAND_H +#define _SEPOL_POLICYDB_EXPAND_H + +#include <stddef.h> +#include <sepol/handle.h> +#include <sepol/policydb/conditional.h> + +/* + * Expand only the avrules for a module. It is valid for this function + * to expand base into itself (i.e. base == out); the typemap for + * this special case should map type[i] to i+1. Likewise the boolmap + * should map bool[i] to i + 1. This function optionally expands + * neverallow rules. If neverallow rules are expanded, there is no + * need to copy them and doing so could cause duplicate entries when + * base == out. If the neverallow rules are not expanded, they are + * just copied to the destination policy so that assertion checking + * can be performed after expand. No assertion or hierarchy checking + * is performed by this function. + */ +extern int expand_module_avrules(sepol_handle_t * handle, policydb_t * base, + policydb_t * out, uint32_t * typemap, uint32_t * boolmap, + uint32_t * rolemap, uint32_t * usermap, + int verbose, int expand_neverallow); +/* + * Expand all parts of a module. Neverallow rules are not expanded (only + * copied). It is not valid to expand base into itself. If check is non-zero, + * performs hierarchy and assertion checking. + */ +extern int expand_module(sepol_handle_t * handle, + policydb_t * base, policydb_t * out, + int verbose, int check); +extern int convert_type_ebitmap(ebitmap_t * src, ebitmap_t * dst, + uint32_t * typemap); +extern int expand_convert_type_set(policydb_t * p, uint32_t * typemap, + type_set_t * set, ebitmap_t * types, + unsigned char alwaysexpand); +extern int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + unsigned char alwaysexpand); +extern int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap); +extern int mls_semantic_level_expand(mls_semantic_level_t *sl, mls_level_t *l, + policydb_t *p, sepol_handle_t *h); +extern int mls_semantic_range_expand(mls_semantic_range_t *sr, mls_range_t *r, + policydb_t *p, sepol_handle_t *h); +extern int expand_rule(sepol_handle_t * handle, + policydb_t * source_pol, + avrule_t * source_rule, avtab_t * dest_avtab, + cond_av_list_t ** cond, cond_av_list_t ** other, + int enabled); + +extern int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa); + +extern int expand_cond_av_list(policydb_t * p, cond_av_list_t * l, + cond_av_list_t ** newl, avtab_t * expa); + +#endif diff --git a/include/sepol/policydb/flask.h b/include/sepol/policydb/flask.h new file mode 100644 index 0000000..3134284 --- /dev/null +++ b/include/sepol/policydb/flask.h @@ -0,0 +1,94 @@ +/* This file is automatically generated. Do not edit. */ +#ifndef _SEPOL_POLICYDB_FLASK_H_ +#define _SEPOL_POLICYDB_FLASK_H_ + +/* + * Security object class definitions + */ +#define SECCLASS_SECURITY 1 +#define SECCLASS_PROCESS 2 +#define SECCLASS_SYSTEM 3 +#define SECCLASS_CAPABILITY 4 +#define SECCLASS_FILESYSTEM 5 +#define SECCLASS_FILE 6 +#define SECCLASS_DIR 7 +#define SECCLASS_FD 8 +#define SECCLASS_LNK_FILE 9 +#define SECCLASS_CHR_FILE 10 +#define SECCLASS_BLK_FILE 11 +#define SECCLASS_SOCK_FILE 12 +#define SECCLASS_FIFO_FILE 13 +#define SECCLASS_SOCKET 14 +#define SECCLASS_TCP_SOCKET 15 +#define SECCLASS_UDP_SOCKET 16 +#define SECCLASS_RAWIP_SOCKET 17 +#define SECCLASS_NODE 18 +#define SECCLASS_NETIF 19 +#define SECCLASS_NETLINK_SOCKET 20 +#define SECCLASS_PACKET_SOCKET 21 +#define SECCLASS_KEY_SOCKET 22 +#define SECCLASS_UNIX_STREAM_SOCKET 23 +#define SECCLASS_UNIX_DGRAM_SOCKET 24 +#define SECCLASS_SEM 25 +#define SECCLASS_MSG 26 +#define SECCLASS_MSGQ 27 +#define SECCLASS_SHM 28 +#define SECCLASS_IPC 29 +#define SECCLASS_PASSWD 30 +#define SECCLASS_DRAWABLE 31 +#define SECCLASS_WINDOW 32 +#define SECCLASS_GC 33 +#define SECCLASS_FONT 34 +#define SECCLASS_COLORMAP 35 +#define SECCLASS_PROPERTY 36 +#define SECCLASS_CURSOR 37 +#define SECCLASS_XCLIENT 38 +#define SECCLASS_XINPUT 39 +#define SECCLASS_XSERVER 40 +#define SECCLASS_XEXTENSION 41 +#define SECCLASS_PAX 42 +#define SECCLASS_NETLINK_ROUTE_SOCKET 43 +#define SECCLASS_NETLINK_FIREWALL_SOCKET 44 +#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45 +#define SECCLASS_NETLINK_NFLOG_SOCKET 46 +#define SECCLASS_NETLINK_XFRM_SOCKET 47 +#define SECCLASS_NETLINK_SELINUX_SOCKET 48 +#define SECCLASS_NETLINK_AUDIT_SOCKET 49 +#define SECCLASS_NETLINK_IP6FW_SOCKET 50 +#define SECCLASS_NETLINK_DNRT_SOCKET 51 +#define SECCLASS_DBUS 52 + +/* + * Security identifier indices for initial entities + */ +#define SECINITSID_KERNEL 1 +#define SECINITSID_SECURITY 2 +#define SECINITSID_UNLABELED 3 +#define SECINITSID_FS 4 +#define SECINITSID_FILE 5 +#define SECINITSID_FILE_LABELS 6 +#define SECINITSID_INIT 7 +#define SECINITSID_ANY_SOCKET 8 +#define SECINITSID_PORT 9 +#define SECINITSID_NETIF 10 +#define SECINITSID_NETMSG 11 +#define SECINITSID_NODE 12 +#define SECINITSID_IGMP_PACKET 13 +#define SECINITSID_ICMP_SOCKET 14 +#define SECINITSID_TCP_SOCKET 15 +#define SECINITSID_SYSCTL_MODPROBE 16 +#define SECINITSID_SYSCTL 17 +#define SECINITSID_SYSCTL_FS 18 +#define SECINITSID_SYSCTL_KERNEL 19 +#define SECINITSID_SYSCTL_NET 20 +#define SECINITSID_SYSCTL_NET_UNIX 21 +#define SECINITSID_SYSCTL_VM 22 +#define SECINITSID_SYSCTL_DEV 23 +#define SECINITSID_KMOD 24 +#define SECINITSID_POLICY 25 +#define SECINITSID_SCMP_PACKET 26 +#define SECINITSID_DEVNULL 27 + +#define SECINITSID_NUM 27 + +#endif diff --git a/include/sepol/policydb/flask_types.h b/include/sepol/policydb/flask_types.h new file mode 100644 index 0000000..575c6f2 --- /dev/null +++ b/include/sepol/policydb/flask_types.h @@ -0,0 +1,62 @@ + +/* -*- linux-c -*- */ + +/* + * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + */ + +#ifndef _SEPOL_POLICYDB_FLASK_TYPES_H_ +#define _SEPOL_POLICYDB_FLASK_TYPES_H_ + +/* + * The basic Flask types and constants. + */ + +#include <sys/types.h> +#include <stdint.h> + +/* + * A security context is a set of security attributes + * associated with each subject and object controlled + * by the security policy. The security context type + * is defined as a variable-length string that can be + * interpreted by any application or user with an + * understanding of the security policy. + */ +typedef char *sepol_security_context_t; + +/* + * An access vector (AV) is a collection of related permissions + * for a pair of SIDs. The bits within an access vector + * are interpreted differently depending on the class of + * the object. The access vector interpretations are specified + * in flask/access_vectors, and the corresponding constants + * for permissions are defined in the automatically generated + * header file av_permissions.h. + */ +typedef uint32_t sepol_access_vector_t; + +/* + * Each object class is identified by a fixed-size value. + * The set of security classes is specified in flask/security_classes, + * with the corresponding constants defined in the automatically + * generated header file flask.h. + */ +typedef uint16_t sepol_security_class_t; +#define SEPOL_SECCLASS_NULL 0x0000 /* no class */ + +#define SELINUX_MAGIC 0xf97cff8c +#define SELINUX_MOD_MAGIC 0xf97cff8d + +typedef uint32_t sepol_security_id_t; +#define SEPOL_SECSID_NULL 0 + +struct sepol_av_decision { + sepol_access_vector_t allowed; + sepol_access_vector_t decided; + sepol_access_vector_t auditallow; + sepol_access_vector_t auditdeny; + uint32_t seqno; +}; + +#endif diff --git a/include/sepol/policydb/hashtab.h b/include/sepol/policydb/hashtab.h new file mode 100644 index 0000000..1081ff6 --- /dev/null +++ b/include/sepol/policydb/hashtab.h @@ -0,0 +1,137 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* FLASK */ + +/* + * A hash table (hashtab) maintains associations between + * key values and datum values. The type of the key values + * and the type of the datum values is arbitrary. The + * functions for hash computation and key comparison are + * provided by the creator of the table. + */ + +#ifndef _SEPOL_POLICYDB_HASHTAB_H_ +#define _SEPOL_POLICYDB_HASHTAB_H_ + +#include <sepol/errcodes.h> + +#include <stdint.h> +#include <stdio.h> + +typedef char *hashtab_key_t; /* generic key type */ +typedef void *hashtab_datum_t; /* generic datum type */ + +typedef struct hashtab_node *hashtab_ptr_t; + +typedef struct hashtab_node { + hashtab_key_t key; + hashtab_datum_t datum; + hashtab_ptr_t next; +} hashtab_node_t; + +typedef struct hashtab_val { + hashtab_ptr_t *htable; /* hash table */ + unsigned int size; /* number of slots in hash table */ + uint32_t nel; /* number of elements in hash table */ + unsigned int (*hash_value) (struct hashtab_val * h, hashtab_key_t key); /* hash function */ + int (*keycmp) (struct hashtab_val * h, hashtab_key_t key1, hashtab_key_t key2); /* key comparison function */ +} hashtab_val_t; + +typedef hashtab_val_t *hashtab_t; + +/* + Creates a new hash table with the specified characteristics. + + Returns NULL if insufficent space is available or + the new hash table otherwise. + */ +extern hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, + const hashtab_key_t + key), + int (*keycmp) (hashtab_t h, + const hashtab_key_t key1, + const hashtab_key_t key2), + unsigned int size); +/* + Inserts the specified (key, datum) pair into the specified hash table. + + Returns SEPOL_ENOMEM if insufficient space is available or + SEPOL_EEXIST if there is already an entry with the same key or + SEPOL_OK otherwise. + */ +extern int hashtab_insert(hashtab_t h, hashtab_key_t k, hashtab_datum_t d); + +/* + Removes the entry with the specified key from the hash table. + Applies the specified destroy function to (key,datum,args) for + the entry. + + Returns SEPOL_ENOENT if no entry has the specified key or + SEPOL_OK otherwise. + */ +extern int hashtab_remove(hashtab_t h, hashtab_key_t k, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + +/* + Insert or replace the specified (key, datum) pair in the specified + hash table. If an entry for the specified key already exists, + then the specified destroy function is applied to (key,datum,args) + for the entry prior to replacing the entry's contents. + + Returns SEPOL_ENOMEM if insufficient space is available or + SEPOL_OK otherwise. + */ +extern int hashtab_replace(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + +/* + Searches for the entry with the specified key in the hash table. + + Returns NULL if no entry has the specified key or + the datum of the entry otherwise. + */ +extern hashtab_datum_t hashtab_search(hashtab_t h, const hashtab_key_t k); + +/* + Destroys the specified hash table. + */ +extern void hashtab_destroy(hashtab_t h); + +/* + Applies the specified apply function to (key,datum,args) + for each entry in the specified hash table. + + The order in which the function is applied to the entries + is dependent upon the internal structure of the hash table. + + If apply returns a non-zero status, then hashtab_map will cease + iterating through the hash table and will propagate the error + return to its caller. + */ +extern int hashtab_map(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + +/* + Same as hashtab_map, except that if apply returns a non-zero status, + then the (key,datum) pair will be removed from the hashtab and the + destroy function will be applied to (key,datum,args). + */ +extern void hashtab_map_remove_on_error(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void *args); + +extern void hashtab_hash_eval(hashtab_t h, char *tag); + +#endif diff --git a/include/sepol/policydb/hierarchy.h b/include/sepol/policydb/hierarchy.h new file mode 100644 index 0000000..de2dfc7 --- /dev/null +++ b/include/sepol/policydb/hierarchy.h @@ -0,0 +1,32 @@ +/* Authors: Jason Tang <jtang@tresys.com> + * Joshua Brindle <jbrindle@tresys.com> + * Karl MacMillan <kmacmillan@tresys.com> + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal items. + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_HIERARCHY_H_ +#define _SEPOL_POLICYDB_HIERARCHY_H_ + +#include <sepol/policydb/policydb.h> + +extern int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p); + +#endif diff --git a/include/sepol/policydb/link.h b/include/sepol/policydb/link.h new file mode 100644 index 0000000..fca9114 --- /dev/null +++ b/include/sepol/policydb/link.h @@ -0,0 +1,20 @@ +/* Authors: Jason Tang <jtang@tresys.com> + * Joshua Brindle <jbrindle@tresys.com> + * Karl MacMillan <kmacmillan@mentalrootkit.com> + */ + +#ifndef _SEPOL_POLICYDB_LINK_H +#define _SEPOL_POLICYDB_LINK_H + +#include <sepol/handle.h> +#include <sepol/errcodes.h> +#include <sepol/policydb/policydb.h> + + +#include <stddef.h> + +extern int link_modules(sepol_handle_t * handle, + policydb_t * b, policydb_t ** mods, int len, + int verbose); + +#endif diff --git a/include/sepol/policydb/mls_types.h b/include/sepol/policydb/mls_types.h new file mode 100644 index 0000000..e491209 --- /dev/null +++ b/include/sepol/policydb/mls_types.h @@ -0,0 +1,153 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ +/* + * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> + * + * Support for enhanced MLS infrastructure. + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * Type definitions for the multi-level security (MLS) policy. + */ + +#ifndef _SEPOL_POLICYDB_MLS_TYPES_H_ +#define _SEPOL_POLICYDB_MLS_TYPES_H_ + +#include <stdint.h> +#include <stdlib.h> +#include <sepol/policydb/ebitmap.h> +#include <sepol/policydb/flask_types.h> + +typedef struct mls_level { + uint32_t sens; /* sensitivity */ + ebitmap_t cat; /* category set */ +} mls_level_t; + +typedef struct mls_range { + mls_level_t level[2]; /* low == level[0], high == level[1] */ +} mls_range_t; + +static inline int mls_level_cpy(struct mls_level *dst, struct mls_level *src) +{ + + dst->sens = src->sens; + if (ebitmap_cpy(&dst->cat, &src->cat) < 0) + return -1; + return 0; +} + +static inline void mls_level_init(struct mls_level *level) +{ + + memset(level, 0, sizeof(mls_level_t)); +} + +static inline void mls_level_destroy(struct mls_level *level) +{ + + if (level == NULL) + return; + + ebitmap_destroy(&level->cat); + mls_level_init(level); +} + +static inline int mls_level_eq(const struct mls_level *l1, const struct mls_level *l2) +{ + return ((l1->sens == l2->sens) && ebitmap_cmp(&l1->cat, &l2->cat)); +} + +static inline int mls_level_dom(const struct mls_level *l1, const struct mls_level *l2) +{ + return ((l1->sens >= l2->sens) && ebitmap_contains(&l1->cat, &l2->cat)); +} + +#define mls_level_incomp(l1, l2) \ +(!mls_level_dom((l1), (l2)) && !mls_level_dom((l2), (l1))) + +#define mls_level_between(l1, l2, l3) \ +(mls_level_dom((l1), (l2)) && mls_level_dom((l3), (l1))) + +#define mls_range_contains(r1, r2) \ +(mls_level_dom(&(r2).level[0], &(r1).level[0]) && \ + mls_level_dom(&(r1).level[1], &(r2).level[1])) + +static inline int mls_range_cpy(mls_range_t * dst, mls_range_t * src) +{ + + if (mls_level_cpy(&dst->level[0], &src->level[0]) < 0) + goto err; + + if (mls_level_cpy(&dst->level[1], &src->level[1]) < 0) + goto err_destroy; + + return 0; + + err_destroy: + mls_level_destroy(&dst->level[0]); + + err: + return -1; +} + +static inline void mls_range_init(struct mls_range *r) +{ + mls_level_init(&r->level[0]); + mls_level_init(&r->level[1]); +} + +static inline void mls_range_destroy(struct mls_range *r) +{ + mls_level_destroy(&r->level[0]); + mls_level_destroy(&r->level[1]); +} + +static inline int mls_range_eq(struct mls_range *r1, struct mls_range *r2) +{ + return (mls_level_eq(&r1->level[0], &r2->level[0]) && + mls_level_eq(&r1->level[1], &r2->level[1])); +} + +typedef struct mls_semantic_cat { + uint32_t low; /* first bit this struct represents */ + uint32_t high; /* last bit represented - equals low for a single cat */ + struct mls_semantic_cat *next; +} mls_semantic_cat_t; + +typedef struct mls_semantic_level { + uint32_t sens; + mls_semantic_cat_t *cat; +} mls_semantic_level_t; + +typedef struct mls_semantic_range { + mls_semantic_level_t level[2]; +} mls_semantic_range_t; + +extern void mls_semantic_cat_init(mls_semantic_cat_t *c); +extern void mls_semantic_cat_destroy(mls_semantic_cat_t *c); +extern void mls_semantic_level_init(mls_semantic_level_t *l); +extern void mls_semantic_level_destroy(mls_semantic_level_t *l); +extern int mls_semantic_level_cpy(mls_semantic_level_t *dst, mls_semantic_level_t *src); +extern void mls_semantic_range_init(mls_semantic_range_t *r); +extern void mls_semantic_range_destroy(mls_semantic_range_t *r); +extern int mls_semantic_range_cpy(mls_semantic_range_t *dst, mls_semantic_range_t *src); + +#endif diff --git a/include/sepol/policydb/module.h b/include/sepol/policydb/module.h new file mode 100644 index 0000000..10403c8 --- /dev/null +++ b/include/sepol/policydb/module.h @@ -0,0 +1,48 @@ +/* Author: Karl MacMillan <kmacmillan@tresys.com> + * + * Copyright (C) 2004-2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_MODULE_H_ +#define _SEPOL_POLICYDB_MODULE_H_ + +#include <stdlib.h> +#include <stddef.h> + +#include <sepol/module.h> + +#include <sepol/policydb/policydb.h> +#include <sepol/policydb/conditional.h> + +#define SEPOL_MODULE_PACKAGE_MAGIC 0xf97cff8f + +struct sepol_module_package { + sepol_policydb_t *policy; + uint32_t version; + char *file_contexts; + size_t file_contexts_len; + char *seusers; + size_t seusers_len; + char *user_extra; + size_t user_extra_len; + char *netfilter_contexts; + size_t netfilter_contexts_len; +}; + +extern int sepol_module_package_init(sepol_module_package_t * p); + +#endif diff --git a/include/sepol/policydb/polcaps.h b/include/sepol/policydb/polcaps.h new file mode 100644 index 0000000..40c0a48 --- /dev/null +++ b/include/sepol/policydb/polcaps.h @@ -0,0 +1,18 @@ +#ifndef _SEPOL_POLICYDB_POLCAPS_H_ +#define _SEPOL_POLICYDB_POLCAPS_H_ + +/* Policy capabilities */ +enum { + POLICYDB_CAPABILITY_NETPEER, + POLICYDB_CAPABILITY_OPENPERM, + __POLICYDB_CAPABILITY_MAX +}; +#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) + +/* Convert a capability name to number. */ +extern int sepol_polcap_getnum(const char *name); + +/* Convert a capability number to name. */ +extern const char *sepol_polcap_getname(int capnum); + +#endif /* _SEPOL_POLICYDB_POLCAPS_H_ */ diff --git a/include/sepol/policydb/policydb.h b/include/sepol/policydb/policydb.h new file mode 100644 index 0000000..5320bc8 --- /dev/null +++ b/include/sepol/policydb/policydb.h @@ -0,0 +1,724 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* + * Updated: Joshua Brindle <jbrindle@tresys.com> + * Karl MacMillan <kmacmillan@tresys.com> + * Jason Tang <jtang@tresys.com> + * + * Module support + * + * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> + * + * Support for enhanced MLS infrastructure. + * + * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> + * + * Added conditional policy language extensions + * + * Updated: Red Hat, Inc. James Morris <jmorris@redhat.com> + * + * Fine-grained netlink support + * IPv6 support + * Code cleanup + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Copyright (C) 2003 - 2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * A policy database (policydb) specifies the + * configuration data for the security policy. + */ + +#ifndef _SEPOL_POLICYDB_POLICYDB_H_ +#define _SEPOL_POLICYDB_POLICYDB_H_ + +#include <stdio.h> +#include <stddef.h> + +#include <sepol/policydb.h> + +#include <sepol/policydb/flask_types.h> +#include <sepol/policydb/symtab.h> +#include <sepol/policydb/avtab.h> +#include <sepol/policydb/context.h> +#include <sepol/policydb/constraint.h> +#include <sepol/policydb/sidtab.h> + +#define ERRMSG_LEN 1024 + +#define POLICYDB_SUCCESS 0 +#define POLICYDB_ERROR -1 +#define POLICYDB_UNSUPPORTED -2 + +/* + * A datum type is defined for each kind of symbol + * in the configuration data: individual permissions, + * common prefixes for access vectors, classes, + * users, roles, types, sensitivities, categories, etc. + */ + +/* type set preserves data needed by modules such as *, ~ and attributes */ +typedef struct type_set { + ebitmap_t types; + ebitmap_t negset; +#define TYPE_STAR 1 +#define TYPE_COMP 2 + uint32_t flags; +} type_set_t; + +typedef struct role_set { + ebitmap_t roles; +#define ROLE_STAR 1 +#define ROLE_COMP 2 + uint32_t flags; +} role_set_t; + +/* Permission attributes */ +typedef struct perm_datum { + symtab_datum_t s; +} perm_datum_t; + +/* Attributes of a common prefix for access vectors */ +typedef struct common_datum { + symtab_datum_t s; + symtab_t permissions; /* common permissions */ +} common_datum_t; + +/* Class attributes */ +typedef struct class_datum { + symtab_datum_t s; + char *comkey; /* common name */ + common_datum_t *comdatum; /* common datum */ + symtab_t permissions; /* class-specific permission symbol table */ + constraint_node_t *constraints; /* constraints on class permissions */ + constraint_node_t *validatetrans; /* special transition rules */ +} class_datum_t; + +/* Role attributes */ +typedef struct role_datum { + symtab_datum_t s; + ebitmap_t dominates; /* set of roles dominated by this role */ + type_set_t types; /* set of authorized types for role */ + ebitmap_t cache; /* This is an expanded set used for context validation during parsing */ + uint32_t bounds; /* bounds role, if exist */ +#define ROLE_ROLE 0 /* regular role in kernel policies */ +#define ROLE_ATTRIB 1 /* attribute */ + uint32_t flavor; + ebitmap_t roles; /* roles with this attribute */ +} role_datum_t; + +typedef struct role_trans { + uint32_t role; /* current role */ + uint32_t type; /* program executable type, or new object type */ + uint32_t tclass; /* process class, or new object class */ + uint32_t new_role; /* new role */ + struct role_trans *next; +} role_trans_t; + +typedef struct role_allow { + uint32_t role; /* current role */ + uint32_t new_role; /* new role */ + struct role_allow *next; +} role_allow_t; + +/* filename_trans rules */ +typedef struct filename_trans { + uint32_t stype; + uint32_t ttype; + uint32_t tclass; + char *name; + uint32_t otype; + struct filename_trans *next; +} filename_trans_t; + +/* Type attributes */ +typedef struct type_datum { + symtab_datum_t s; + uint32_t primary; /* primary name? can be set to primary value if below is TYPE_ */ +#define TYPE_TYPE 0 /* regular type or alias in kernel policies */ +#define TYPE_ATTRIB 1 /* attribute */ +#define TYPE_ALIAS 2 /* alias in modular policy */ + uint32_t flavor; + ebitmap_t types; /* types with this attribute */ +#define TYPE_FLAGS_PERMISSIVE 0x01 + uint32_t flags; + uint32_t bounds; /* bounds type, if exist */ +} type_datum_t; + +/* + * Properties of type_datum + * available on the policy version >= (MOD_)POLICYDB_VERSION_BOUNDARY + */ +#define TYPEDATUM_PROPERTY_PRIMARY 0x0001 +#define TYPEDATUM_PROPERTY_ATTRIBUTE 0x0002 +#define TYPEDATUM_PROPERTY_ALIAS 0x0004 /* userspace only */ +#define TYPEDATUM_PROPERTY_PERMISSIVE 0x0008 /* userspace only */ + +/* User attributes */ +typedef struct user_datum { + symtab_datum_t s; + role_set_t roles; /* set of authorized roles for user */ + mls_semantic_range_t range; /* MLS range (min. - max.) for user */ + mls_semantic_level_t dfltlevel; /* default login MLS level for user */ + ebitmap_t cache; /* This is an expanded set used for context validation during parsing */ + mls_range_t exp_range; /* expanded range used for validation */ + mls_level_t exp_dfltlevel; /* expanded range used for validation */ + uint32_t bounds; /* bounds user, if exist */ +} user_datum_t; + +/* Sensitivity attributes */ +typedef struct level_datum { + mls_level_t *level; /* sensitivity and associated categories */ + unsigned char isalias; /* is this sensitivity an alias for another? */ + unsigned char defined; +} level_datum_t; + +/* Category attributes */ +typedef struct cat_datum { + symtab_datum_t s; + unsigned char isalias; /* is this category an alias for another? */ +} cat_datum_t; + +typedef struct range_trans { + uint32_t source_type; + uint32_t target_type; + uint32_t target_class; + mls_range_t target_range; + struct range_trans *next; +} range_trans_t; + +/* Boolean data type */ +typedef struct cond_bool_datum { + symtab_datum_t s; + int state; +} cond_bool_datum_t; + +struct cond_node; + +typedef struct cond_node cond_list_t; +struct cond_av_list; + +typedef struct class_perm_node { + uint32_t class; + uint32_t data; /* permissions or new type */ + struct class_perm_node *next; +} class_perm_node_t; + +typedef struct avrule { +/* these typedefs are almost exactly the same as those in avtab.h - they are + * here because of the need to include neverallow and dontaudit messages */ +#define AVRULE_ALLOWED 1 +#define AVRULE_AUDITALLOW 2 +#define AVRULE_AUDITDENY 4 +#define AVRULE_DONTAUDIT 8 +#define AVRULE_NEVERALLOW 128 +#define AVRULE_AV (AVRULE_ALLOWED | AVRULE_AUDITALLOW | AVRULE_AUDITDENY | AVRULE_DONTAUDIT | AVRULE_NEVERALLOW) +#define AVRULE_TRANSITION 16 +#define AVRULE_MEMBER 32 +#define AVRULE_CHANGE 64 +#define AVRULE_TYPE (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE) + uint32_t specified; +#define RULE_SELF 1 + uint32_t flags; + type_set_t stypes; + type_set_t ttypes; + class_perm_node_t *perms; + unsigned long line; /* line number from policy.conf where + * this rule originated */ + struct avrule *next; +} avrule_t; + +typedef struct role_trans_rule { + role_set_t roles; /* current role */ + type_set_t types; /* program executable type, or new object type */ + ebitmap_t classes; /* process class, or new object class */ + uint32_t new_role; /* new role */ + struct role_trans_rule *next; +} role_trans_rule_t; + +typedef struct role_allow_rule { + role_set_t roles; /* current role */ + role_set_t new_roles; /* new roles */ + struct role_allow_rule *next; +} role_allow_rule_t; + +typedef struct filename_trans_rule { + type_set_t stypes; + type_set_t ttypes; + uint32_t tclass; + char *name; + uint32_t otype; /* new type */ + struct filename_trans_rule *next; +} filename_trans_rule_t; + +typedef struct range_trans_rule { + type_set_t stypes; + type_set_t ttypes; + ebitmap_t tclasses; + mls_semantic_range_t trange; + struct range_trans_rule *next; +} range_trans_rule_t; + +/* + * The configuration data includes security contexts for + * initial SIDs, unlabeled file systems, TCP and UDP port numbers, + * network interfaces, and nodes. This structure stores the + * relevant data for one such entry. Entries of the same kind + * (e.g. all initial SIDs) are linked together into a list. + */ +typedef struct ocontext { + union { + char *name; /* name of initial SID, fs, netif, fstype, path */ + struct { + uint8_t protocol; + uint16_t low_port; + uint16_t high_port; + } port; /* TCP or UDP port information */ + struct { + uint32_t addr; /* network order */ + uint32_t mask; /* network order */ + } node; /* node information */ + struct { + uint32_t addr[4]; /* network order */ + uint32_t mask[4]; /* network order */ + } node6; /* IPv6 node information */ + uint32_t device; + uint16_t pirq; + struct { + uint32_t low_iomem; + uint32_t high_iomem; + } iomem; + struct { + uint32_t low_ioport; + uint32_t high_ioport; + } ioport; + } u; + union { + uint32_t sclass; /* security class for genfs */ + uint32_t behavior; /* labeling behavior for fs_use */ + } v; + context_struct_t context[2]; /* security context(s) */ + sepol_security_id_t sid[2]; /* SID(s) */ + struct ocontext *next; +} ocontext_t; + +typedef struct genfs { + char *fstype; + struct ocontext *head; + struct genfs *next; +} genfs_t; + +/* symbol table array indices */ +#define SYM_COMMONS 0 +#define SYM_CLASSES 1 +#define SYM_ROLES 2 +#define SYM_TYPES 3 +#define SYM_USERS 4 +#define SYM_BOOLS 5 +#define SYM_LEVELS 6 +#define SYM_CATS 7 +#define SYM_NUM 8 + +/* object context array indices */ +#define OCON_ISID 0 /* initial SIDs */ +#define OCON_FS 1 /* unlabeled file systems */ +#define OCON_PORT 2 /* TCP and UDP port numbers */ +#define OCON_NETIF 3 /* network interfaces */ +#define OCON_NODE 4 /* nodes */ +#define OCON_FSUSE 5 /* fs_use */ +#define OCON_NODE6 6 /* IPv6 nodes */ +#define OCON_GENFS 7 /* needed for ocontext_supported */ + +/* object context array indices for Xen */ +#define OCON_XEN_ISID 0 /* initial SIDs */ +#define OCON_XEN_PIRQ 1 /* physical irqs */ +#define OCON_XEN_IOPORT 2 /* io ports */ +#define OCON_XEN_IOMEM 3 /* io memory */ +#define OCON_XEN_PCIDEVICE 4 /* pci devices */ + +/* OCON_NUM needs to be the largest index in any platform's ocontext array */ +#define OCON_NUM 7 + +/* section: module information */ + +/* scope_index_t holds all of the symbols that are in scope in a + * particular situation. The bitmaps are indices (and thus must + * subtract one) into the global policydb->scope array. */ +typedef struct scope_index { + ebitmap_t scope[SYM_NUM]; +#define p_classes_scope scope[SYM_CLASSES] +#define p_roles_scope scope[SYM_ROLES] +#define p_types_scope scope[SYM_TYPES] +#define p_users_scope scope[SYM_USERS] +#define p_bools_scope scope[SYM_BOOLS] +#define p_sens_scope scope[SYM_LEVELS] +#define p_cat_scope scope[SYM_CATS] + + /* this array maps from class->value to the permissions within + * scope. if bit (perm->value - 1) is set in map + * class_perms_map[class->value - 1] then that permission is + * enabled for this class within this decl. */ + ebitmap_t *class_perms_map; + /* total number of classes in class_perms_map array */ + uint32_t class_perms_len; +} scope_index_t; + +/* a list of declarations for a particular avrule_decl */ + +/* These two structs declare a block of policy that has TE and RBAC + * statements and declarations. The root block (the global policy) + * can never have an ELSE branch. */ +typedef struct avrule_decl { + uint32_t decl_id; + uint32_t enabled; /* whether this block is enabled */ + + cond_list_t *cond_list; + avrule_t *avrules; + role_trans_rule_t *role_tr_rules; + role_allow_rule_t *role_allow_rules; + range_trans_rule_t *range_tr_rules; + scope_index_t required; /* symbols needed to activate this block */ + scope_index_t declared; /* symbols declared within this block */ + + /* type transition rules with a 'name' component */ + filename_trans_rule_t *filename_trans_rules; + + /* for additive statements (type attribute, roles, and users) */ + symtab_t symtab[SYM_NUM]; + + /* In a linked module this will contain the name of the module + * from which this avrule_decl originated. */ + char *module_name; + + struct avrule_decl *next; +} avrule_decl_t; + +typedef struct avrule_block { + avrule_decl_t *branch_list; + avrule_decl_t *enabled; /* pointer to which branch is enabled. this is + used in linking and never written to disk */ +#define AVRULE_OPTIONAL 1 + uint32_t flags; /* any flags for this block, currently just optional */ + struct avrule_block *next; +} avrule_block_t; + +/* Every identifier has its own scope datum. The datum describes if + * the item is to be included into the final policy during + * expansion. */ +typedef struct scope_datum { +/* Required for this decl */ +#define SCOPE_REQ 1 +/* Declared in this decl */ +#define SCOPE_DECL 2 + uint32_t scope; + uint32_t *decl_ids; + uint32_t decl_ids_len; + /* decl_ids is a list of avrule_decl's that declare/require + * this symbol. If scope==SCOPE_DECL then this is a list of + * declarations. If the symbol may only be declared once + * (types, bools) then decl_ids_len will be exactly 1. For + * implicitly declared things (roles, users) then decl_ids_len + * will be at least 1. */ +} scope_datum_t; + +/* The policy database */ +typedef struct policydb { +#define POLICY_KERN SEPOL_POLICY_KERN +#define POLICY_BASE SEPOL_POLICY_BASE +#define POLICY_MOD SEPOL_POLICY_MOD + uint32_t policy_type; + char *name; + char *version; + int target_platform; + + /* Set when the policydb is modified such that writing is unsupported */ + int unsupported_format; + + /* Whether this policydb is mls, should always be set */ + int mls; + + /* symbol tables */ + symtab_t symtab[SYM_NUM]; +#define p_commons symtab[SYM_COMMONS] +#define p_classes symtab[SYM_CLASSES] +#define p_roles symtab[SYM_ROLES] +#define p_types symtab[SYM_TYPES] +#define p_users symtab[SYM_USERS] +#define p_bools symtab[SYM_BOOLS] +#define p_levels symtab[SYM_LEVELS] +#define p_cats symtab[SYM_CATS] + + /* symbol names indexed by (value - 1) */ + char **sym_val_to_name[SYM_NUM]; +#define p_common_val_to_name sym_val_to_name[SYM_COMMONS] +#define p_class_val_to_name sym_val_to_name[SYM_CLASSES] +#define p_role_val_to_name sym_val_to_name[SYM_ROLES] +#define p_type_val_to_name sym_val_to_name[SYM_TYPES] +#define p_user_val_to_name sym_val_to_name[SYM_USERS] +#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS] +#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS] +#define p_cat_val_to_name sym_val_to_name[SYM_CATS] + + /* class, role, and user attributes indexed by (value - 1) */ + class_datum_t **class_val_to_struct; + role_datum_t **role_val_to_struct; + user_datum_t **user_val_to_struct; + type_datum_t **type_val_to_struct; + + /* module stuff section -- used in parsing and for modules */ + + /* keep track of the scope for every identifier. these are + * hash tables, where the key is the identifier name and value + * a scope_datum_t. as a convenience, one may use the + * p_*_macros (cf. struct scope_index_t declaration). */ + symtab_t scope[SYM_NUM]; + + /* module rule storage */ + avrule_block_t *global; + /* avrule_decl index used for link/expand */ + avrule_decl_t **decl_val_to_struct; + + /* compiled storage of rules - use for the kernel policy */ + + /* type enforcement access vectors and transitions */ + avtab_t te_avtab; + + /* bools indexed by (value - 1) */ + cond_bool_datum_t **bool_val_to_struct; + /* type enforcement conditional access vectors and transitions */ + avtab_t te_cond_avtab; + /* linked list indexing te_cond_avtab by conditional */ + cond_list_t *cond_list; + + /* role transitions */ + role_trans_t *role_tr; + + /* type transition rules with a 'name' component */ + filename_trans_t *filename_trans; + + /* role allows */ + role_allow_t *role_allow; + + /* security contexts of initial SIDs, unlabeled file systems, + TCP or UDP port numbers, network interfaces and nodes */ + ocontext_t *ocontexts[OCON_NUM]; + + /* security contexts for files in filesystems that cannot support + a persistent label mapping or use another + fixed labeling behavior. */ + genfs_t *genfs; + + /* range transitions */ + range_trans_t *range_tr; + + ebitmap_t *type_attr_map; + + ebitmap_t *attr_type_map; /* not saved in the binary policy */ + + ebitmap_t policycaps; + + /* this bitmap is referenced by type NOT the typical type-1 used in other + bitmaps. Someday the 0 bit may be used for global permissive */ + ebitmap_t permissive_map; + + unsigned policyvers; + + unsigned handle_unknown; +} policydb_t; + +struct sepol_policydb { + struct policydb p; +}; + +extern int policydb_init(policydb_t * p); + +extern int policydb_from_image(sepol_handle_t * handle, + void *data, size_t len, policydb_t * policydb); + +extern int policydb_to_image(sepol_handle_t * handle, + policydb_t * policydb, void **newdata, + size_t * newlen); + +extern int policydb_index_classes(policydb_t * p); + +extern int policydb_index_bools(policydb_t * p); + +extern int policydb_index_others(sepol_handle_t * handle, policydb_t * p, + unsigned int verbose); + +extern int policydb_reindex_users(policydb_t * p); + +extern void policydb_destroy(policydb_t * p); + +extern int policydb_load_isids(policydb_t * p, sidtab_t * s); + +/* Deprecated */ +extern int policydb_context_isvalid(const policydb_t * p, + const context_struct_t * c); + +extern void symtabs_destroy(symtab_t * symtab); +extern int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p); +typedef void (*hashtab_destroy_func_t) (hashtab_key_t k, hashtab_datum_t d, + void *args); +extern hashtab_destroy_func_t get_symtab_destroy_func(int sym_num); + +extern void class_perm_node_init(class_perm_node_t * x); +extern void type_set_init(type_set_t * x); +extern void type_set_destroy(type_set_t * x); +extern int type_set_cpy(type_set_t * dst, type_set_t * src); +extern int type_set_or_eq(type_set_t * dst, type_set_t * other); +extern void role_set_init(role_set_t * x); +extern void role_set_destroy(role_set_t * x); +extern void avrule_init(avrule_t * x); +extern void avrule_destroy(avrule_t * x); +extern void avrule_list_destroy(avrule_t * x); +extern void role_trans_rule_init(role_trans_rule_t * x); +extern void role_trans_rule_list_destroy(role_trans_rule_t * x); +extern void filename_trans_rule_init(filename_trans_rule_t * x); +extern void filename_trans_rule_list_destroy(filename_trans_rule_t * x); + +extern void role_datum_init(role_datum_t * x); +extern void role_datum_destroy(role_datum_t * x); +extern void role_allow_rule_init(role_allow_rule_t * x); +extern void role_allow_rule_destroy(role_allow_rule_t * x); +extern void role_allow_rule_list_destroy(role_allow_rule_t * x); +extern void range_trans_rule_init(range_trans_rule_t *x); +extern void range_trans_rule_destroy(range_trans_rule_t *x); +extern void range_trans_rule_list_destroy(range_trans_rule_t *x); +extern void type_datum_init(type_datum_t * x); +extern void type_datum_destroy(type_datum_t * x); +extern void user_datum_init(user_datum_t * x); +extern void user_datum_destroy(user_datum_t * x); +extern void level_datum_init(level_datum_t * x); +extern void level_datum_destroy(level_datum_t * x); +extern void cat_datum_init(cat_datum_t * x); +extern void cat_datum_destroy(cat_datum_t * x); + +extern int check_assertions(sepol_handle_t * handle, + policydb_t * p, avrule_t * avrules); + +extern int symtab_insert(policydb_t * x, uint32_t sym, + hashtab_key_t key, hashtab_datum_t datum, + uint32_t scope, uint32_t avrule_decl_id, + uint32_t * value); + +/* A policy "file" may be a memory region referenced by a (data, len) pair + or a file referenced by a FILE pointer. */ +typedef struct policy_file { +#define PF_USE_MEMORY 0 +#define PF_USE_STDIO 1 +#define PF_LEN 2 /* total up length in len field */ + unsigned type; + char *data; + size_t len; + size_t size; + FILE *fp; + struct sepol_handle *handle; +} policy_file_t; + +struct sepol_policy_file { + struct policy_file pf; +}; + +extern void policy_file_init(policy_file_t * x); + +extern int policydb_read(policydb_t * p, struct policy_file *fp, + unsigned int verbose); +extern int avrule_read_list(policydb_t * p, avrule_t ** avrules, + struct policy_file *fp); + +extern int policydb_write(struct policydb *p, struct policy_file *pf); +extern int policydb_set_target_platform(policydb_t *p, int platform); + +#define PERM_SYMTAB_SIZE 32 + +/* 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 + +/* Range of policy versions we understand*/ +#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS + +/* Module versions and specific changes*/ +#define MOD_POLICYDB_VERSION_BASE 4 +#define MOD_POLICYDB_VERSION_VALIDATETRANS 5 +#define MOD_POLICYDB_VERSION_MLS 5 +#define MOD_POLICYDB_VERSION_RANGETRANS 6 +#define MOD_POLICYDB_VERSION_MLS_USERS 6 +#define MOD_POLICYDB_VERSION_POLCAP 7 +#define MOD_POLICYDB_VERSION_PERMISSIVE 8 +#define MOD_POLICYDB_VERSION_BOUNDARY 9 +#define MOD_POLICYDB_VERSION_BOUNDARY_ALIAS 10 +#define MOD_POLICYDB_VERSION_FILENAME_TRANS 11 +#define MOD_POLICYDB_VERSION_ROLETRANS 12 +#define MOD_POLICYDB_VERSION_ROLEATTRIB 13 + +#define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_ROLEATTRIB + +#define POLICYDB_CONFIG_MLS 1 + +/* macros to check policy feature */ + +/* TODO: add other features here */ + +#define policydb_has_boundary_feature(p) \ + (((p)->policy_type == POLICY_KERN \ + && p->policyvers >= POLICYDB_VERSION_BOUNDARY) || \ + ((p)->policy_type != POLICY_KERN \ + && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY)) + +/* the config flags related to unknown classes/perms are bits 2 and 3 */ +#define DENY_UNKNOWN SEPOL_DENY_UNKNOWN +#define REJECT_UNKNOWN SEPOL_REJECT_UNKNOWN +#define ALLOW_UNKNOWN SEPOL_ALLOW_UNKNOWN + +#define POLICYDB_CONFIG_UNKNOWN_MASK (DENY_UNKNOWN | REJECT_UNKNOWN | ALLOW_UNKNOWN) + +#define OBJECT_R "object_r" +#define OBJECT_R_VAL 1 + +#define POLICYDB_MAGIC SELINUX_MAGIC +#define POLICYDB_STRING "SE Linux" +#define POLICYDB_XEN_STRING "XenFlask" +#define POLICYDB_STRING_MAX_LENGTH 32 +#define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC +#define POLICYDB_MOD_STRING "SE Linux Module" +#define SEPOL_TARGET_SELINUX 0 +#define SEPOL_TARGET_XEN 1 + + +#endif /* _POLICYDB_H_ */ + +/* FLASK */ diff --git a/include/sepol/policydb/services.h b/include/sepol/policydb/services.h new file mode 100644 index 0000000..aef0c7b --- /dev/null +++ b/include/sepol/policydb/services.h @@ -0,0 +1,184 @@ + +/* -*- linux-c -*- */ + +/* + * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + */ + +#ifndef _SEPOL_POLICYDB_SERVICES_H_ +#define _SEPOL_POLICYDB_SERVICES_H_ + +/* + * Security server interface. + */ + +#include <sepol/policydb/flask_types.h> +#include <sepol/policydb/policydb.h> +#include <stddef.h> + +/* Set the policydb and sidtab structures to be used by + the service functions. If not set, then these default + to private structures within libsepol that can only be + initialized and accessed via the service functions themselves. + Setting the structures explicitly allows a program to directly + manipulate them, e.g. checkpolicy populates the structures directly + from a source policy rather than from a binary policy. */ +extern int sepol_set_policydb(policydb_t * p); +extern int sepol_set_sidtab(sidtab_t * s); + +/* Modify a policydb for boolean settings. */ +int sepol_genbools_policydb(policydb_t * policydb, const char *booleans); + +/* Modify a policydb for user settings. */ +int sepol_genusers_policydb(policydb_t * policydb, const char *usersdir); + +/* Load the security policy. This initializes the policydb + and sidtab based on the provided binary policy. */ +extern int sepol_load_policy(void *data, size_t len); + +/* + * Compute access vectors based on a SID pair for + * the permissions in a particular class. + */ +extern int sepol_compute_av(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_access_vector_t requested, /* IN */ + struct sepol_av_decision *avd); /* OUT */ + +/* Same as above, but also return the reason(s) for any + denials of the requested permissions. */ +#define SEPOL_COMPUTEAV_TE 1 +#define SEPOL_COMPUTEAV_CONS 2 +#define SEPOL_COMPUTEAV_RBAC 4 +extern int sepol_compute_av_reason(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason); + +/* + * Compute a SID to use for labeling a new object in the + * class `tclass' based on a SID pair. + */ +extern int sepol_transition_sid(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Compute a SID to use when selecting a member of a + * polyinstantiated object of class `tclass' based on + * a SID pair. + */ +extern int sepol_member_sid(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Compute a SID to use for relabeling an object in the + * class `tclass' based on a SID pair. + */ +extern int sepol_change_sid(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Write the security context string representation of + * the context associated with `sid' into a dynamically + * allocated string of the correct size. Set `*scontext' + * to point to this string and set `*scontext_len' to + * the length of the string. + */ +extern int sepol_sid_to_context(sepol_security_id_t sid, /* IN */ + sepol_security_context_t * scontext, /* OUT */ + size_t * scontext_len); /* OUT */ + +/* + * Return a SID associated with the security context that + * has the string representation specified by `scontext'. + */ +extern int sepol_context_to_sid(const sepol_security_context_t scontext, /* IN */ + size_t scontext_len, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Generate the set of SIDs for legal security contexts + * for a given user that can be reached by `fromsid'. + * Set `*sids' to point to a dynamically allocated + * array containing the set of SIDs. Set `*nel' to the + * number of elements in the array. + */ +extern int sepol_get_user_sids(sepol_security_id_t callsid, + char *username, + sepol_security_id_t ** sids, uint32_t * nel); + +/* + * Return the SIDs to use for an unlabeled file system + * that is being mounted from the device with the + * the kdevname `name'. The `fs_sid' SID is returned for + * the file system and the `file_sid' SID is returned + * for all files within that file system. + */ +extern int sepol_fs_sid(char *dev, /* IN */ + sepol_security_id_t * fs_sid, /* OUT */ + sepol_security_id_t * file_sid); /* OUT */ + +/* + * Return the SID of the port specified by + * `domain', `type', `protocol', and `port'. + */ +extern int sepol_port_sid(uint16_t domain, + uint16_t type, + uint8_t protocol, + uint16_t port, sepol_security_id_t * out_sid); + +/* + * Return the SIDs to use for a network interface + * with the name `name'. The `if_sid' SID is returned for + * the interface and the `msg_sid' SID is returned as + * the default SID for messages received on the + * interface. + */ +extern int sepol_netif_sid(char *name, + sepol_security_id_t * if_sid, + sepol_security_id_t * msg_sid); + +/* + * Return the SID of the node specified by the address + * `addr' where `addrlen' is the length of the address + * in bytes and `domain' is the communications domain or + * address family in which the address should be interpreted. + */ +extern int sepol_node_sid(uint16_t domain, + void *addr, + size_t addrlen, sepol_security_id_t * out_sid); + +/* + * Return a value indicating how to handle labeling for the + * the specified filesystem type, and optionally return a SID + * for the filesystem object. + */ +#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 */ +extern int sepol_fs_use(const char *fstype, /* IN */ + unsigned int *behavior, /* OUT */ + sepol_security_id_t * sid); /* OUT */ + +/* + * Return the SID to use for a file in a filesystem + * that cannot support a persistent label mapping or use another + * fixed labeling behavior like transition SIDs or task SIDs. + */ +extern int sepol_genfs_sid(const char *fstype, /* IN */ + char *name, /* IN */ + sepol_security_class_t sclass, /* IN */ + sepol_security_id_t * sid); /* OUT */ + +#endif diff --git a/include/sepol/policydb/sidtab.h b/include/sepol/policydb/sidtab.h new file mode 100644 index 0000000..33c7cb5 --- /dev/null +++ b/include/sepol/policydb/sidtab.h @@ -0,0 +1,72 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* FLASK */ + +/* + * A security identifier table (sidtab) is a hash table + * of security context structures indexed by SID value. + */ + +#ifndef _SEPOL_POLICYDB_SIDTAB_H_ +#define _SEPOL_POLICYDB_SIDTAB_H_ + +#include <sepol/policydb/context.h> + +typedef struct sidtab_node { + sepol_security_id_t sid; /* security identifier */ + context_struct_t context; /* security context structure */ + struct sidtab_node *next; +} sidtab_node_t; + +typedef struct sidtab_node *sidtab_ptr_t; + +#define SIDTAB_HASH_BITS 7 +#define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS) +#define SIDTAB_HASH_MASK (SIDTAB_HASH_BUCKETS-1) + +#define SIDTAB_SIZE SIDTAB_HASH_BUCKETS + +typedef struct { + sidtab_ptr_t *htable; + unsigned int nel; /* number of elements */ + unsigned int next_sid; /* next SID to allocate */ + unsigned char shutdown; +} sidtab_t; + +extern int sepol_sidtab_init(sidtab_t * s); + +extern int sepol_sidtab_insert(sidtab_t * s, + sepol_security_id_t sid, + context_struct_t * context); + +extern context_struct_t *sepol_sidtab_search(sidtab_t * s, + sepol_security_id_t sid); + +extern int sepol_sidtab_map(sidtab_t * s, + int (*apply) (sepol_security_id_t sid, + context_struct_t * context, + void *args), void *args); + +extern void sepol_sidtab_map_remove_on_error(sidtab_t * s, + int (*apply) (sepol_security_id_t + s, + context_struct_t * + context, void *args), + void *args); + +extern int sepol_sidtab_context_to_sid(sidtab_t * s, /* IN */ + context_struct_t * context, /* IN */ + sepol_security_id_t * sid); /* OUT */ + +extern void sepol_sidtab_hash_eval(sidtab_t * h, char *tag); + +extern void sepol_sidtab_destroy(sidtab_t * s); + +extern void sepol_sidtab_set(sidtab_t * dst, sidtab_t * src); + +extern void sepol_sidtab_shutdown(sidtab_t * s); + +#endif /* _SIDTAB_H_ */ + +/* FLASK */ diff --git a/include/sepol/policydb/symtab.h b/include/sepol/policydb/symtab.h new file mode 100644 index 0000000..c8ad664 --- /dev/null +++ b/include/sepol/policydb/symtab.h @@ -0,0 +1,38 @@ + +/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ + +/* FLASK */ + +/* + * A symbol table (symtab) maintains associations between symbol + * strings and datum values. The type of the datum values + * is arbitrary. The symbol table type is implemented + * using the hash table type (hashtab). + */ + +#ifndef _SEPOL_POLICYDB_SYMTAB_H_ +#define _SEPOL_POLICYDB_SYMTAB_H_ + +#include <sepol/policydb/hashtab.h> + +/* The symtab_datum struct stores the common information for + * all symtab datums. It should the first element in every + * struct that will be used in a symtab to allow the specific + * datum types to be freely cast to this type. + * + * The values start at 1 - 0 is never a valid value. + */ +typedef struct symtab_datum { + uint32_t value; +} symtab_datum_t; + +typedef struct { + hashtab_t table; /* hash table (keyed on a string) */ + uint32_t nprim; /* number of primary names in table */ +} symtab_t; + +extern int symtab_init(symtab_t *, unsigned int size); + +#endif /* _SYMTAB_H_ */ + +/* FLASK */ diff --git a/include/sepol/policydb/util.h b/include/sepol/policydb/util.h new file mode 100644 index 0000000..40bfaa6 --- /dev/null +++ b/include/sepol/policydb/util.h @@ -0,0 +1,31 @@ +/* Authors: Karl MacMillan <kmacmillan@tresys.com> + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal namespaces. + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SEPOL_UTIL_H__ +#define __SEPOL_UTIL_H__ + +extern int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a); + +extern char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass, + sepol_access_vector_t av); + +#endif diff --git a/include/sepol/port_record.h b/include/sepol/port_record.h new file mode 100644 index 0000000..b347e08 --- /dev/null +++ b/include/sepol/port_record.h @@ -0,0 +1,66 @@ +#ifndef _SEPOL_PORT_RECORD_H_ +#define _SEPOL_PORT_RECORD_H_ + +#include <sepol/context_record.h> +#include <sepol/handle.h> + +struct sepol_port; +struct sepol_port_key; +typedef struct sepol_port sepol_port_t; +typedef struct sepol_port_key sepol_port_key_t; + +#define SEPOL_PROTO_UDP 0 +#define SEPOL_PROTO_TCP 1 + +/* Key */ +extern int sepol_port_compare(const sepol_port_t * port, + const sepol_port_key_t * key); + +extern int sepol_port_compare2(const sepol_port_t * port, + const sepol_port_t * port2); + +extern int sepol_port_key_create(sepol_handle_t * handle, + int low, int high, int proto, + sepol_port_key_t ** key_ptr); + +extern void sepol_port_key_unpack(const sepol_port_key_t * key, + int *low, int *high, int *proto); + +extern int sepol_port_key_extract(sepol_handle_t * handle, + const sepol_port_t * port, + sepol_port_key_t ** key_ptr); + +extern void sepol_port_key_free(sepol_port_key_t * key); + +/* Protocol */ +extern int sepol_port_get_proto(const sepol_port_t * port); + +extern void sepol_port_set_proto(sepol_port_t * port, int proto); + +extern const char *sepol_port_get_proto_str(int proto); + +/* Port */ +extern int sepol_port_get_low(const sepol_port_t * port); + +extern int sepol_port_get_high(const sepol_port_t * port); + +extern void sepol_port_set_port(sepol_port_t * port, int port_num); + +extern void sepol_port_set_range(sepol_port_t * port, int low, int high); + +/* Context */ +extern sepol_context_t *sepol_port_get_con(const sepol_port_t * port); + +extern int sepol_port_set_con(sepol_handle_t * handle, + sepol_port_t * port, sepol_context_t * con); + +/* Create/Clone/Destroy */ +extern int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port_ptr); + +extern int sepol_port_clone(sepol_handle_t * handle, + const sepol_port_t * port, + sepol_port_t ** port_ptr); + +extern void sepol_port_free(sepol_port_t * port); + +#endif diff --git a/include/sepol/ports.h b/include/sepol/ports.h new file mode 100644 index 0000000..fb94117 --- /dev/null +++ b/include/sepol/ports.h @@ -0,0 +1,40 @@ +#ifndef _SEPOL_PORTS_H_ +#define _SEPOL_PORTS_H_ + +#include <sepol/handle.h> +#include <sepol/policydb.h> +#include <sepol/port_record.h> + +/* Return the number of ports */ +extern int sepol_port_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if a port exists */ +extern int sepol_port_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_port_key_t * key, int *response); + +/* Query a port - returns the port, or NULL if not found */ +extern int sepol_port_query(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_port_key_t * key, + sepol_port_t ** response); + +/* Modify a port, or add it, if the key is not found */ +extern int sepol_port_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_port_key_t * key, + const sepol_port_t * data); + +/* Iterate the ports + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_port_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_port_t * port, + void *fn_arg), void *arg); + +#endif diff --git a/include/sepol/roles.h b/include/sepol/roles.h new file mode 100644 index 0000000..113f9d2 --- /dev/null +++ b/include/sepol/roles.h @@ -0,0 +1,10 @@ +#ifndef _SEPOL_ROLES_H_ +#define _SEPOL_ROLES_H_ + +extern int sepol_role_exists(const sepol_policydb_t * policydb, + const char *role, int *response); + +extern int sepol_role_list(const sepol_policydb_t * policydb, + char ***roles, unsigned int *nroles); + +#endif diff --git a/include/sepol/sepol.h b/include/sepol/sepol.h new file mode 100644 index 0000000..c8900d3 --- /dev/null +++ b/include/sepol/sepol.h @@ -0,0 +1,28 @@ +#ifndef _SEPOL_H_ +#define _SEPOL_H_ + +#include <stddef.h> +#include <stdio.h> + +#include <sepol/user_record.h> +#include <sepol/context_record.h> +#include <sepol/iface_record.h> +#include <sepol/port_record.h> +#include <sepol/boolean_record.h> +#include <sepol/node_record.h> + +#include <sepol/booleans.h> +#include <sepol/interfaces.h> +#include <sepol/ports.h> +#include <sepol/nodes.h> +#include <sepol/users.h> +#include <sepol/handle.h> +#include <sepol/debug.h> +#include <sepol/policydb.h> +#include <sepol/module.h> +#include <sepol/context.h> + +/* Set internal policydb from a file for subsequent service calls. */ +extern int sepol_set_policydb_from_file(FILE * fp); + +#endif diff --git a/include/sepol/user_record.h b/include/sepol/user_record.h new file mode 100644 index 0000000..c86ad16 --- /dev/null +++ b/include/sepol/user_record.h @@ -0,0 +1,76 @@ +#ifndef _SEPOL_USER_RECORD_H_ +#define _SEPOL_USER_RECORD_H_ + +#include <stddef.h> +#include <sepol/handle.h> + +struct sepol_user; +struct sepol_user_key; +typedef struct sepol_user sepol_user_t; +typedef struct sepol_user_key sepol_user_key_t; + +/* Key */ +extern int sepol_user_key_create(sepol_handle_t * handle, + const char *name, sepol_user_key_t ** key); + +extern void sepol_user_key_unpack(const sepol_user_key_t * key, + const char **name); + +extern int sepol_user_key_extract(sepol_handle_t * handle, + const sepol_user_t * user, + sepol_user_key_t ** key_ptr); + +extern void sepol_user_key_free(sepol_user_key_t * key); + +extern int sepol_user_compare(const sepol_user_t * user, + const sepol_user_key_t * key); + +extern int sepol_user_compare2(const sepol_user_t * user, + const sepol_user_t * user2); + +/* Name */ +extern const char *sepol_user_get_name(const sepol_user_t * user); + +extern int sepol_user_set_name(sepol_handle_t * handle, + sepol_user_t * user, const char *name); + +/* MLS */ +extern const char *sepol_user_get_mlslevel(const sepol_user_t * user); + +extern int sepol_user_set_mlslevel(sepol_handle_t * handle, + sepol_user_t * user, const char *mls_level); + +extern const char *sepol_user_get_mlsrange(const sepol_user_t * user); + +extern int sepol_user_set_mlsrange(sepol_handle_t * handle, + sepol_user_t * user, const char *mls_range); + +/* Role management */ +extern int sepol_user_get_num_roles(const sepol_user_t * user); + +extern int sepol_user_add_role(sepol_handle_t * handle, + sepol_user_t * user, const char *role); + +extern void sepol_user_del_role(sepol_user_t * user, const char *role); + +extern int sepol_user_has_role(const sepol_user_t * user, const char *role); + +extern int sepol_user_get_roles(sepol_handle_t * handle, + const sepol_user_t * user, + const char ***roles_arr, + unsigned int *num_roles); + +extern int sepol_user_set_roles(sepol_handle_t * handle, + sepol_user_t * user, + const char **roles_arr, unsigned int num_roles); + +/* Create/Clone/Destroy */ +extern int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr); + +extern int sepol_user_clone(sepol_handle_t * handle, + const sepol_user_t * user, + sepol_user_t ** user_ptr); + +extern void sepol_user_free(sepol_user_t * user); + +#endif diff --git a/include/sepol/users.h b/include/sepol/users.h new file mode 100644 index 0000000..01b0775 --- /dev/null +++ b/include/sepol/users.h @@ -0,0 +1,57 @@ +#ifndef _SEPOL_USERS_H_ +#define _SEPOL_USERS_H_ + +#include <sepol/policydb.h> +#include <sepol/user_record.h> +#include <sepol/handle.h> +#include <stddef.h> + +/*---------compatibility------------*/ + +/* Given an existing binary policy (starting at 'data with length 'len') + and user configurations living in 'usersdir', generate a new binary + policy for the new user configurations. Sets '*newdata' and '*newlen' + to refer to the new binary policy image. */ +extern int sepol_genusers(void *data, size_t len, + const char *usersdir, + void **newdata, size_t * newlen); + +/* Enable or disable deletion of users by sepol_genusers(3) when + a user in original binary policy image is not defined by the + new user configurations. Defaults to disabled. */ +extern void sepol_set_delusers(int on); + +/*--------end compatibility----------*/ + +/* Modify the user, or add it, if the key is not found */ +extern int sepol_user_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_user_key_t * key, + const sepol_user_t * data); + +/* Return the number of users */ +extern int sepol_user_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if the specified user exists */ +extern int sepol_user_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_user_key_t * key, int *response); + +/* Query a user - returns the user or NULL if not found */ +extern int sepol_user_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_user_key_t * key, + sepol_user_t ** response); + +/* Iterate the users + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ +extern int sepol_user_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_user_t * user, + void *fn_arg), void *arg); + +#endif |