diff options
author | Eric Paris <eparis@redhat.com> | 2008-04-18 10:09:25 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-28 06:18:03 -0400 |
commit | 2532386f480eefbdd67b48be55fb4fb3e5a6081c (patch) | |
tree | dd6a5a3c4116a67380a1336319c16632f04f80f9 /kernel | |
parent | 436c405c7d19455a71f42c9bec5fd5e028f1eb4e (diff) |
Audit: collect sessionid in netlink messages
Previously I added sessionid output to all audit messages where it was
available but we still didn't know the sessionid of the sender of
netlink messages. This patch adds that information to netlink messages
so we can audit who sent netlink messages.
Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 72 | ||||
-rw-r--r-- | kernel/auditfilter.c | 16 |
2 files changed, 49 insertions, 39 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index a7b16086d36f..ad6d1abfa1d2 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -252,14 +252,15 @@ void audit_log_lost(const char *message) | |||
252 | } | 252 | } |
253 | 253 | ||
254 | static int audit_log_config_change(char *function_name, int new, int old, | 254 | static int audit_log_config_change(char *function_name, int new, int old, |
255 | uid_t loginuid, u32 sid, int allow_changes) | 255 | uid_t loginuid, u32 sessionid, u32 sid, |
256 | int allow_changes) | ||
256 | { | 257 | { |
257 | struct audit_buffer *ab; | 258 | struct audit_buffer *ab; |
258 | int rc = 0; | 259 | int rc = 0; |
259 | 260 | ||
260 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 261 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
261 | audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new, | 262 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, |
262 | old, loginuid); | 263 | old, loginuid, sessionid); |
263 | if (sid) { | 264 | if (sid) { |
264 | char *ctx = NULL; | 265 | char *ctx = NULL; |
265 | u32 len; | 266 | u32 len; |
@@ -279,7 +280,8 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
279 | } | 280 | } |
280 | 281 | ||
281 | static int audit_do_config_change(char *function_name, int *to_change, | 282 | static int audit_do_config_change(char *function_name, int *to_change, |
282 | int new, uid_t loginuid, u32 sid) | 283 | int new, uid_t loginuid, u32 sessionid, |
284 | u32 sid) | ||
283 | { | 285 | { |
284 | int allow_changes, rc = 0, old = *to_change; | 286 | int allow_changes, rc = 0, old = *to_change; |
285 | 287 | ||
@@ -290,8 +292,8 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
290 | allow_changes = 1; | 292 | allow_changes = 1; |
291 | 293 | ||
292 | if (audit_enabled != AUDIT_OFF) { | 294 | if (audit_enabled != AUDIT_OFF) { |
293 | rc = audit_log_config_change(function_name, new, old, | 295 | rc = audit_log_config_change(function_name, new, old, loginuid, |
294 | loginuid, sid, allow_changes); | 296 | sessionid, sid, allow_changes); |
295 | if (rc) | 297 | if (rc) |
296 | allow_changes = 0; | 298 | allow_changes = 0; |
297 | } | 299 | } |
@@ -305,26 +307,28 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
305 | return rc; | 307 | return rc; |
306 | } | 308 | } |
307 | 309 | ||
308 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) | 310 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sessionid, |
311 | u32 sid) | ||
309 | { | 312 | { |
310 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, | 313 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, |
311 | limit, loginuid, sid); | 314 | limit, loginuid, sessionid, sid); |
312 | } | 315 | } |
313 | 316 | ||
314 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) | 317 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sessionid, |
318 | u32 sid) | ||
315 | { | 319 | { |
316 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, | 320 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, |
317 | limit, loginuid, sid); | 321 | limit, loginuid, sessionid, sid); |
318 | } | 322 | } |
319 | 323 | ||
320 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | 324 | static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid) |
321 | { | 325 | { |
322 | int rc; | 326 | int rc; |
323 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) | 327 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) |
324 | return -EINVAL; | 328 | return -EINVAL; |
325 | 329 | ||
326 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, | 330 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, |
327 | loginuid, sid); | 331 | loginuid, sessionid, sid); |
328 | 332 | ||
329 | if (!rc) | 333 | if (!rc) |
330 | audit_ever_enabled |= !!state; | 334 | audit_ever_enabled |= !!state; |
@@ -332,7 +336,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | |||
332 | return rc; | 336 | return rc; |
333 | } | 337 | } |
334 | 338 | ||
335 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) | 339 | static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid) |
336 | { | 340 | { |
337 | if (state != AUDIT_FAIL_SILENT | 341 | if (state != AUDIT_FAIL_SILENT |
338 | && state != AUDIT_FAIL_PRINTK | 342 | && state != AUDIT_FAIL_PRINTK |
@@ -340,7 +344,7 @@ static int audit_set_failure(int state, uid_t loginuid, u32 sid) | |||
340 | return -EINVAL; | 344 | return -EINVAL; |
341 | 345 | ||
342 | return audit_do_config_change("audit_failure", &audit_failure, state, | 346 | return audit_do_config_change("audit_failure", &audit_failure, state, |
343 | loginuid, sid); | 347 | loginuid, sessionid, sid); |
344 | } | 348 | } |
345 | 349 | ||
346 | static int kauditd_thread(void *dummy) | 350 | static int kauditd_thread(void *dummy) |
@@ -385,7 +389,7 @@ static int kauditd_thread(void *dummy) | |||
385 | return 0; | 389 | return 0; |
386 | } | 390 | } |
387 | 391 | ||
388 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | 392 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid) |
389 | { | 393 | { |
390 | struct task_struct *tsk; | 394 | struct task_struct *tsk; |
391 | int err; | 395 | int err; |
@@ -404,7 +408,7 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | |||
404 | if (err) | 408 | if (err) |
405 | goto out; | 409 | goto out; |
406 | 410 | ||
407 | tty_audit_push_task(tsk, loginuid); | 411 | tty_audit_push_task(tsk, loginuid, sessionid); |
408 | out: | 412 | out: |
409 | read_unlock(&tasklist_lock); | 413 | read_unlock(&tasklist_lock); |
410 | return err; | 414 | return err; |
@@ -534,7 +538,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
534 | } | 538 | } |
535 | 539 | ||
536 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | 540 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, |
537 | u32 pid, u32 uid, uid_t auid, u32 sid) | 541 | u32 pid, u32 uid, uid_t auid, u32 ses, |
542 | u32 sid) | ||
538 | { | 543 | { |
539 | int rc = 0; | 544 | int rc = 0; |
540 | char *ctx = NULL; | 545 | char *ctx = NULL; |
@@ -546,8 +551,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
546 | } | 551 | } |
547 | 552 | ||
548 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 553 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
549 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", | 554 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u ses=%u", |
550 | pid, uid, auid); | 555 | pid, uid, auid, ses); |
551 | if (sid) { | 556 | if (sid) { |
552 | rc = security_secid_to_secctx(sid, &ctx, &len); | 557 | rc = security_secid_to_secctx(sid, &ctx, &len); |
553 | if (rc) | 558 | if (rc) |
@@ -570,6 +575,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
570 | struct audit_buffer *ab; | 575 | struct audit_buffer *ab; |
571 | u16 msg_type = nlh->nlmsg_type; | 576 | u16 msg_type = nlh->nlmsg_type; |
572 | uid_t loginuid; /* loginuid of sender */ | 577 | uid_t loginuid; /* loginuid of sender */ |
578 | u32 sessionid; | ||
573 | struct audit_sig_info *sig_data; | 579 | struct audit_sig_info *sig_data; |
574 | char *ctx = NULL; | 580 | char *ctx = NULL; |
575 | u32 len; | 581 | u32 len; |
@@ -591,6 +597,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
591 | pid = NETLINK_CREDS(skb)->pid; | 597 | pid = NETLINK_CREDS(skb)->pid; |
592 | uid = NETLINK_CREDS(skb)->uid; | 598 | uid = NETLINK_CREDS(skb)->uid; |
593 | loginuid = NETLINK_CB(skb).loginuid; | 599 | loginuid = NETLINK_CB(skb).loginuid; |
600 | sessionid = NETLINK_CB(skb).sessionid; | ||
594 | sid = NETLINK_CB(skb).sid; | 601 | sid = NETLINK_CB(skb).sid; |
595 | seq = nlh->nlmsg_seq; | 602 | seq = nlh->nlmsg_seq; |
596 | data = NLMSG_DATA(nlh); | 603 | data = NLMSG_DATA(nlh); |
@@ -613,12 +620,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
613 | status_get = (struct audit_status *)data; | 620 | status_get = (struct audit_status *)data; |
614 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 621 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
615 | err = audit_set_enabled(status_get->enabled, | 622 | err = audit_set_enabled(status_get->enabled, |
616 | loginuid, sid); | 623 | loginuid, sessionid, sid); |
617 | if (err < 0) return err; | 624 | if (err < 0) return err; |
618 | } | 625 | } |
619 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 626 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
620 | err = audit_set_failure(status_get->failure, | 627 | err = audit_set_failure(status_get->failure, |
621 | loginuid, sid); | 628 | loginuid, sessionid, sid); |
622 | if (err < 0) return err; | 629 | if (err < 0) return err; |
623 | } | 630 | } |
624 | if (status_get->mask & AUDIT_STATUS_PID) { | 631 | if (status_get->mask & AUDIT_STATUS_PID) { |
@@ -627,17 +634,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
627 | if (audit_enabled != AUDIT_OFF) | 634 | if (audit_enabled != AUDIT_OFF) |
628 | audit_log_config_change("audit_pid", new_pid, | 635 | audit_log_config_change("audit_pid", new_pid, |
629 | audit_pid, loginuid, | 636 | audit_pid, loginuid, |
630 | sid, 1); | 637 | sessionid, sid, 1); |
631 | 638 | ||
632 | audit_pid = new_pid; | 639 | audit_pid = new_pid; |
633 | audit_nlk_pid = NETLINK_CB(skb).pid; | 640 | audit_nlk_pid = NETLINK_CB(skb).pid; |
634 | } | 641 | } |
635 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 642 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
636 | err = audit_set_rate_limit(status_get->rate_limit, | 643 | err = audit_set_rate_limit(status_get->rate_limit, |
637 | loginuid, sid); | 644 | loginuid, sessionid, sid); |
638 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 645 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
639 | err = audit_set_backlog_limit(status_get->backlog_limit, | 646 | err = audit_set_backlog_limit(status_get->backlog_limit, |
640 | loginuid, sid); | 647 | loginuid, sessionid, sid); |
641 | break; | 648 | break; |
642 | case AUDIT_USER: | 649 | case AUDIT_USER: |
643 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 650 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
@@ -649,12 +656,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
649 | if (err == 1) { | 656 | if (err == 1) { |
650 | err = 0; | 657 | err = 0; |
651 | if (msg_type == AUDIT_USER_TTY) { | 658 | if (msg_type == AUDIT_USER_TTY) { |
652 | err = audit_prepare_user_tty(pid, loginuid); | 659 | err = audit_prepare_user_tty(pid, loginuid, |
660 | sessionid); | ||
653 | if (err) | 661 | if (err) |
654 | break; | 662 | break; |
655 | } | 663 | } |
656 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, | 664 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, |
657 | loginuid, sid); | 665 | loginuid, sessionid, sid); |
658 | 666 | ||
659 | if (msg_type != AUDIT_USER_TTY) | 667 | if (msg_type != AUDIT_USER_TTY) |
660 | audit_log_format(ab, " msg='%.1024s'", | 668 | audit_log_format(ab, " msg='%.1024s'", |
@@ -677,7 +685,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
677 | return -EINVAL; | 685 | return -EINVAL; |
678 | if (audit_enabled == AUDIT_LOCKED) { | 686 | if (audit_enabled == AUDIT_LOCKED) { |
679 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 687 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
680 | uid, loginuid, sid); | 688 | uid, loginuid, sessionid, sid); |
681 | 689 | ||
682 | audit_log_format(ab, " audit_enabled=%d res=0", | 690 | audit_log_format(ab, " audit_enabled=%d res=0", |
683 | audit_enabled); | 691 | audit_enabled); |
@@ -688,7 +696,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
688 | case AUDIT_LIST: | 696 | case AUDIT_LIST: |
689 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 697 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
690 | uid, seq, data, nlmsg_len(nlh), | 698 | uid, seq, data, nlmsg_len(nlh), |
691 | loginuid, sid); | 699 | loginuid, sessionid, sid); |
692 | break; | 700 | break; |
693 | case AUDIT_ADD_RULE: | 701 | case AUDIT_ADD_RULE: |
694 | case AUDIT_DEL_RULE: | 702 | case AUDIT_DEL_RULE: |
@@ -696,7 +704,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
696 | return -EINVAL; | 704 | return -EINVAL; |
697 | if (audit_enabled == AUDIT_LOCKED) { | 705 | if (audit_enabled == AUDIT_LOCKED) { |
698 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 706 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
699 | uid, loginuid, sid); | 707 | uid, loginuid, sessionid, sid); |
700 | 708 | ||
701 | audit_log_format(ab, " audit_enabled=%d res=0", | 709 | audit_log_format(ab, " audit_enabled=%d res=0", |
702 | audit_enabled); | 710 | audit_enabled); |
@@ -707,13 +715,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
707 | case AUDIT_LIST_RULES: | 715 | case AUDIT_LIST_RULES: |
708 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 716 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
709 | uid, seq, data, nlmsg_len(nlh), | 717 | uid, seq, data, nlmsg_len(nlh), |
710 | loginuid, sid); | 718 | loginuid, sessionid, sid); |
711 | break; | 719 | break; |
712 | case AUDIT_TRIM: | 720 | case AUDIT_TRIM: |
713 | audit_trim_trees(); | 721 | audit_trim_trees(); |
714 | 722 | ||
715 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 723 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
716 | uid, loginuid, sid); | 724 | uid, loginuid, sessionid, sid); |
717 | 725 | ||
718 | audit_log_format(ab, " op=trim res=1"); | 726 | audit_log_format(ab, " op=trim res=1"); |
719 | audit_log_end(ab); | 727 | audit_log_end(ab); |
@@ -745,7 +753,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
745 | err = audit_tag_tree(old, new); | 753 | err = audit_tag_tree(old, new); |
746 | 754 | ||
747 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 755 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
748 | uid, loginuid, sid); | 756 | uid, loginuid, sessionid, sid); |
749 | 757 | ||
750 | audit_log_format(ab, " op=make_equiv old="); | 758 | audit_log_format(ab, " op=make_equiv old="); |
751 | audit_log_untrustedstring(ab, old); | 759 | audit_log_untrustedstring(ab, old); |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 28fef6bf8534..af3ae91c47b1 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -1500,8 +1500,9 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
1500 | } | 1500 | } |
1501 | 1501 | ||
1502 | /* Log rule additions and removals */ | 1502 | /* Log rule additions and removals */ |
1503 | static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | 1503 | static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, |
1504 | struct audit_krule *rule, int res) | 1504 | char *action, struct audit_krule *rule, |
1505 | int res) | ||
1505 | { | 1506 | { |
1506 | struct audit_buffer *ab; | 1507 | struct audit_buffer *ab; |
1507 | 1508 | ||
@@ -1511,7 +1512,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
1511 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 1512 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
1512 | if (!ab) | 1513 | if (!ab) |
1513 | return; | 1514 | return; |
1514 | audit_log_format(ab, "auid=%u", loginuid); | 1515 | audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid); |
1515 | if (sid) { | 1516 | if (sid) { |
1516 | char *ctx = NULL; | 1517 | char *ctx = NULL; |
1517 | u32 len; | 1518 | u32 len; |
@@ -1543,7 +1544,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
1543 | * @sid: SE Linux Security ID of sender | 1544 | * @sid: SE Linux Security ID of sender |
1544 | */ | 1545 | */ |
1545 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 1546 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
1546 | size_t datasz, uid_t loginuid, u32 sid) | 1547 | size_t datasz, uid_t loginuid, u32 sessionid, u32 sid) |
1547 | { | 1548 | { |
1548 | struct task_struct *tsk; | 1549 | struct task_struct *tsk; |
1549 | struct audit_netlink_list *dest; | 1550 | struct audit_netlink_list *dest; |
@@ -1590,7 +1591,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1590 | 1591 | ||
1591 | err = audit_add_rule(entry, | 1592 | err = audit_add_rule(entry, |
1592 | &audit_filter_list[entry->rule.listnr]); | 1593 | &audit_filter_list[entry->rule.listnr]); |
1593 | audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err); | 1594 | audit_log_rule_change(loginuid, sessionid, sid, "add", |
1595 | &entry->rule, !err); | ||
1594 | 1596 | ||
1595 | if (err) | 1597 | if (err) |
1596 | audit_free_rule(entry); | 1598 | audit_free_rule(entry); |
@@ -1606,8 +1608,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1606 | 1608 | ||
1607 | err = audit_del_rule(entry, | 1609 | err = audit_del_rule(entry, |
1608 | &audit_filter_list[entry->rule.listnr]); | 1610 | &audit_filter_list[entry->rule.listnr]); |
1609 | audit_log_rule_change(loginuid, sid, "remove", &entry->rule, | 1611 | audit_log_rule_change(loginuid, sessionid, sid, "remove", |
1610 | !err); | 1612 | &entry->rule, !err); |
1611 | 1613 | ||
1612 | audit_free_rule(entry); | 1614 | audit_free_rule(entry); |
1613 | break; | 1615 | break; |