Files
ImHex-Patterns/patterns/selinux.hexpat

716 lines
16 KiB
Rust

#pragma description SE Linux modules
#include <std/sys.pat>
#pragma pattern_limit 13107200
#pragma endian little
u32 version;
u32 symbols_count;
u32 object_contexts_count;
u32 type_primary_names_count = 0;
bool boundary_feature;
using Header;
enum magics: u32 {
kernel = 0xf97cff8c,
module = 0xf97cff8d,
};
enum policy_types: u32 {
kernel = 0,
base = 1,
module = 2,
};
policy_types type_g;
enum targets: u32 {
selinux = 0,
xen = 1,
};
targets target;
struct list<T> {
u32 count;
T item[count];
};
struct symbols_list<T> {
u32 primary_names_count;
list<T> [[inline]];
};
struct permission {
u32 length;
u32 value;
char key[length];
};
struct extensible_bitmap_node {
u32 startbit;
u64 map;
};
struct extensible_bitmap {
u32 mapsize;
std::assert(mapsize == 0x40 , "Incorrect mapsize");
u32 highbit;
std::assert(!(highbit & 0x3F) , "Incorrect highbit");
u32 count;
std::assert(!((highbit > 0) && (count == 0)) , "Incorrect bitmap");
extensible_bitmap_node node[count];
};
struct type_set {
extensible_bitmap types;
extensible_bitmap negset;
u32 flag;
};
enum expression_types: u32 {
not = 1,
and = 2,
or = 3,
attr = 4,
names = 5,
};
struct expression {
expression_types type_;
u32 attribute;
u32 operator;
if (type_ == expression_types::names) {
extensible_bitmap names;
if ((type_g == policy_types::kernel && version >= 29) ||
(type_g != policy_types::kernel))
type_set type_names;
}
};
struct constraint {
u32 permissions;
list<expression> [[inline]];
};
struct mls_range {
u32 items;
u32 sensitivity0;
if (items > 1)
u32 sensitivity1;
extensible_bitmap category0;
if (items > 1)
extensible_bitmap category1;
};
struct role_set {
extensible_bitmap roles;
u32 flags;
};
struct mls_level {
u32 sensitivity;
extensible_bitmap category;
};
struct semantic_category {
u32 low;
u32 high;
};
struct mls_semantic_level {
u32 sensitivity;
list<semantic_category> [[inline]];
};
struct mls_semantic_range {
mls_semantic_level level0;
mls_semantic_level level1;
};
struct context_s {
u32 user;
u32 role;
u32 type_;
if (((type_g == policy_types::kernel) && (version >= 19)) || ((type_g == policy_types::base) && (version >= 5)))
mls_range mls_range;
};
struct common {
u32 length;
u32 value;
u32 primary_names_count;
u32 elements_count;
char key[length];
permission permission[elements_count];
};
using commons = symbols_list<common>;
struct class {
u32 key_length;
u32 common_key_length;
u32 value;
u32 primary_names_count;
u32 elements_count;
u32 constraints_count;
char key[key_length];
char common_key[common_key_length];
permission permissions[elements_count];
constraint constraints[constraints_count];
if (((type_g == policy_types::kernel) && (version >= 19)) || (type_g == policy_types::base && version >= 5))
u32 validatetrans_count;
if ((type_g == policy_types::kernel && version >= 19) || (type_g == policy_types::base && version >= 5))
constraint validatetrans[validatetrans_count];
if ((type_g == policy_types::kernel && version >= 27) || (type_g == policy_types::base && version >= 15)) {
u32 default_user;
u32 default_role;
u32 default_range;
}
if ((type_g == policy_types::kernel && version >= 28) || (type_g == policy_types::base && version >= 16))
u32 default_type;
};
using classes = symbols_list<class>;
struct role_s {
u32 length;
u32 value;
u32 bounds;
char key[length];
extensible_bitmap dominates;
if (type_g == policy_types::kernel)
extensible_bitmap types;
else
type_set types;
if ((type_g != policy_types::kernel && version >= 13)) {
u32 flavor;
extensible_bitmap roles;
}
};
using roles = symbols_list<role_s>;
struct type_s {
u32 length;
u32 value;
if ((boundary_feature && (type_g != policy_types::kernel && version >= 10)) || !boundary_feature)
u32 primary;
if (boundary_feature) {
u32 properties;
u32 bounds;
}
if (!boundary_feature && (type_g != policy_types::kernel))
u32 flavor;
if (!boundary_feature && (type_g != policy_types::kernel && version >= 8))
u32 flags;
if (type_g != policy_types::kernel)
extensible_bitmap types;
char key[length];
};
struct types_s {
u32 primary_names_count;
type_primary_names_count = primary_names_count;
list<type_s> [[inline]];
};
struct user_s {
u32 length;
u32 value;
if (boundary_feature)
u32 bounds;
char key[length];
if (type_g == policy_types::kernel)
extensible_bitmap roles;
else
role_set roles;
if ((type_g == policy_types::kernel && version >= 19) || (type_g == policy_types::module && version >= 5 && version < 6) || (type_g == policy_types::base && version >= 5 && version < 6)) {
mls_range exp_range;
mls_level exp_dftlevel;
}
if ((type_g == policy_types::module || type_g == policy_types::base) && (version >= 6)) {
mls_semantic_range range;
mls_semantic_range dfltlevel;
}
};
using users = symbols_list<user_s>;
struct bool_ { // conditional boolean
u32 value;
u32 state;
u32 length;
char key[length];
if ((type_g != policy_types::kernel && version >= 14))
u32 flags;
};
using bools = symbols_list<bool_>;
struct level {
u32 length;
u32 isalias;
char key[length];
mls_level level;
};
using sensitivity_levels = symbols_list<level>;
struct category {
u32 length;
u32 value;
u32 isalias;
char key[length];
};
using categories = symbols_list<category>;
struct symbols {
commons commons;
classes classes;
roles roles;
types_s types;
users users;
if (symbols_count >= 6)
bools bools;
if (symbols_count >= 7)
sensitivity_levels levels;
if (symbols_count >= 8)
categories cats;
};
struct module_header {
u32 name_length;
std::assert(name_length >= 1, "Invalid 'name_length' in module header.");
char name[name_length];
u32 version_length;
std::assert(version_length >= 1, "Invalid 'version_length' in module header.");
char version[version_length];
};
struct access_vector_old {
u32 total;
u32 source_type;
u32 target_type;
u32 target_class;
u32 value;
u32 data[8];
};
struct access_vector {
u16 source_type;
u16 target_type;
u16 target_class;
u16 specified;
if ((specified & 0x700) != 0) {
u8 xperms_specified;
u8 xperms_drivers;
u32 xperms_perms[8];
}
else
u32 data;
};
struct avrule_item {
u32 tclass;
u32 data;
};
struct avrule {
u32 specified;
u32 flags;
type_set stypes;
type_set ttypes;
u32 length;
avrule_item avrule_item[length];
if ((specified & (0x0100 | 0x0200 | 0x0400 | 0x0800)) != 0) {
u8 xperms_specified;
u8 xperms_driver;
list<u32> perms[[inline]];
}
};
struct avrule_list {
u32 length;
avrule avrule[length];
};
struct conditional_node_item {
u32 expr_type;
u32 boolean;
};
struct access_vector_table_s {
if (version < 20)
list<access_vector_old> access_vector_table;
else
list<access_vector> access_vector_table;
} [[inline]];
using cond_av_list = access_vector_table_s;
struct conditional_node {
u32 current_state;
u32 length;
conditional_node_item item[length];
if (type_g == policy_types::kernel) {
cond_av_list true_list;
cond_av_list false_list;
} else {
avrule_list avtrue_list;
avrule_list avfalse_list;
if (version >= 14)
u32 flags;
}
};
struct conditional_list {
u32 length;
conditional_node conditional_node[length];
};
struct role_trans_item {
u32 role;
u32 type_;
u32 new_role;
if (type_g == policy_types::kernel && version >= 26)
u32 tclass;
};
using role_trans = list<role_trans_item>;
struct role_allow_item {
u32 role;
u32 new_role;
};
using role_allow = list<role_allow_item>;
struct filename_trans_item_old {
u32 length;
char name[length];
u32 stype;
u32 ttype;
u32 tclass;
u32 otype;
};
struct filename_trans_item_item {
extensible_bitmap stypes;
u32 otype;
};
struct filename_trans_item {
u32 length;
char name[length];
u32 ttype;
u32 tclass;
list<filename_trans_item_item> types [[inline]];
};
struct role_trans_rule_item {
role_set roles;
role_set types;
if (version >= 12)
extensible_bitmap classes;
u32 new_role;
};
using role_trans_rule = list<role_trans_rule_item>;
struct role_allow_rule_item {
role_set roles;
role_set new_roles;
};
using role_allow_rule = list<role_allow_rule_item>;
struct scope_s {
u32 length;
char key[length];
u32 scope;
u32 decl_ids_len;
std::assert(decl_ids_len >= 1, "Invalid 'decl_ids_len'");
u32 decl_id[decl_ids_len];
};
struct scope_index {
extensible_bitmap scope[symbols_count];
u32 class_perms_len;
extensible_bitmap class_perms_map[class_perms_len];
};
using scope_list = list<scope_s>;
struct filename_trans_rule_item {
u32 length;
char name[length];
type_set stypes;
type_set ttypes;
u32 tclass;
u32 otype;
if (version >= 21)
u32 flags;
};
using filename_trans_rule = list<filename_trans_rule_item>;
struct range_trans_rule_item {
type_set stypes;
type_set ttypes;
extensible_bitmap tclasses;
mls_semantic_range trange;
};
using range_trans_rule = list<range_trans_rule_item>;
struct avrule_decl {
u32 decl_id;
u32 enabled;
conditional_list cond_list;
avrule_list avrules;
role_trans_rule role_tr_rules;
role_allow_rule role_allow_rules;
if (version >= 11)
filename_trans_rule filename_trans_rules;
if (version >= 6)
range_trans_rule range_tr_rules;
scope_index required;
scope_index declared;
symbols symbols;
};
struct avrule_block_item {
u32 num_decls;
if (num_decls > 0)
avrule_decl avrule_decl[num_decls];
};
using avrule_block = list<avrule_block_item>;
struct initial_sid {
u32 sid0;
context_s context0;
};
struct filesystem {
u32 length;
char key[length];
context_s context0;
context_s context1;
};
struct port {
u32 protocol;
u32 low_port;
u32 high_port;
context_s context;
};
struct node {
u32 addr;
u32 mask;
context_s context;
};
struct fsuse {
u32 behavior;
u32 length;
char name[length];
context_s context;
};
struct node6 {
u32 addr[4];
u32 mask[4];
context_s context;
};
struct ibpkey {
u32 low_pkey;
u32 high_pkey;
context_s context;
};
struct ibpendport {
u32 length;
u32 port;
char dev_name[length];
context_s context;
};
struct ocontext_selinux {
if (object_contexts_count < 1) break;
list<initial_sid> initial_sids;
if (object_contexts_count < 2) break;
list<filesystem> filesystems;
if (object_contexts_count < 3) break;
list<port> ports;
if (object_contexts_count < 4) break;
list<filesystem> network_interfaces; // same type
if (object_contexts_count < 5) break;
list<node> nodes;
if (object_contexts_count < 6) break;
list<fsuse> fsuses;
if (object_contexts_count < 7) break;
list<node6> nodes6;
if (object_contexts_count < 8) break;
list<ibpkey> ibpkeys;
if (object_contexts_count < 9) break;
list<ibpendport> ibpendports;
};
struct xen_isid {
u32 sid0;
context_s context0;
};
struct xen_pirq {
u32 pirq;
context_s context0;
};
struct xen_ioport {
u32 low_port;
u32 high_port;
context_s context0;
};
struct xen_iomem {
if (version >= 30) {
u64 low_iomem;
u64 high_iomem;
} else {
u32 low_iomem;
u32 high_iomem;
}
context_s context;
};
struct xen_pcidevice {
u32 device;
context_s context;
};
struct xen_devicetree {
u32 length;
char name[length];
context_s context;
};
struct ocontext_xen {
if (object_contexts_count < 1) break;
list<xen_isid> xen_isids;
if (object_contexts_count < 2) break;
list<xen_pirq> xen_pirqs;
if (object_contexts_count < 3) break;
list<xen_ioport> xen_ioports;
if (object_contexts_count < 4) break;
list<xen_iomem> xen_iomems;
if (object_contexts_count < 5) break;
list<xen_pcidevice> xen_pcidevices;
if (object_contexts_count < 6) break;
list<xen_devicetree> xen_devicetrees;
if (object_contexts_count < 7) break;
};
struct genfs2_item {
u32 length;
char name[length];
u32 sclass;
context_s context0;
};
struct genfs_item {
u32 length;
char fstype[length];
list<genfs2_item> [[inline]];
};
struct range_item {
u32 source_type;
u32 target_type;
if (type_g == policy_types::kernel && version >= 21)
u32 target_class;
mls_range range_tr;
};
struct Header {
magics magic;
std::assert(magic == magics::kernel || magic == magics::module , "Unexpected magic");
u32 policydb_str_len;
char policydb_str[policydb_str_len];
std::assert(policydb_str == "SE Linux" || policydb_str == "SE Linux Module" || policydb_str == "XenFlask", "Unexpected signature");
if (policydb_str == "XenFlask")
target = targets::xen;
else
target = targets::selinux;
std::assert((magic == magics::kernel && (policydb_str == "SE Linux" || policydb_str == "XenFlask"))
|| (magic == magics::module && policydb_str == "SE Linux Module"), "Non matching magic and signature");
if (magic == magics::module)
u32 policy_subtype;
if (magic == magics::kernel)
type_g = policy_types::kernel;
else
if (policy_subtype == policy_types::module)
type_g = policy_types::module;
else
type_g = policy_types::base;
u32 __policyvers;
version = __policyvers;
boundary_feature = (type_g == policy_types::kernel && version >= 24) || (type_g != policy_types::kernel && version >= 9);
std::assert((magic == magics::kernel && 15 <= version && version <= 33) || (magic != magics::kernel && 4 <= version && version <= 21), "Non matching type_g != and type");
u32 config;
u32 symbols_count_;
symbols_count = symbols_count_;
std::assert(0 <= symbols_count && symbols_count <= 9, "Invalid 'symbols_count' value.");
u32 object_contexts_count_;
object_contexts_count = object_contexts_count_;
std::assert(0 <= object_contexts_count && object_contexts_count <= 9, "Invalid 'object_contexts_count' value.");
if (magic == magics::module)
module_header module_header;
if ((type_g == policy_types::kernel && version >= 22) || (version >= 7))
extensible_bitmap policycaps;
if (type_g == policy_types::kernel && version >= 23)
extensible_bitmap permissive_map;
symbols symbols;
if (type_g == policy_types::kernel) {
access_vector_table_s access_vector_table;
}
if (type_g == policy_types::kernel && version >= 16)
conditional_list conditional_list;
if (type_g == policy_types::kernel) {
role_trans role_trans;
role_allow role_allow;
if (version >= 25) {
if (version < 33)
list<filename_trans_item_old> filename_trans;
else
list<filename_trans_item> filename_trans;
}
} else {
list<avrule_block_item> avrule_block;
list<scope_s> scope_list[symbols_count];
}
if (target == targets::selinux)
ocontext_selinux ocontext_selinux;
else
ocontext_xen ocontext_xen;
list<genfs_item> genfs;
if (((type_g == policy_types::kernel) && (version >= 19)) || ((type_g == policy_types::base) && (version == 5)))
list<range_item> range;
if (type_g == policy_types::kernel)
extensible_bitmap type_attr_map[type_primary_names_count];
};
Header header @ 0;