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 | 152 | /* bit values for audit_cfg_lsm */ |
| 153 | 153 | #define AUDIT_CFG_LSM_SECCTX_SUBJECT BIT(0) |
| 154 | +#define AUDIT_CFG_LSM_SECCTX_OBJECT BIT(1) | |
| 154 | 155 | |
| 155 | 156 | struct filename; |
| 156 | 157 | |
| @@ -191,6 +192,7 @@ extern void audit_log_path_denied(int type, · 34 unmodified lines | ||
| 191 | 192 | extern void audit_log_lost(const char *message); |
| 192 | 193 | |
| 193 | 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 | 196 | extern int audit_log_task_context(struct audit_buffer *ab); |
| 195 | 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 | 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 | 268 | static inline int audit_log_task_context(struct audit_buffer *ab) |
| 262 | 269 | { |
| 263 | 270 | return 0; |
| @@ -149,6 +149,7 @@ · 148 unmodified lines | ||
| 149 | 149 | #define AUDIT_LANDLOCK_ACCESS 1423 /* Landlock denial */ |
| 150 | 150 | #define AUDIT_LANDLOCK_DOMAIN 1424 /* Landlock domain status */ |
| 151 | 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 | 154 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 |
| 154 | 155 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 |
| @@ -85,7 +85,9 @@ static unsigned int audit_net_id; · 84 unmodified lines | ||
| 85 | 85 | /* Number of modules that provide a security context. |
| 86 | 86 | List of lsms that provide a security context */ |
| 87 | 87 | static u32 audit_subj_secctx_cnt; |
| 88 | +static u32 audit_obj_secctx_cnt; | |
| 88 | 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 | 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 | 307 | return; |
| 306 | 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 | 1150 | return af.features & AUDIT_FEATURE_TO_MASK(i); |
| 1143 | 1151 | } |
| 1144 | 1152 | |
| 1145 | − | |
| 1146 | 1153 | static int audit_get_feature(struct sk_buff *skb) |
| 1147 | 1154 | { |
| 1148 | 1155 | u32 seq; |
| @@ -2337,6 +2344,55 @@ int audit_log_task_context(struct audit_buffer *ab) · 1188 unmodified lines | ||
| 2337 | 2344 | } |
| 2338 | 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 | 2396 | void audit_log_d_path_exe(struct audit_buffer *ab, |
| 2341 | 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 | 1098 | char *comm) |
| 1099 | 1099 | { |
| 1100 | 1100 | struct audit_buffer *ab; |
| 1101 | − struct lsm_context ctx; | |
| 1102 | 1101 | int rc = 0; |
| 1103 | 1102 | |
| 1104 | 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 | 1107 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, |
| 1109 | 1108 | from_kuid(&init_user_ns, auid), |
| 1110 | 1109 | from_kuid(&init_user_ns, uid), sessionid); |
| 1111 | − if (lsmprop_is_set(prop)) { | |
| 1112 | − if (security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF) < 0) { | |
| 1113 | − audit_log_format(ab, " obj=(none)"); | |
| 1114 | − rc = 1; | |
| 1115 | − } else { | |
| 1116 | − audit_log_format(ab, " obj=%s", ctx.context); | |
| 1117 | − security_release_secctx(&ctx); | |
| 1118 | − } | |
| 1119 | − } | |
| 1110 | + if (lsmprop_is_set(prop) && audit_log_obj_ctx(ab, prop)) | |
| 1111 | + rc = 1; | |
| 1112 | + | |
| 1120 | 1113 | audit_log_format(ab, " ocomm="); |
| 1121 | 1114 | audit_log_untrustedstring(ab, comm); |
| 1122 | 1115 | audit_log_end(ab); |
| @@ -1392,16 +1385,8 @@ static void show_special(struct audit_context *context, int *call_panic) · 269 unmodified lines | ||
| 1392 | 1385 | from_kgid(&init_user_ns, context->ipc.gid), |
| 1393 | 1386 | context->ipc.mode); |
| 1394 | 1387 | if (lsmprop_is_set(&context->ipc.oprop)) { |
| 1395 | − struct lsm_context lsmctx; | |
| 1396 | − | |
| 1397 | − if (security_lsmprop_to_secctx(&context->ipc.oprop, | |
| 1398 | − &lsmctx, | |
| 1399 | − LSM_ID_UNDEF) < 0) { | |
| 1388 | + if (audit_log_obj_ctx(ab, &context->ipc.oprop)) | |
| 1400 | 1389 | *call_panic = 1; |
| 1401 | − } else { | |
| 1402 | − audit_log_format(ab, " obj=%s", lsmctx.context); | |
| 1403 | − security_release_secctx(&lsmctx); | |
| 1404 | − } | |
| 1405 | 1390 | } |
| 1406 | 1391 | if (context->ipc.has_perm) { |
| 1407 | 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 | 1543 | from_kgid(&init_user_ns, n->gid), |
| 1559 | 1544 | MAJOR(n->rdev), |
| 1560 | 1545 | MINOR(n->rdev)); |
| 1561 | − if (lsmprop_is_set(&n->oprop)) { | |
| 1562 | − struct lsm_context ctx; | |
| 1563 | − | |
| 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 | − } | |
| 1546 | + if (lsmprop_is_set(&n->oprop) && | |
| 1547 | + audit_log_obj_ctx(ab, &n->oprop)) | |
| 1548 | + *call_panic = 2; | |
| 1573 | 1549 | |
| 1574 | 1550 | /* log the audit_names record type */ |
| 1575 | 1551 | switch (n->type) { |
| @@ -7619,7 +7619,9 @@ static __init int selinux_init(void) · 7618 unmodified lines | ||
| 7619 | 7619 | cred_init_security(); |
| 7620 | 7620 | |
| 7621 | 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 | 7626 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); |
| 7625 | 7627 | if (!default_noexec) |
| @@ -5268,7 +5268,9 @@ static __init int smack_init(void) · 5267 unmodified lines | ||
| 5268 | 5268 | init_smack_known_list(); |
| 5269 | 5269 | |
| 5270 | 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 | 5275 | return 0; |
| 5274 | 5276 | } |