diff options
| -rw-r--r-- | include/linux/audit.h | 2 | ||||
| -rw-r--r-- | kernel/audit.c | 132 | ||||
| -rw-r--r-- | kernel/auditfilter.c | 44 | ||||
| -rw-r--r-- | kernel/auditsc.c | 4 |
4 files changed, 142 insertions, 40 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 740f950397b7..d5c40823e166 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -371,7 +371,7 @@ extern void audit_log_d_path(struct audit_buffer *ab, | |||
| 371 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 371 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
| 372 | extern int audit_filter_type(int type); | 372 | extern int audit_filter_type(int type); |
| 373 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 373 | extern int audit_receive_filter(int type, int pid, int uid, int seq, |
| 374 | void *data, size_t datasz, uid_t loginuid); | 374 | void *data, size_t datasz, uid_t loginuid, u32 sid); |
| 375 | #else | 375 | #else |
| 376 | #define audit_log(c,g,t,f,...) do { ; } while (0) | 376 | #define audit_log(c,g,t,f,...) do { ; } while (0) |
| 377 | #define audit_log_start(c,g,t) ({ NULL; }) | 377 | #define audit_log_start(c,g,t) ({ NULL; }) |
diff --git a/kernel/audit.c b/kernel/audit.c index 7ec9ccae1299..df57b493e1cb 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -230,49 +230,103 @@ void audit_log_lost(const char *message) | |||
| 230 | } | 230 | } |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | static int audit_set_rate_limit(int limit, uid_t loginuid) | 233 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) |
| 234 | { | 234 | { |
| 235 | int old = audit_rate_limit; | 235 | int old = audit_rate_limit; |
| 236 | audit_rate_limit = limit; | 236 | |
| 237 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 237 | if (sid) { |
| 238 | char *ctx = NULL; | ||
| 239 | u32 len; | ||
| 240 | int rc; | ||
| 241 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 242 | return rc; | ||
| 243 | else | ||
| 244 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 245 | "audit_rate_limit=%d old=%d by auid=%u subj=%s", | ||
| 246 | limit, old, loginuid, ctx); | ||
| 247 | kfree(ctx); | ||
| 248 | } else | ||
| 249 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 238 | "audit_rate_limit=%d old=%d by auid=%u", | 250 | "audit_rate_limit=%d old=%d by auid=%u", |
| 239 | audit_rate_limit, old, loginuid); | 251 | limit, old, loginuid); |
| 252 | audit_rate_limit = limit; | ||
| 240 | return old; | 253 | return old; |
| 241 | } | 254 | } |
| 242 | 255 | ||
| 243 | static int audit_set_backlog_limit(int limit, uid_t loginuid) | 256 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) |
| 244 | { | 257 | { |
| 245 | int old = audit_backlog_limit; | 258 | int old = audit_backlog_limit; |
| 246 | audit_backlog_limit = limit; | 259 | |
| 247 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 260 | if (sid) { |
| 261 | char *ctx = NULL; | ||
| 262 | u32 len; | ||
| 263 | int rc; | ||
| 264 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 265 | return rc; | ||
| 266 | else | ||
| 267 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 268 | "audit_backlog_limit=%d old=%d by auid=%u subj=%s", | ||
| 269 | limit, old, loginuid, ctx); | ||
| 270 | kfree(ctx); | ||
| 271 | } else | ||
| 272 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 248 | "audit_backlog_limit=%d old=%d by auid=%u", | 273 | "audit_backlog_limit=%d old=%d by auid=%u", |
| 249 | audit_backlog_limit, old, loginuid); | 274 | limit, old, loginuid); |
| 275 | audit_backlog_limit = limit; | ||
| 250 | return old; | 276 | return old; |
| 251 | } | 277 | } |
| 252 | 278 | ||
| 253 | static int audit_set_enabled(int state, uid_t loginuid) | 279 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) |
| 254 | { | 280 | { |
| 255 | int old = audit_enabled; | 281 | int old = audit_enabled; |
| 282 | |||
| 256 | if (state != 0 && state != 1) | 283 | if (state != 0 && state != 1) |
| 257 | return -EINVAL; | 284 | return -EINVAL; |
| 258 | audit_enabled = state; | 285 | |
| 259 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 286 | if (sid) { |
| 287 | char *ctx = NULL; | ||
| 288 | u32 len; | ||
| 289 | int rc; | ||
| 290 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 291 | return rc; | ||
| 292 | else | ||
| 293 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 294 | "audit_enabled=%d old=%d by auid=%u subj=%s", | ||
| 295 | state, old, loginuid, ctx); | ||
| 296 | kfree(ctx); | ||
| 297 | } else | ||
| 298 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 260 | "audit_enabled=%d old=%d by auid=%u", | 299 | "audit_enabled=%d old=%d by auid=%u", |
| 261 | audit_enabled, old, loginuid); | 300 | state, old, loginuid); |
| 301 | audit_enabled = state; | ||
| 262 | return old; | 302 | return old; |
| 263 | } | 303 | } |
| 264 | 304 | ||
| 265 | static int audit_set_failure(int state, uid_t loginuid) | 305 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) |
| 266 | { | 306 | { |
| 267 | int old = audit_failure; | 307 | int old = audit_failure; |
| 308 | |||
| 268 | if (state != AUDIT_FAIL_SILENT | 309 | if (state != AUDIT_FAIL_SILENT |
| 269 | && state != AUDIT_FAIL_PRINTK | 310 | && state != AUDIT_FAIL_PRINTK |
| 270 | && state != AUDIT_FAIL_PANIC) | 311 | && state != AUDIT_FAIL_PANIC) |
| 271 | return -EINVAL; | 312 | return -EINVAL; |
| 272 | audit_failure = state; | 313 | |
| 273 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 314 | if (sid) { |
| 315 | char *ctx = NULL; | ||
| 316 | u32 len; | ||
| 317 | int rc; | ||
| 318 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 319 | return rc; | ||
| 320 | else | ||
| 321 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 322 | "audit_failure=%d old=%d by auid=%u subj=%s", | ||
| 323 | state, old, loginuid, ctx); | ||
| 324 | kfree(ctx); | ||
| 325 | } else | ||
| 326 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 274 | "audit_failure=%d old=%d by auid=%u", | 327 | "audit_failure=%d old=%d by auid=%u", |
| 275 | audit_failure, old, loginuid); | 328 | state, old, loginuid); |
| 329 | audit_failure = state; | ||
| 276 | return old; | 330 | return old; |
| 277 | } | 331 | } |
| 278 | 332 | ||
| @@ -437,25 +491,43 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 437 | return -EINVAL; | 491 | return -EINVAL; |
| 438 | status_get = (struct audit_status *)data; | 492 | status_get = (struct audit_status *)data; |
| 439 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 493 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
| 440 | err = audit_set_enabled(status_get->enabled, loginuid); | 494 | err = audit_set_enabled(status_get->enabled, |
| 495 | loginuid, sid); | ||
| 441 | if (err < 0) return err; | 496 | if (err < 0) return err; |
| 442 | } | 497 | } |
| 443 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 498 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
| 444 | err = audit_set_failure(status_get->failure, loginuid); | 499 | err = audit_set_failure(status_get->failure, |
| 500 | loginuid, sid); | ||
| 445 | if (err < 0) return err; | 501 | if (err < 0) return err; |
| 446 | } | 502 | } |
| 447 | if (status_get->mask & AUDIT_STATUS_PID) { | 503 | if (status_get->mask & AUDIT_STATUS_PID) { |
| 448 | int old = audit_pid; | 504 | int old = audit_pid; |
| 505 | if (sid) { | ||
| 506 | char *ctx = NULL; | ||
| 507 | u32 len; | ||
| 508 | int rc; | ||
| 509 | if ((rc = selinux_ctxid_to_string( | ||
| 510 | sid, &ctx, &len))) | ||
| 511 | return rc; | ||
| 512 | else | ||
| 513 | audit_log(NULL, GFP_KERNEL, | ||
| 514 | AUDIT_CONFIG_CHANGE, | ||
| 515 | "audit_pid=%d old=%d by auid=%u subj=%s", | ||
| 516 | status_get->pid, old, | ||
| 517 | loginuid, ctx); | ||
| 518 | kfree(ctx); | ||
| 519 | } else | ||
| 520 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 521 | "audit_pid=%d old=%d by auid=%u", | ||
| 522 | status_get->pid, old, loginuid); | ||
| 449 | audit_pid = status_get->pid; | 523 | audit_pid = status_get->pid; |
| 450 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 451 | "audit_pid=%d old=%d by auid=%u", | ||
| 452 | audit_pid, old, loginuid); | ||
| 453 | } | 524 | } |
| 454 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 525 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
| 455 | audit_set_rate_limit(status_get->rate_limit, loginuid); | 526 | audit_set_rate_limit(status_get->rate_limit, |
| 527 | loginuid, sid); | ||
| 456 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 528 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
| 457 | audit_set_backlog_limit(status_get->backlog_limit, | 529 | audit_set_backlog_limit(status_get->backlog_limit, |
| 458 | loginuid); | 530 | loginuid, sid); |
| 459 | break; | 531 | break; |
| 460 | case AUDIT_USER: | 532 | case AUDIT_USER: |
| 461 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 533 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
| @@ -477,7 +549,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 477 | if (selinux_ctxid_to_string( | 549 | if (selinux_ctxid_to_string( |
| 478 | sid, &ctx, &len)) { | 550 | sid, &ctx, &len)) { |
| 479 | audit_log_format(ab, | 551 | audit_log_format(ab, |
| 480 | " subj=%u", sid); | 552 | " ssid=%u", sid); |
| 481 | /* Maybe call audit_panic? */ | 553 | /* Maybe call audit_panic? */ |
| 482 | } else | 554 | } else |
| 483 | audit_log_format(ab, | 555 | audit_log_format(ab, |
| @@ -499,7 +571,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 499 | case AUDIT_LIST: | 571 | case AUDIT_LIST: |
| 500 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 572 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
| 501 | uid, seq, data, nlmsg_len(nlh), | 573 | uid, seq, data, nlmsg_len(nlh), |
| 502 | loginuid); | 574 | loginuid, sid); |
| 503 | break; | 575 | break; |
| 504 | case AUDIT_ADD_RULE: | 576 | case AUDIT_ADD_RULE: |
| 505 | case AUDIT_DEL_RULE: | 577 | case AUDIT_DEL_RULE: |
| @@ -509,7 +581,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 509 | case AUDIT_LIST_RULES: | 581 | case AUDIT_LIST_RULES: |
| 510 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 582 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
| 511 | uid, seq, data, nlmsg_len(nlh), | 583 | uid, seq, data, nlmsg_len(nlh), |
| 512 | loginuid); | 584 | loginuid, sid); |
| 513 | break; | 585 | break; |
| 514 | case AUDIT_SIGNAL_INFO: | 586 | case AUDIT_SIGNAL_INFO: |
| 515 | sig_data.uid = audit_sig_uid; | 587 | sig_data.uid = audit_sig_uid; |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 85a7862143a1..7c134906d689 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -586,9 +586,10 @@ static int audit_list_rules(void *_dest) | |||
| 586 | * @data: payload data | 586 | * @data: payload data |
| 587 | * @datasz: size of payload data | 587 | * @datasz: size of payload data |
| 588 | * @loginuid: loginuid of sender | 588 | * @loginuid: loginuid of sender |
| 589 | * @sid: SE Linux Security ID of sender | ||
| 589 | */ | 590 | */ |
| 590 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 591 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
| 591 | size_t datasz, uid_t loginuid) | 592 | size_t datasz, uid_t loginuid, u32 sid) |
| 592 | { | 593 | { |
| 593 | struct task_struct *tsk; | 594 | struct task_struct *tsk; |
| 594 | int *dest; | 595 | int *dest; |
| @@ -631,9 +632,23 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 631 | 632 | ||
| 632 | err = audit_add_rule(entry, | 633 | err = audit_add_rule(entry, |
| 633 | &audit_filter_list[entry->rule.listnr]); | 634 | &audit_filter_list[entry->rule.listnr]); |
| 634 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 635 | if (sid) { |
| 635 | "auid=%u add rule to list=%d res=%d\n", | 636 | char *ctx = NULL; |
| 636 | loginuid, entry->rule.listnr, !err); | 637 | u32 len; |
| 638 | if (selinux_ctxid_to_string(sid, &ctx, &len)) { | ||
| 639 | /* Maybe call audit_panic? */ | ||
| 640 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 641 | "auid=%u ssid=%u add rule to list=%d res=%d", | ||
| 642 | loginuid, sid, entry->rule.listnr, !err); | ||
| 643 | } else | ||
| 644 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 645 | "auid=%u subj=%s add rule to list=%d res=%d", | ||
| 646 | loginuid, ctx, entry->rule.listnr, !err); | ||
| 647 | kfree(ctx); | ||
| 648 | } else | ||
| 649 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 650 | "auid=%u add rule to list=%d res=%d", | ||
| 651 | loginuid, entry->rule.listnr, !err); | ||
| 637 | 652 | ||
| 638 | if (err) | 653 | if (err) |
| 639 | audit_free_rule(entry); | 654 | audit_free_rule(entry); |
| @@ -649,9 +664,24 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 649 | 664 | ||
| 650 | err = audit_del_rule(entry, | 665 | err = audit_del_rule(entry, |
| 651 | &audit_filter_list[entry->rule.listnr]); | 666 | &audit_filter_list[entry->rule.listnr]); |
| 652 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 667 | |
| 653 | "auid=%u remove rule from list=%d res=%d\n", | 668 | if (sid) { |
| 654 | loginuid, entry->rule.listnr, !err); | 669 | char *ctx = NULL; |
| 670 | u32 len; | ||
| 671 | if (selinux_ctxid_to_string(sid, &ctx, &len)) { | ||
| 672 | /* Maybe call audit_panic? */ | ||
| 673 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 674 | "auid=%u ssid=%u remove rule from list=%d res=%d", | ||
| 675 | loginuid, sid, entry->rule.listnr, !err); | ||
| 676 | } else | ||
| 677 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 678 | "auid=%u subj=%s remove rule from list=%d res=%d", | ||
| 679 | loginuid, ctx, entry->rule.listnr, !err); | ||
| 680 | kfree(ctx); | ||
| 681 | } else | ||
| 682 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 683 | "auid=%u remove rule from list=%d res=%d", | ||
| 684 | loginuid, entry->rule.listnr, !err); | ||
| 655 | 685 | ||
| 656 | audit_free_rule(entry); | 686 | audit_free_rule(entry); |
| 657 | break; | 687 | break; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b4f7223811fe..d94e0404113c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -637,7 +637,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 637 | u32 len; | 637 | u32 len; |
| 638 | if (selinux_ctxid_to_string( | 638 | if (selinux_ctxid_to_string( |
| 639 | axi->osid, &ctx, &len)) { | 639 | axi->osid, &ctx, &len)) { |
| 640 | audit_log_format(ab, " obj=%u", | 640 | audit_log_format(ab, " osid=%u", |
| 641 | axi->osid); | 641 | axi->osid); |
| 642 | call_panic = 1; | 642 | call_panic = 1; |
| 643 | } else | 643 | } else |
| @@ -712,7 +712,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 712 | u32 len; | 712 | u32 len; |
| 713 | if (selinux_ctxid_to_string( | 713 | if (selinux_ctxid_to_string( |
| 714 | context->names[i].osid, &ctx, &len)) { | 714 | context->names[i].osid, &ctx, &len)) { |
| 715 | audit_log_format(ab, " obj=%u", | 715 | audit_log_format(ab, " osid=%u", |
| 716 | context->names[i].osid); | 716 | context->names[i].osid); |
| 717 | call_panic = 2; | 717 | call_panic = 2; |
| 718 | } else | 718 | } else |
