mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-28 07:47:02 -05:00
725 lines
16 KiB
Rust
725 lines
16 KiB
Rust
#pragma description SE Linux modules
|
|
#pragma author Ange Albertini
|
|
|
|
import std.sys;
|
|
#pragma pattern_limit 13107200
|
|
#pragma array_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,
|
|
};
|
|
|
|
bitfield CONFIG {
|
|
DENY_UNKNOWN: 1;
|
|
MLS: 1;
|
|
REJECT_UNKNOWN: 1;
|
|
ALLOW_UNKNOWN: 1;
|
|
padding: 4 + 3 * 8;
|
|
};
|
|
|
|
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");
|
|
CONFIG 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;
|