Create a new audit record AUDIT_MAC_OBJ_CONTEXTS. An example of the MAC_OBJ_CONTEXTS record is: type=MAC_OBJ_CONTEXTS msg=audit(1601152467.009:1050): obj_selinux=unconfined_u:object_r:user_home_t:s0 When an audit event includes a AUDIT_MAC_OBJ_CONTEXTS record the "obj=" field in other records in the event will be "obj=?". An AUDIT_MAC_OBJ_CONTEXTS record is supplied when the system has multiple security modules that may make access decisions based on an object security context.
Unified · Split
| @@ -151,6 +151,7 @@ extern unsigned compat_signal_class[]; · 150 unmodified lines | |||
| 151 | 151 | ||
| 152 | /* bit values for audit_cfg_lsm */ | 152 | /* bit values for audit_cfg_lsm */ |
| 153 | #define AUDIT_CFG_LSM_SECCTX_SUBJECT BIT(0) | 153 | #define AUDIT_CFG_LSM_SECCTX_SUBJECT BIT(0) |
| 154 | #define AUDIT_CFG_LSM_SECCTX_OBJECT BIT(1) | ||
| 154 | 155 | ||
| 155 | struct filename; | 156 | struct filename; |
| 156 | 157 | ||
| @@ -191,6 +192,7 @@ extern void audit_log_path_denied(int type, · 34 unmodified lines | |||
| 191 | extern void audit_log_lost(const char *message); | 192 | extern void audit_log_lost(const char *message); |
| 192 | 193 | ||
| 193 | extern int audit_log_subj_ctx(struct audit_buffer *ab, struct lsm_prop *prop); | 194 | extern int audit_log_subj_ctx(struct audit_buffer *ab, struct lsm_prop *prop); |
| 195 | extern int audit_log_obj_ctx(struct audit_buffer *ab, struct lsm_prop *prop); | ||
| 194 | extern int audit_log_task_context(struct audit_buffer *ab); | 196 | extern int audit_log_task_context(struct audit_buffer *ab); |
| 195 | extern void audit_log_task_info(struct audit_buffer *ab); | 197 | extern void audit_log_task_info(struct audit_buffer *ab); |
| 196 | 198 | ||
| @@ -258,6 +260,11 @@ static inline int audit_log_subj_ctx(struct audit_buffer *ab, · 61 unmodified lines | |||
| 258 | { | 260 | { |
| 259 | return 0; | 261 | return 0; |
| 260 | } | 262 | } |
| 263 | static inline int audit_log_obj_ctx(struct audit_buffer *ab, | ||
| 264 | struct lsm_prop *prop) | ||
| 265 | { | ||
| 266 | return 0; | ||
| 267 | } | ||
| 261 | static inline int audit_log_task_context(struct audit_buffer *ab) | 268 | static inline int audit_log_task_context(struct audit_buffer *ab) |
| 262 | { | 269 | { |
| 263 | return 0; | 270 | return 0; |
| @@ -149,6 +149,7 @@ · 148 unmodified lines | |||
| 149 | #define AUDIT_LANDLOCK_ACCESS 1423 /* Landlock denial */ | 149 | #define AUDIT_LANDLOCK_ACCESS 1423 /* Landlock denial */ |
| 150 | #define AUDIT_LANDLOCK_DOMAIN 1424 /* Landlock domain status */ | 150 | #define AUDIT_LANDLOCK_DOMAIN 1424 /* Landlock domain status */ |
| 151 | #define AUDIT_MAC_TASK_CONTEXTS 1425 /* Multiple LSM task contexts */ | 151 | #define AUDIT_MAC_TASK_CONTEXTS 1425 /* Multiple LSM task contexts */ |
| 152 | #define AUDIT_MAC_OBJ_CONTEXTS 1426 /* Multiple LSM objext contexts */ | ||
| 152 | 153 | ||
| 153 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 | 154 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 |
| 154 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 | 155 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 |
| @@ -85,7 +85,9 @@ static unsigned int audit_net_id; · 84 unmodified lines | |||
| 85 | /* Number of modules that provide a security context. | 85 | /* Number of modules that provide a security context. |
| 86 | List of lsms that provide a security context */ | 86 | List of lsms that provide a security context */ |
| 87 | static u32 audit_subj_secctx_cnt; | 87 | static u32 audit_subj_secctx_cnt; |
| 88 | static u32 audit_obj_secctx_cnt; | ||
| 88 | static const struct lsm_id *audit_subj_lsms[MAX_LSM_COUNT]; | 89 | static const struct lsm_id *audit_subj_lsms[MAX_LSM_COUNT]; |
| 90 | static const struct lsm_id *audit_obj_lsms[MAX_LSM_COUNT]; | ||
| 89 | 91 | ||
| 90 | /** | 92 | /** |
| 91 | * struct audit_net - audit private network namespace data | 93 | * struct audit_net - audit private network namespace data |
| @@ -305,6 +307,12 @@ void audit_cfg_lsm(const struct lsm_id *lsmid, int flags) · 213 unmodified lines | |||
| 305 | return; | 307 | return; |
| 306 | audit_subj_lsms[audit_subj_secctx_cnt++] = lsmid; | 308 | audit_subj_lsms[audit_subj_secctx_cnt++] = lsmid; |
| 307 | } | 309 | } |
| 310 | if (flags & AUDIT_CFG_LSM_SECCTX_OBJECT) { | ||
| 311 | for (i = 0 ; i < audit_obj_secctx_cnt; i++) | ||
| 312 | if (audit_obj_lsms[i] == lsmid) | ||
| 313 | return; | ||
| 314 | audit_obj_lsms[audit_obj_secctx_cnt++] = lsmid; | ||
| 315 | } | ||
| 308 | } | 316 | } |
| 309 | 317 | ||
| 310 | /** | 318 | /** |
| @@ -1142,7 +1150,6 @@ static int is_audit_feature_set(int i) · 831 unmodified lines | |||
| 1142 | return af.features & AUDIT_FEATURE_TO_MASK(i); | 1150 | return af.features & AUDIT_FEATURE_TO_MASK(i); |
| 1143 | } | 1151 | } |
| 1144 | 1152 | ||
| 1145 | |||
| 1146 | static int audit_get_feature(struct sk_buff *skb) | 1153 | static int audit_get_feature(struct sk_buff *skb) |
| 1147 | { | 1154 | { |
| 1148 | u32 seq; | 1155 | u32 seq; |
| @@ -2337,6 +2344,55 @@ int audit_log_task_context(struct audit_buffer *ab) · 1188 unmodified lines | |||
| 2337 | } | 2344 | } |
| 2338 | EXPORT_SYMBOL(audit_log_task_context); | 2345 | EXPORT_SYMBOL(audit_log_task_context); |
| 2339 | 2346 | ||
| 2347 | int audit_log_obj_ctx(struct audit_buffer *ab, struct lsm_prop *prop) | ||
| 2348 | { | ||
| 2349 | int i; | ||
| 2350 | int rc; | ||
| 2351 | int error = 0; | ||
| 2352 | char *space = ""; | ||
| 2353 | struct lsm_context ctx; | ||
| 2354 | |||
| 2355 | if (audit_obj_secctx_cnt < 2) { | ||
| 2356 | error = security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF); | ||
| 2357 | if (error < 0) { | ||
| 2358 | if (error != -EINVAL) | ||
| 2359 | goto error_path; | ||
| 2360 | return error; | ||
| 2361 | } | ||
| 2362 | audit_log_format(ab, " obj=%s", ctx.context); | ||
| 2363 | security_release_secctx(&ctx); | ||
| 2364 | return 0; | ||
| 2365 | } | ||
| 2366 | audit_log_format(ab, " obj=?"); | ||
| 2367 | error = audit_buffer_aux_new(ab, AUDIT_MAC_OBJ_CONTEXTS); | ||
| 2368 | if (error) | ||
| 2369 | goto error_path; | ||
| 2370 | |||
| 2371 | for (i = 0; i < audit_obj_secctx_cnt; i++) { | ||
| 2372 | rc = security_lsmprop_to_secctx(prop, &ctx, | ||
| 2373 | audit_obj_lsms[i]->id); | ||
| 2374 | if (rc < 0) { | ||
| 2375 | audit_log_format(ab, "%sobj_%s=?", space, | ||
| 2376 | audit_obj_lsms[i]->name); | ||
| 2377 | if (rc != -EINVAL) | ||
| 2378 | audit_panic("error in audit_log_obj_ctx"); | ||
| 2379 | error = rc; | ||
| 2380 | } else { | ||
| 2381 | audit_log_format(ab, "%sobj_%s=%s", space, | ||
| 2382 | audit_obj_lsms[i]->name, ctx.context); | ||
| 2383 | security_release_secctx(&ctx); | ||
| 2384 | } | ||
| 2385 | space = " "; | ||
| 2386 | } | ||
| 2387 | |||
| 2388 | audit_buffer_aux_end(ab); | ||
| 2389 | return error; | ||
| 2390 | |||
| 2391 | error_path: | ||
| 2392 | audit_panic("error in audit_log_obj_ctx"); | ||
| 2393 | return error; | ||
| 2394 | } | ||
| 2395 | |||
| 2340 | void audit_log_d_path_exe(struct audit_buffer *ab, | 2396 | void audit_log_d_path_exe(struct audit_buffer *ab, |
| 2341 | struct mm_struct *mm) | 2397 | struct mm_struct *mm) |
| 2342 | { | 2398 | { |
| @@ -1098,7 +1098,6 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, · 1097 unmodified lines | |||
| 1098 | char *comm) | 1098 | char *comm) |
| 1099 | { | 1099 | { |
| 1100 | struct audit_buffer *ab; | 1100 | struct audit_buffer *ab; |
| 1101 | struct lsm_context ctx; | ||
| 1102 | int rc = 0; | 1101 | int rc = 0; |
| 1103 | 1102 | ||
| 1104 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); | 1103 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); |
| @@ -1108,15 +1107,9 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, · 3 unmodified lines | |||
| 1108 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, | 1107 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, |
| 1109 | from_kuid(&init_user_ns, auid), | 1108 | from_kuid(&init_user_ns, auid), |
| 1110 | from_kuid(&init_user_ns, uid), sessionid); | 1109 | from_kuid(&init_user_ns, uid), sessionid); |
| 1111 | if (lsmprop_is_set(prop)) { | 1110 | if (lsmprop_is_set(prop) && audit_log_obj_ctx(ab, prop)) |
| 1112 | if (security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF) < 0) { | 1111 | rc = 1; |
| 1113 | audit_log_format(ab, " obj=(none)"); | 1112 | |
| 1114 | rc = 1; | ||
| 1115 | } else { | ||
| 1116 | audit_log_format(ab, " obj=%s", ctx.context); | ||
| 1117 | security_release_secctx(&ctx); | ||
| 1118 | } | ||
| 1119 | } | ||
| 1120 | audit_log_format(ab, " ocomm="); | 1113 | audit_log_format(ab, " ocomm="); |
| 1121 | audit_log_untrustedstring(ab, comm); | 1114 | audit_log_untrustedstring(ab, comm); |
| 1122 | audit_log_end(ab); | 1115 | audit_log_end(ab); |
| @@ -1392,16 +1385,8 @@ static void show_special(struct audit_context *context, int *call_panic) · 269 unmodified lines | |||
| 1392 | from_kgid(&init_user_ns, context->ipc.gid), | 1385 | from_kgid(&init_user_ns, context->ipc.gid), |
| 1393 | context->ipc.mode); | 1386 | context->ipc.mode); |
| 1394 | if (lsmprop_is_set(&context->ipc.oprop)) { | 1387 | if (lsmprop_is_set(&context->ipc.oprop)) { |
| 1395 | struct lsm_context lsmctx; | 1388 | if (audit_log_obj_ctx(ab, &context->ipc.oprop)) |
| 1396 | |||
| 1397 | if (security_lsmprop_to_secctx(&context->ipc.oprop, | ||
| 1398 | &lsmctx, | ||
| 1399 | LSM_ID_UNDEF) < 0) { | ||
| 1400 | *call_panic = 1; | 1389 | *call_panic = 1; |
| 1401 | } else { | ||
| 1402 | audit_log_format(ab, " obj=%s", lsmctx.context); | ||
| 1403 | security_release_secctx(&lsmctx); | ||
| 1404 | } | ||
| 1405 | } | 1390 | } |
| 1406 | if (context->ipc.has_perm) { | 1391 | if (context->ipc.has_perm) { |
| 1407 | audit_log_end(ab); | 1392 | audit_log_end(ab); |
| @@ -1558,18 +1543,9 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, · 150 unmodified lines | |||
| 1558 | from_kgid(&init_user_ns, n->gid), | 1543 | from_kgid(&init_user_ns, n->gid), |
| 1559 | MAJOR(n->rdev), | 1544 | MAJOR(n->rdev), |
| 1560 | MINOR(n->rdev)); | 1545 | MINOR(n->rdev)); |
| 1561 | if (lsmprop_is_set(&n->oprop)) { | 1546 | if (lsmprop_is_set(&n->oprop) && |
| 1562 | struct lsm_context ctx; | 1547 | audit_log_obj_ctx(ab, &n->oprop)) |
| 1563 | 1548 | *call_panic = 2; | |
| 1564 | if (security_lsmprop_to_secctx(&n->oprop, &ctx, | ||
| 1565 | LSM_ID_UNDEF) < 0) { | ||
| 1566 | if (call_panic) | ||
| 1567 | *call_panic = 2; | ||
| 1568 | } else { | ||
| 1569 | audit_log_format(ab, " obj=%s", ctx.context); | ||
| 1570 | security_release_secctx(&ctx); | ||
| 1571 | } | ||
| 1572 | } | ||
| 1573 | 1549 | ||
| 1574 | /* log the audit_names record type */ | 1550 | /* log the audit_names record type */ |
| 1575 | switch (n->type) { | 1551 | switch (n->type) { |
| @@ -7619,7 +7619,9 @@ static __init int selinux_init(void) · 7618 unmodified lines | |||
| 7619 | cred_init_security(); | 7619 | cred_init_security(); |
| 7620 | 7620 | ||
| 7621 | /* Inform the audit system that secctx is used */ | 7621 | /* Inform the audit system that secctx is used */ |
| 7622 | audit_cfg_lsm(&selinux_lsmid, AUDIT_CFG_LSM_SECCTX_SUBJECT); | 7622 | audit_cfg_lsm(&selinux_lsmid, |
| 7623 | AUDIT_CFG_LSM_SECCTX_SUBJECT | | ||
| 7624 | AUDIT_CFG_LSM_SECCTX_OBJECT); | ||
| 7623 | 7625 | ||
| 7624 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); | 7626 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); |
| 7625 | if (!default_noexec) | 7627 | if (!default_noexec) |
| @@ -5268,7 +5268,9 @@ static __init int smack_init(void) · 5267 unmodified lines | |||
| 5268 | init_smack_known_list(); | 5268 | init_smack_known_list(); |
| 5269 | 5269 | ||
| 5270 | /* Inform the audit system that secctx is used */ | 5270 | /* Inform the audit system that secctx is used */ |
| 5271 | audit_cfg_lsm(&smack_lsmid, AUDIT_CFG_LSM_SECCTX_SUBJECT); | 5271 | audit_cfg_lsm(&smack_lsmid, |
| 5272 | AUDIT_CFG_LSM_SECCTX_SUBJECT | | ||
| 5273 | AUDIT_CFG_LSM_SECCTX_OBJECT); | ||
| 5272 | 5274 | ||
| 5273 | return 0; | 5275 | return 0; |
| 5274 | } | 5276 | } |