diff options
| -rw-r--r-- | include/linux/audit.h | 29 | ||||
| -rw-r--r-- | include/linux/selinux.h | 72 | ||||
| -rw-r--r-- | kernel/audit.h | 25 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 8 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 45 |
5 files changed, 71 insertions, 108 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 2af9ec025015..04869c96016b 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -353,6 +353,33 @@ struct netlink_skb_parms; | |||
| 353 | struct linux_binprm; | 353 | struct linux_binprm; |
| 354 | struct mq_attr; | 354 | struct mq_attr; |
| 355 | struct mqstat; | 355 | struct mqstat; |
| 356 | struct audit_watch; | ||
| 357 | struct audit_tree; | ||
| 358 | |||
| 359 | struct audit_krule { | ||
| 360 | int vers_ops; | ||
| 361 | u32 flags; | ||
| 362 | u32 listnr; | ||
| 363 | u32 action; | ||
| 364 | u32 mask[AUDIT_BITMASK_SIZE]; | ||
| 365 | u32 buflen; /* for data alloc on list rules */ | ||
| 366 | u32 field_count; | ||
| 367 | char *filterkey; /* ties events to rules */ | ||
| 368 | struct audit_field *fields; | ||
| 369 | struct audit_field *arch_f; /* quick access to arch field */ | ||
| 370 | struct audit_field *inode_f; /* quick access to an inode field */ | ||
| 371 | struct audit_watch *watch; /* associated watch */ | ||
| 372 | struct audit_tree *tree; /* associated watched tree */ | ||
| 373 | struct list_head rlist; /* entry in audit_{watch,tree}.rules list */ | ||
| 374 | }; | ||
| 375 | |||
| 376 | struct audit_field { | ||
| 377 | u32 type; | ||
| 378 | u32 val; | ||
| 379 | u32 op; | ||
| 380 | char *se_str; | ||
| 381 | void *se_rule; | ||
| 382 | }; | ||
| 356 | 383 | ||
| 357 | #define AUDITSC_INVALID 0 | 384 | #define AUDITSC_INVALID 0 |
| 358 | #define AUDITSC_SUCCESS 1 | 385 | #define AUDITSC_SUCCESS 1 |
| @@ -536,6 +563,8 @@ extern void audit_log_d_path(struct audit_buffer *ab, | |||
| 536 | const char *prefix, | 563 | const char *prefix, |
| 537 | struct path *path); | 564 | struct path *path); |
| 538 | extern void audit_log_lost(const char *message); | 565 | extern void audit_log_lost(const char *message); |
| 566 | extern int audit_update_lsm_rules(void); | ||
| 567 | |||
| 539 | /* Private API (for audit.c only) */ | 568 | /* Private API (for audit.c only) */ |
| 540 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 569 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
| 541 | extern int audit_filter_type(int type); | 570 | extern int audit_filter_type(int type); |
diff --git a/include/linux/selinux.h b/include/linux/selinux.h index 24b0af1c4cac..20f965d4b041 100644 --- a/include/linux/selinux.h +++ b/include/linux/selinux.h | |||
| @@ -21,54 +21,6 @@ struct kern_ipc_perm; | |||
| 21 | #ifdef CONFIG_SECURITY_SELINUX | 21 | #ifdef CONFIG_SECURITY_SELINUX |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * selinux_audit_rule_init - alloc/init an selinux audit rule structure. | ||
| 25 | * @field: the field this rule refers to | ||
| 26 | * @op: the operater the rule uses | ||
| 27 | * @rulestr: the text "target" of the rule | ||
| 28 | * @rule: pointer to the new rule structure returned via this | ||
| 29 | * | ||
| 30 | * Returns 0 if successful, -errno if not. On success, the rule structure | ||
| 31 | * will be allocated internally. The caller must free this structure with | ||
| 32 | * selinux_audit_rule_free() after use. | ||
| 33 | */ | ||
| 34 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
| 35 | struct selinux_audit_rule **rule); | ||
| 36 | |||
| 37 | /** | ||
| 38 | * selinux_audit_rule_free - free an selinux audit rule structure. | ||
| 39 | * @rule: pointer to the audit rule to be freed | ||
| 40 | * | ||
| 41 | * This will free all memory associated with the given rule. | ||
| 42 | * If @rule is NULL, no operation is performed. | ||
| 43 | */ | ||
| 44 | void selinux_audit_rule_free(struct selinux_audit_rule *rule); | ||
| 45 | |||
| 46 | /** | ||
| 47 | * selinux_audit_rule_match - determine if a context ID matches a rule. | ||
| 48 | * @sid: the context ID to check | ||
| 49 | * @field: the field this rule refers to | ||
| 50 | * @op: the operater the rule uses | ||
| 51 | * @rule: pointer to the audit rule to check against | ||
| 52 | * @actx: the audit context (can be NULL) associated with the check | ||
| 53 | * | ||
| 54 | * Returns 1 if the context id matches the rule, 0 if it does not, and | ||
| 55 | * -errno on failure. | ||
| 56 | */ | ||
| 57 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, | ||
| 58 | struct selinux_audit_rule *rule, | ||
| 59 | struct audit_context *actx); | ||
| 60 | |||
| 61 | /** | ||
| 62 | * selinux_audit_set_callback - set the callback for policy reloads. | ||
| 63 | * @callback: the function to call when the policy is reloaded | ||
| 64 | * | ||
| 65 | * This sets the function callback function that will update the rules | ||
| 66 | * upon policy reloads. This callback should rebuild all existing rules | ||
| 67 | * using selinux_audit_rule_init(). | ||
| 68 | */ | ||
| 69 | void selinux_audit_set_callback(int (*callback)(void)); | ||
| 70 | |||
| 71 | /** | ||
| 72 | * selinux_string_to_sid - map a security context string to a security ID | 24 | * selinux_string_to_sid - map a security context string to a security ID |
| 73 | * @str: the security context string to be mapped | 25 | * @str: the security context string to be mapped |
| 74 | * @sid: ID value returned via this. | 26 | * @sid: ID value returned via this. |
| @@ -111,30 +63,6 @@ void selinux_secmark_refcount_inc(void); | |||
| 111 | void selinux_secmark_refcount_dec(void); | 63 | void selinux_secmark_refcount_dec(void); |
| 112 | #else | 64 | #else |
| 113 | 65 | ||
| 114 | static inline int selinux_audit_rule_init(u32 field, u32 op, | ||
| 115 | char *rulestr, | ||
| 116 | struct selinux_audit_rule **rule) | ||
| 117 | { | ||
| 118 | return -EOPNOTSUPP; | ||
| 119 | } | ||
| 120 | |||
| 121 | static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule) | ||
| 122 | { | ||
| 123 | return; | ||
| 124 | } | ||
| 125 | |||
| 126 | static inline int selinux_audit_rule_match(u32 sid, u32 field, u32 op, | ||
| 127 | struct selinux_audit_rule *rule, | ||
| 128 | struct audit_context *actx) | ||
| 129 | { | ||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 133 | static inline void selinux_audit_set_callback(int (*callback)(void)) | ||
| 134 | { | ||
| 135 | return; | ||
| 136 | } | ||
| 137 | |||
| 138 | static inline int selinux_string_to_sid(const char *str, u32 *sid) | 66 | static inline int selinux_string_to_sid(const char *str, u32 *sid) |
| 139 | { | 67 | { |
| 140 | *sid = 0; | 68 | *sid = 0; |
diff --git a/kernel/audit.h b/kernel/audit.h index 2554bd524fd1..3cfc54ee3e1f 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
| @@ -65,34 +65,9 @@ struct audit_watch { | |||
| 65 | struct list_head rules; /* associated rules */ | 65 | struct list_head rules; /* associated rules */ |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | struct audit_field { | ||
| 69 | u32 type; | ||
| 70 | u32 val; | ||
| 71 | u32 op; | ||
| 72 | char *se_str; | ||
| 73 | struct selinux_audit_rule *se_rule; | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct audit_tree; | 68 | struct audit_tree; |
| 77 | struct audit_chunk; | 69 | struct audit_chunk; |
| 78 | 70 | ||
| 79 | struct audit_krule { | ||
| 80 | int vers_ops; | ||
| 81 | u32 flags; | ||
| 82 | u32 listnr; | ||
| 83 | u32 action; | ||
| 84 | u32 mask[AUDIT_BITMASK_SIZE]; | ||
| 85 | u32 buflen; /* for data alloc on list rules */ | ||
| 86 | u32 field_count; | ||
| 87 | char *filterkey; /* ties events to rules */ | ||
| 88 | struct audit_field *fields; | ||
| 89 | struct audit_field *arch_f; /* quick access to arch field */ | ||
| 90 | struct audit_field *inode_f; /* quick access to an inode field */ | ||
| 91 | struct audit_watch *watch; /* associated watch */ | ||
| 92 | struct audit_tree *tree; /* associated watched tree */ | ||
| 93 | struct list_head rlist; /* entry in audit_{watch,tree}.rules list */ | ||
| 94 | }; | ||
| 95 | |||
| 96 | struct audit_entry { | 71 | struct audit_entry { |
| 97 | struct list_head list; | 72 | struct list_head list; |
| 98 | struct rcu_head rcu; | 73 | struct rcu_head rcu; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index bfffaa52e0cb..a2f7e9cf78c5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -83,6 +83,7 @@ | |||
| 83 | #include "netport.h" | 83 | #include "netport.h" |
| 84 | #include "xfrm.h" | 84 | #include "xfrm.h" |
| 85 | #include "netlabel.h" | 85 | #include "netlabel.h" |
| 86 | #include "audit.h" | ||
| 86 | 87 | ||
| 87 | #define XATTR_SELINUX_SUFFIX "selinux" | 88 | #define XATTR_SELINUX_SUFFIX "selinux" |
| 88 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX | 89 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX |
| @@ -5478,6 +5479,13 @@ static struct security_operations selinux_ops = { | |||
| 5478 | .key_free = selinux_key_free, | 5479 | .key_free = selinux_key_free, |
| 5479 | .key_permission = selinux_key_permission, | 5480 | .key_permission = selinux_key_permission, |
| 5480 | #endif | 5481 | #endif |
| 5482 | |||
| 5483 | #ifdef CONFIG_AUDIT | ||
| 5484 | .audit_rule_init = selinux_audit_rule_init, | ||
| 5485 | .audit_rule_known = selinux_audit_rule_known, | ||
| 5486 | .audit_rule_match = selinux_audit_rule_match, | ||
| 5487 | .audit_rule_free = selinux_audit_rule_free, | ||
| 5488 | #endif | ||
| 5481 | }; | 5489 | }; |
| 5482 | 5490 | ||
| 5483 | static __init int selinux_init(void) | 5491 | static __init int selinux_init(void) |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d75050819b06..1e0df5ec1bcd 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | #include "netlabel.h" | 57 | #include "netlabel.h" |
| 58 | #include "xfrm.h" | 58 | #include "xfrm.h" |
| 59 | #include "ebitmap.h" | 59 | #include "ebitmap.h" |
| 60 | #include "audit.h" | ||
| 60 | 61 | ||
| 61 | extern void selnl_notify_policyload(u32 seqno); | 62 | extern void selnl_notify_policyload(u32 seqno); |
| 62 | unsigned int policydb_loaded_version; | 63 | unsigned int policydb_loaded_version; |
| @@ -2296,21 +2297,23 @@ struct selinux_audit_rule { | |||
| 2296 | struct context au_ctxt; | 2297 | struct context au_ctxt; |
| 2297 | }; | 2298 | }; |
| 2298 | 2299 | ||
| 2299 | void selinux_audit_rule_free(struct selinux_audit_rule *rule) | 2300 | void selinux_audit_rule_free(void *vrule) |
| 2300 | { | 2301 | { |
| 2302 | struct selinux_audit_rule *rule = vrule; | ||
| 2303 | |||
| 2301 | if (rule) { | 2304 | if (rule) { |
| 2302 | context_destroy(&rule->au_ctxt); | 2305 | context_destroy(&rule->au_ctxt); |
| 2303 | kfree(rule); | 2306 | kfree(rule); |
| 2304 | } | 2307 | } |
| 2305 | } | 2308 | } |
| 2306 | 2309 | ||
| 2307 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | 2310 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) |
| 2308 | struct selinux_audit_rule **rule) | ||
| 2309 | { | 2311 | { |
| 2310 | struct selinux_audit_rule *tmprule; | 2312 | struct selinux_audit_rule *tmprule; |
| 2311 | struct role_datum *roledatum; | 2313 | struct role_datum *roledatum; |
| 2312 | struct type_datum *typedatum; | 2314 | struct type_datum *typedatum; |
| 2313 | struct user_datum *userdatum; | 2315 | struct user_datum *userdatum; |
| 2316 | struct selinux_audit_rule **rule = (struct selinux_audit_rule **)vrule; | ||
| 2314 | int rc = 0; | 2317 | int rc = 0; |
| 2315 | 2318 | ||
| 2316 | *rule = NULL; | 2319 | *rule = NULL; |
| @@ -2397,12 +2400,37 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | |||
| 2397 | return rc; | 2400 | return rc; |
| 2398 | } | 2401 | } |
| 2399 | 2402 | ||
| 2400 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, | 2403 | /* Check to see if the rule contains any selinux fields */ |
| 2401 | struct selinux_audit_rule *rule, | 2404 | int selinux_audit_rule_known(struct audit_krule *rule) |
| 2405 | { | ||
| 2406 | int i; | ||
| 2407 | |||
| 2408 | for (i = 0; i < rule->field_count; i++) { | ||
| 2409 | struct audit_field *f = &rule->fields[i]; | ||
| 2410 | switch (f->type) { | ||
| 2411 | case AUDIT_SUBJ_USER: | ||
| 2412 | case AUDIT_SUBJ_ROLE: | ||
| 2413 | case AUDIT_SUBJ_TYPE: | ||
| 2414 | case AUDIT_SUBJ_SEN: | ||
| 2415 | case AUDIT_SUBJ_CLR: | ||
| 2416 | case AUDIT_OBJ_USER: | ||
| 2417 | case AUDIT_OBJ_ROLE: | ||
| 2418 | case AUDIT_OBJ_TYPE: | ||
| 2419 | case AUDIT_OBJ_LEV_LOW: | ||
| 2420 | case AUDIT_OBJ_LEV_HIGH: | ||
| 2421 | return 1; | ||
| 2422 | } | ||
| 2423 | } | ||
| 2424 | |||
| 2425 | return 0; | ||
| 2426 | } | ||
| 2427 | |||
| 2428 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | ||
| 2402 | struct audit_context *actx) | 2429 | struct audit_context *actx) |
| 2403 | { | 2430 | { |
| 2404 | struct context *ctxt; | 2431 | struct context *ctxt; |
| 2405 | struct mls_level *level; | 2432 | struct mls_level *level; |
| 2433 | struct selinux_audit_rule *rule = vrule; | ||
| 2406 | int match = 0; | 2434 | int match = 0; |
| 2407 | 2435 | ||
| 2408 | if (!rule) { | 2436 | if (!rule) { |
| @@ -2509,7 +2537,7 @@ out: | |||
| 2509 | return match; | 2537 | return match; |
| 2510 | } | 2538 | } |
| 2511 | 2539 | ||
| 2512 | static int (*aurule_callback)(void) = NULL; | 2540 | static int (*aurule_callback)(void) = audit_update_lsm_rules; |
| 2513 | 2541 | ||
| 2514 | static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, | 2542 | static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, |
| 2515 | u16 class, u32 perms, u32 *retained) | 2543 | u16 class, u32 perms, u32 *retained) |
| @@ -2534,11 +2562,6 @@ static int __init aurule_init(void) | |||
| 2534 | } | 2562 | } |
| 2535 | __initcall(aurule_init); | 2563 | __initcall(aurule_init); |
| 2536 | 2564 | ||
| 2537 | void selinux_audit_set_callback(int (*callback)(void)) | ||
| 2538 | { | ||
| 2539 | aurule_callback = callback; | ||
| 2540 | } | ||
| 2541 | |||
| 2542 | #ifdef CONFIG_NETLABEL | 2565 | #ifdef CONFIG_NETLABEL |
| 2543 | /** | 2566 | /** |
| 2544 | * security_netlbl_cache_add - Add an entry to the NetLabel cache | 2567 | * security_netlbl_cache_add - Add an entry to the NetLabel cache |
