| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 
|---|
| 2 | /* | 
|---|
| 3 | * A policy database (policydb) specifies the | 
|---|
| 4 | * configuration data for the security policy. | 
|---|
| 5 | * | 
|---|
| 6 | * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> | 
|---|
| 7 | */ | 
|---|
| 8 |  | 
|---|
| 9 | /* | 
|---|
| 10 | * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | 
|---|
| 11 | *          Support for enhanced MLS infrastructure. | 
|---|
| 12 | *          Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 
|---|
| 13 | * | 
|---|
| 14 | * Updated: Frank Mayer <mayerf@tresys.com> and | 
|---|
| 15 | *          Karl MacMillan <kmacmillan@tresys.com> | 
|---|
| 16 | *          Added conditional policy language extensions | 
|---|
| 17 | *          Copyright (C) 2003-2004 Tresys Technology, LLC | 
|---|
| 18 | */ | 
|---|
| 19 |  | 
|---|
| 20 | #ifndef _SS_POLICYDB_H_ | 
|---|
| 21 | #define _SS_POLICYDB_H_ | 
|---|
| 22 |  | 
|---|
| 23 | #include "symtab.h" | 
|---|
| 24 | #include "avtab.h" | 
|---|
| 25 | #include "sidtab.h" | 
|---|
| 26 | #include "ebitmap.h" | 
|---|
| 27 | #include "mls_types.h" | 
|---|
| 28 | #include "context.h" | 
|---|
| 29 | #include "constraint.h" | 
|---|
| 30 |  | 
|---|
| 31 | /* | 
|---|
| 32 | * A datum type is defined for each kind of symbol | 
|---|
| 33 | * in the configuration data:  individual permissions, | 
|---|
| 34 | * common prefixes for access vectors, classes, | 
|---|
| 35 | * users, roles, types, sensitivities, categories, etc. | 
|---|
| 36 | */ | 
|---|
| 37 |  | 
|---|
| 38 | /* Permission attributes */ | 
|---|
| 39 | struct perm_datum { | 
|---|
| 40 | u32 value; /* permission bit + 1 */ | 
|---|
| 41 | }; | 
|---|
| 42 |  | 
|---|
| 43 | /* Attributes of a common prefix for access vectors */ | 
|---|
| 44 | struct common_datum { | 
|---|
| 45 | u32 value; /* internal common value */ | 
|---|
| 46 | struct symtab permissions; /* common permissions */ | 
|---|
| 47 | }; | 
|---|
| 48 |  | 
|---|
| 49 | /* Class attributes */ | 
|---|
| 50 | struct class_datum { | 
|---|
| 51 | u32 value; /* class value */ | 
|---|
| 52 | char *comkey; /* common name */ | 
|---|
| 53 | struct common_datum *comdatum; /* common datum */ | 
|---|
| 54 | struct symtab permissions; /* class-specific permission symbol table */ | 
|---|
| 55 | struct constraint_node *constraints; /* constraints on class perms */ | 
|---|
| 56 | struct constraint_node *validatetrans; /* special transition rules */ | 
|---|
| 57 | /* Options how a new object user, role, and type should be decided */ | 
|---|
| 58 | #define DEFAULT_SOURCE 1 | 
|---|
| 59 | #define DEFAULT_TARGET 2 | 
|---|
| 60 | char default_user; | 
|---|
| 61 | char default_role; | 
|---|
| 62 | char default_type; | 
|---|
| 63 | /* Options how a new object range should be decided */ | 
|---|
| 64 | #define DEFAULT_SOURCE_LOW	1 | 
|---|
| 65 | #define DEFAULT_SOURCE_HIGH	2 | 
|---|
| 66 | #define DEFAULT_SOURCE_LOW_HIGH 3 | 
|---|
| 67 | #define DEFAULT_TARGET_LOW	4 | 
|---|
| 68 | #define DEFAULT_TARGET_HIGH	5 | 
|---|
| 69 | #define DEFAULT_TARGET_LOW_HIGH 6 | 
|---|
| 70 | #define DEFAULT_GLBLUB		7 | 
|---|
| 71 | char default_range; | 
|---|
| 72 | }; | 
|---|
| 73 |  | 
|---|
| 74 | /* Role attributes */ | 
|---|
| 75 | struct role_datum { | 
|---|
| 76 | u32 value; /* internal role value */ | 
|---|
| 77 | u32 bounds; /* boundary of role */ | 
|---|
| 78 | struct ebitmap dominates; /* set of roles dominated by this role */ | 
|---|
| 79 | struct ebitmap types; /* set of authorized types for role */ | 
|---|
| 80 | }; | 
|---|
| 81 |  | 
|---|
| 82 | struct role_trans_key { | 
|---|
| 83 | u32 role; /* current role */ | 
|---|
| 84 | u32 type; /* program executable type, or new object type */ | 
|---|
| 85 | u32 tclass; /* process class, or new object class */ | 
|---|
| 86 | }; | 
|---|
| 87 |  | 
|---|
| 88 | struct role_trans_datum { | 
|---|
| 89 | u32 new_role; /* new role */ | 
|---|
| 90 | }; | 
|---|
| 91 |  | 
|---|
| 92 | struct filename_trans_key { | 
|---|
| 93 | u32 ttype; /* parent dir context */ | 
|---|
| 94 | u16 tclass; /* class of new object */ | 
|---|
| 95 | const char *name; /* last path component */ | 
|---|
| 96 | }; | 
|---|
| 97 |  | 
|---|
| 98 | struct filename_trans_datum { | 
|---|
| 99 | struct ebitmap stypes; /* bitmap of source types for this otype */ | 
|---|
| 100 | u32 otype; /* resulting type of new object */ | 
|---|
| 101 | struct filename_trans_datum *next; /* record for next otype*/ | 
|---|
| 102 | }; | 
|---|
| 103 |  | 
|---|
| 104 | struct role_allow { | 
|---|
| 105 | u32 role; /* current role */ | 
|---|
| 106 | u32 new_role; /* new role */ | 
|---|
| 107 | struct role_allow *next; | 
|---|
| 108 | }; | 
|---|
| 109 |  | 
|---|
| 110 | /* Type attributes */ | 
|---|
| 111 | struct type_datum { | 
|---|
| 112 | u32 value; /* internal type value */ | 
|---|
| 113 | u32 bounds; /* boundary of type */ | 
|---|
| 114 | unsigned char primary; /* primary name? */ | 
|---|
| 115 | unsigned char attribute; /* attribute ?*/ | 
|---|
| 116 | }; | 
|---|
| 117 |  | 
|---|
| 118 | /* User attributes */ | 
|---|
| 119 | struct user_datum { | 
|---|
| 120 | u32 value; /* internal user value */ | 
|---|
| 121 | u32 bounds; /* bounds of user */ | 
|---|
| 122 | struct ebitmap roles; /* set of authorized roles for user */ | 
|---|
| 123 | struct mls_range range; /* MLS range (min - max) for user */ | 
|---|
| 124 | struct mls_level dfltlevel; /* default login MLS level for user */ | 
|---|
| 125 | }; | 
|---|
| 126 |  | 
|---|
| 127 | /* Sensitivity attributes */ | 
|---|
| 128 | struct level_datum { | 
|---|
| 129 | struct mls_level level; /* sensitivity and associated categories */ | 
|---|
| 130 | unsigned char isalias; /* is this sensitivity an alias for another? */ | 
|---|
| 131 | }; | 
|---|
| 132 |  | 
|---|
| 133 | /* Category attributes */ | 
|---|
| 134 | struct cat_datum { | 
|---|
| 135 | u32 value; /* internal category bit + 1 */ | 
|---|
| 136 | unsigned char isalias; /* is this category an alias for another? */ | 
|---|
| 137 | }; | 
|---|
| 138 |  | 
|---|
| 139 | struct range_trans { | 
|---|
| 140 | u32 source_type; | 
|---|
| 141 | u32 target_type; | 
|---|
| 142 | u32 target_class; | 
|---|
| 143 | }; | 
|---|
| 144 |  | 
|---|
| 145 | /* Boolean data type */ | 
|---|
| 146 | struct cond_bool_datum { | 
|---|
| 147 | u32 value; /* internal type value */ | 
|---|
| 148 | int state; | 
|---|
| 149 | }; | 
|---|
| 150 |  | 
|---|
| 151 | struct cond_node; | 
|---|
| 152 |  | 
|---|
| 153 | /* | 
|---|
| 154 | * type set preserves data needed to determine constraint info from | 
|---|
| 155 | * policy source. This is not used by the kernel policy but allows | 
|---|
| 156 | * utilities such as audit2allow to determine constraint denials. | 
|---|
| 157 | */ | 
|---|
| 158 | struct type_set { | 
|---|
| 159 | struct ebitmap types; | 
|---|
| 160 | struct ebitmap negset; | 
|---|
| 161 | u32 flags; | 
|---|
| 162 | }; | 
|---|
| 163 |  | 
|---|
| 164 | /* | 
|---|
| 165 | * The configuration data includes security contexts for | 
|---|
| 166 | * initial SIDs, unlabeled file systems, TCP and UDP port numbers, | 
|---|
| 167 | * network interfaces, and nodes.  This structure stores the | 
|---|
| 168 | * relevant data for one such entry.  Entries of the same kind | 
|---|
| 169 | * (e.g. all initial SIDs) are linked together into a list. | 
|---|
| 170 | */ | 
|---|
| 171 | struct ocontext { | 
|---|
| 172 | union { | 
|---|
| 173 | char *name; /* name of initial SID, fs, netif, fstype, path */ | 
|---|
| 174 | struct { | 
|---|
| 175 | u8 protocol; | 
|---|
| 176 | u16 low_port; | 
|---|
| 177 | u16 high_port; | 
|---|
| 178 | } port; /* TCP or UDP port information */ | 
|---|
| 179 | struct { | 
|---|
| 180 | u32 addr; | 
|---|
| 181 | u32 mask; | 
|---|
| 182 | } node; /* node information */ | 
|---|
| 183 | struct { | 
|---|
| 184 | u32 addr[4]; | 
|---|
| 185 | u32 mask[4]; | 
|---|
| 186 | } node6; /* IPv6 node information */ | 
|---|
| 187 | struct { | 
|---|
| 188 | u64 subnet_prefix; | 
|---|
| 189 | u16 low_pkey; | 
|---|
| 190 | u16 high_pkey; | 
|---|
| 191 | } ibpkey; | 
|---|
| 192 | struct { | 
|---|
| 193 | char *dev_name; | 
|---|
| 194 | u8 port; | 
|---|
| 195 | } ibendport; | 
|---|
| 196 | } u; | 
|---|
| 197 | union { | 
|---|
| 198 | u32 sclass; /* security class for genfs */ | 
|---|
| 199 | u32 behavior; /* labeling behavior for fs_use */ | 
|---|
| 200 | } v; | 
|---|
| 201 | struct context context[2]; /* security context(s) */ | 
|---|
| 202 | u32 sid[2]; /* SID(s) */ | 
|---|
| 203 | struct ocontext *next; | 
|---|
| 204 | }; | 
|---|
| 205 |  | 
|---|
| 206 | struct genfs { | 
|---|
| 207 | char *fstype; | 
|---|
| 208 | struct ocontext *head; | 
|---|
| 209 | struct genfs *next; | 
|---|
| 210 | }; | 
|---|
| 211 |  | 
|---|
| 212 | /* symbol table array indices */ | 
|---|
| 213 | #define SYM_COMMONS 0 | 
|---|
| 214 | #define SYM_CLASSES 1 | 
|---|
| 215 | #define SYM_ROLES   2 | 
|---|
| 216 | #define SYM_TYPES   3 | 
|---|
| 217 | #define SYM_USERS   4 | 
|---|
| 218 | #define SYM_BOOLS   5 | 
|---|
| 219 | #define SYM_LEVELS  6 | 
|---|
| 220 | #define SYM_CATS    7 | 
|---|
| 221 | #define SYM_NUM	    8 | 
|---|
| 222 |  | 
|---|
| 223 | /* object context array indices */ | 
|---|
| 224 | #define OCON_ISID      0 /* initial SIDs */ | 
|---|
| 225 | #define OCON_FS	       1 /* unlabeled file systems (deprecated) */ | 
|---|
| 226 | #define OCON_PORT      2 /* TCP and UDP port numbers */ | 
|---|
| 227 | #define OCON_NETIF     3 /* network interfaces */ | 
|---|
| 228 | #define OCON_NODE      4 /* nodes */ | 
|---|
| 229 | #define OCON_FSUSE     5 /* fs_use */ | 
|---|
| 230 | #define OCON_NODE6     6 /* IPv6 nodes */ | 
|---|
| 231 | #define OCON_IBPKEY    7 /* Infiniband PKeys */ | 
|---|
| 232 | #define OCON_IBENDPORT 8 /* Infiniband end ports */ | 
|---|
| 233 | #define OCON_NUM       9 | 
|---|
| 234 |  | 
|---|
| 235 | /* The policy database */ | 
|---|
| 236 | struct policydb { | 
|---|
| 237 | int mls_enabled; | 
|---|
| 238 |  | 
|---|
| 239 | /* symbol tables */ | 
|---|
| 240 | struct symtab symtab[SYM_NUM]; | 
|---|
| 241 | #define p_commons symtab[SYM_COMMONS] | 
|---|
| 242 | #define p_classes symtab[SYM_CLASSES] | 
|---|
| 243 | #define p_roles	  symtab[SYM_ROLES] | 
|---|
| 244 | #define p_types	  symtab[SYM_TYPES] | 
|---|
| 245 | #define p_users	  symtab[SYM_USERS] | 
|---|
| 246 | #define p_bools	  symtab[SYM_BOOLS] | 
|---|
| 247 | #define p_levels  symtab[SYM_LEVELS] | 
|---|
| 248 | #define p_cats	  symtab[SYM_CATS] | 
|---|
| 249 |  | 
|---|
| 250 | /* symbol names indexed by (value - 1) */ | 
|---|
| 251 | char **sym_val_to_name[SYM_NUM]; | 
|---|
| 252 |  | 
|---|
| 253 | /* class, role, and user attributes indexed by (value - 1) */ | 
|---|
| 254 | struct class_datum **class_val_to_struct; | 
|---|
| 255 | struct role_datum **role_val_to_struct; | 
|---|
| 256 | struct user_datum **user_val_to_struct; | 
|---|
| 257 | struct type_datum **type_val_to_struct; | 
|---|
| 258 |  | 
|---|
| 259 | /* type enforcement access vectors and transitions */ | 
|---|
| 260 | struct avtab te_avtab; | 
|---|
| 261 |  | 
|---|
| 262 | /* role transitions */ | 
|---|
| 263 | struct hashtab role_tr; | 
|---|
| 264 |  | 
|---|
| 265 | /* file transitions with the last path component */ | 
|---|
| 266 | /* quickly exclude lookups when parent ttype has no rules */ | 
|---|
| 267 | struct ebitmap filename_trans_ttypes; | 
|---|
| 268 | /* actual set of filename_trans rules */ | 
|---|
| 269 | struct hashtab filename_trans; | 
|---|
| 270 | /* only used if policyvers < POLICYDB_VERSION_COMP_FTRANS */ | 
|---|
| 271 | u32 compat_filename_trans_count; | 
|---|
| 272 |  | 
|---|
| 273 | /* bools indexed by (value - 1) */ | 
|---|
| 274 | struct cond_bool_datum **bool_val_to_struct; | 
|---|
| 275 | /* type enforcement conditional access vectors and transitions */ | 
|---|
| 276 | struct avtab te_cond_avtab; | 
|---|
| 277 | /* array indexing te_cond_avtab by conditional */ | 
|---|
| 278 | struct cond_node *cond_list; | 
|---|
| 279 | u32 cond_list_len; | 
|---|
| 280 |  | 
|---|
| 281 | /* role allows */ | 
|---|
| 282 | struct role_allow *role_allow; | 
|---|
| 283 |  | 
|---|
| 284 | /* security contexts of initial SIDs, unlabeled file systems, | 
|---|
| 285 | TCP or UDP port numbers, network interfaces and nodes */ | 
|---|
| 286 | struct ocontext *ocontexts[OCON_NUM]; | 
|---|
| 287 |  | 
|---|
| 288 | /* security contexts for files in filesystems that cannot support | 
|---|
| 289 | a persistent label mapping or use another | 
|---|
| 290 | fixed labeling behavior. */ | 
|---|
| 291 | struct genfs *genfs; | 
|---|
| 292 |  | 
|---|
| 293 | /* range transitions table (range_trans_key -> mls_range) */ | 
|---|
| 294 | struct hashtab range_tr; | 
|---|
| 295 |  | 
|---|
| 296 | /* type -> attribute reverse mapping */ | 
|---|
| 297 | struct ebitmap *type_attr_map_array; | 
|---|
| 298 |  | 
|---|
| 299 | struct ebitmap policycaps; | 
|---|
| 300 |  | 
|---|
| 301 | struct ebitmap permissive_map; | 
|---|
| 302 |  | 
|---|
| 303 | struct ebitmap neveraudit_map; | 
|---|
| 304 |  | 
|---|
| 305 | /* length of this policy when it was loaded */ | 
|---|
| 306 | size_t len; | 
|---|
| 307 |  | 
|---|
| 308 | unsigned int policyvers; | 
|---|
| 309 |  | 
|---|
| 310 | unsigned int reject_unknown : 1; | 
|---|
| 311 | unsigned int allow_unknown : 1; | 
|---|
| 312 |  | 
|---|
| 313 | u16 process_class; | 
|---|
| 314 | u32 process_trans_perms; | 
|---|
| 315 | } __randomize_layout; | 
|---|
| 316 |  | 
|---|
| 317 | struct policy_file { | 
|---|
| 318 | char *data; | 
|---|
| 319 | size_t len; | 
|---|
| 320 | }; | 
|---|
| 321 |  | 
|---|
| 322 | extern void policydb_destroy(struct policydb *p); | 
|---|
| 323 | extern int policydb_load_isids(struct policydb *p, struct sidtab *s); | 
|---|
| 324 | extern int policydb_context_isvalid(struct policydb *p, struct context *c); | 
|---|
| 325 | extern int policydb_class_isvalid(struct policydb *p, unsigned int class); | 
|---|
| 326 | extern int policydb_type_isvalid(struct policydb *p, unsigned int type); | 
|---|
| 327 | extern int policydb_role_isvalid(struct policydb *p, unsigned int role); | 
|---|
| 328 | extern int policydb_read(struct policydb *p, struct policy_file *fp); | 
|---|
| 329 | extern int policydb_write(struct policydb *p, struct policy_file *fp); | 
|---|
| 330 |  | 
|---|
| 331 | extern struct filename_trans_datum * | 
|---|
| 332 | policydb_filenametr_search(struct policydb *p, struct filename_trans_key *key); | 
|---|
| 333 |  | 
|---|
| 334 | extern struct mls_range *policydb_rangetr_search(struct policydb *p, | 
|---|
| 335 | struct range_trans *key); | 
|---|
| 336 |  | 
|---|
| 337 | extern struct role_trans_datum * | 
|---|
| 338 | policydb_roletr_search(struct policydb *p, struct role_trans_key *key); | 
|---|
| 339 |  | 
|---|
| 340 | #define POLICYDB_CONFIG_MLS 1 | 
|---|
| 341 |  | 
|---|
| 342 | /* the config flags related to unknown classes/perms are bits 2 and 3 */ | 
|---|
| 343 | #define REJECT_UNKNOWN 0x00000002 | 
|---|
| 344 | #define ALLOW_UNKNOWN  0x00000004 | 
|---|
| 345 |  | 
|---|
| 346 | #define OBJECT_R     "object_r" | 
|---|
| 347 | #define OBJECT_R_VAL 1 | 
|---|
| 348 |  | 
|---|
| 349 | #define POLICYDB_MAGIC	SELINUX_MAGIC | 
|---|
| 350 | #define POLICYDB_STRING "SE Linux" | 
|---|
| 351 |  | 
|---|
| 352 | struct policy_data { | 
|---|
| 353 | struct policydb *p; | 
|---|
| 354 | struct policy_file *fp; | 
|---|
| 355 | }; | 
|---|
| 356 |  | 
|---|
| 357 | static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) | 
|---|
| 358 | { | 
|---|
| 359 | if (bytes > fp->len) | 
|---|
| 360 | return -EINVAL; | 
|---|
| 361 |  | 
|---|
| 362 | memcpy(to: buf, from: fp->data, len: bytes); | 
|---|
| 363 | fp->data += bytes; | 
|---|
| 364 | fp->len -= bytes; | 
|---|
| 365 | return 0; | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|
| 368 | static inline int put_entry(const void *buf, size_t bytes, size_t num, | 
|---|
| 369 | struct policy_file *fp) | 
|---|
| 370 | { | 
|---|
| 371 | size_t len; | 
|---|
| 372 |  | 
|---|
| 373 | if (unlikely(check_mul_overflow(bytes, num, &len))) | 
|---|
| 374 | return -EINVAL; | 
|---|
| 375 |  | 
|---|
| 376 | if (len > fp->len) | 
|---|
| 377 | return -EINVAL; | 
|---|
| 378 | memcpy(to: fp->data, from: buf, len); | 
|---|
| 379 | fp->data += len; | 
|---|
| 380 | fp->len -= len; | 
|---|
| 381 |  | 
|---|
| 382 | return 0; | 
|---|
| 383 | } | 
|---|
| 384 |  | 
|---|
| 385 | static inline char *sym_name(struct policydb *p, unsigned int sym_num, | 
|---|
| 386 | unsigned int element_nr) | 
|---|
| 387 | { | 
|---|
| 388 | return p->sym_val_to_name[sym_num][element_nr]; | 
|---|
| 389 | } | 
|---|
| 390 |  | 
|---|
| 391 | extern int str_read(char **strp, gfp_t flags, struct policy_file *fp, u32 len); | 
|---|
| 392 |  | 
|---|
| 393 | extern u16 string_to_security_class(struct policydb *p, const char *name); | 
|---|
| 394 | extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); | 
|---|
| 395 |  | 
|---|
| 396 | #endif /* _SS_POLICYDB_H_ */ | 
|---|
| 397 |  | 
|---|