Commit 099dd235113700bbb476e572cd191ddb77b9af46
Committed by
Eric Paris
1 parent
638a0fd2a0
Exists in
master
and in
13 other branches
audit: Send replies in the proper network namespace.
In perverse cases of file descriptor passing the current network namespace of a process and the network namespace of a socket used by that socket may differ. Therefore use the network namespace of the appropiate socket to ensure replies always go to the appropiate socket. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: Richard Guy Briggs <rgb@redhat.com> Signed-off-by: Eric Paris <eparis@redhat.com>
Showing 3 changed files with 17 additions and 14 deletions Side-by-side Diff
include/linux/audit.h
... | ... | @@ -43,6 +43,7 @@ |
43 | 43 | struct mqstat; |
44 | 44 | struct audit_watch; |
45 | 45 | struct audit_tree; |
46 | +struct sk_buff; | |
46 | 47 | |
47 | 48 | struct audit_krule { |
48 | 49 | int vers_ops; |
... | ... | @@ -463,7 +464,7 @@ |
463 | 464 | extern int audit_filter_type(int type); |
464 | 465 | extern int audit_rule_change(int type, __u32 portid, int seq, |
465 | 466 | void *data, size_t datasz); |
466 | -extern int audit_list_rules_send(__u32 portid, int seq); | |
467 | +extern int audit_list_rules_send(struct sk_buff *request_skb, int seq); | |
467 | 468 | |
468 | 469 | extern u32 audit_enabled; |
469 | 470 | #else /* CONFIG_AUDIT */ |
kernel/audit.c
... | ... | @@ -570,9 +570,11 @@ |
570 | 570 | * Allocates an skb, builds the netlink message, and sends it to the port id. |
571 | 571 | * No failure notifications. |
572 | 572 | */ |
573 | -static void audit_send_reply(__u32 portid, int seq, int type, int done, | |
573 | +static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done, | |
574 | 574 | int multi, const void *payload, int size) |
575 | 575 | { |
576 | + u32 portid = NETLINK_CB(request_skb).portid; | |
577 | + struct net *net = sock_net(NETLINK_CB(request_skb).sk); | |
576 | 578 | struct sk_buff *skb; |
577 | 579 | struct task_struct *tsk; |
578 | 580 | struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), |
... | ... | @@ -585,7 +587,7 @@ |
585 | 587 | if (!skb) |
586 | 588 | goto out; |
587 | 589 | |
588 | - reply->net = get_net(current->nsproxy->net_ns); | |
590 | + reply->net = get_net(net); | |
589 | 591 | reply->portid = portid; |
590 | 592 | reply->skb = skb; |
591 | 593 | |
... | ... | @@ -675,8 +677,7 @@ |
675 | 677 | |
676 | 678 | seq = nlmsg_hdr(skb)->nlmsg_seq; |
677 | 679 | |
678 | - audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | |
679 | - &af, sizeof(af)); | |
680 | + audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af)); | |
680 | 681 | |
681 | 682 | return 0; |
682 | 683 | } |
... | ... | @@ -796,8 +797,7 @@ |
796 | 797 | s.backlog = skb_queue_len(&audit_skb_queue); |
797 | 798 | s.version = AUDIT_VERSION_LATEST; |
798 | 799 | s.backlog_wait_time = audit_backlog_wait_time; |
799 | - audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | |
800 | - &s, sizeof(s)); | |
800 | + audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s)); | |
801 | 801 | break; |
802 | 802 | } |
803 | 803 | case AUDIT_SET: { |
... | ... | @@ -907,7 +907,7 @@ |
907 | 907 | seq, data, nlmsg_len(nlh)); |
908 | 908 | break; |
909 | 909 | case AUDIT_LIST_RULES: |
910 | - err = audit_list_rules_send(NETLINK_CB(skb).portid, seq); | |
910 | + err = audit_list_rules_send(skb, seq); | |
911 | 911 | break; |
912 | 912 | case AUDIT_TRIM: |
913 | 913 | audit_trim_trees(); |
... | ... | @@ -972,8 +972,8 @@ |
972 | 972 | memcpy(sig_data->ctx, ctx, len); |
973 | 973 | security_release_secctx(ctx, len); |
974 | 974 | } |
975 | - audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_SIGNAL_INFO, | |
976 | - 0, 0, sig_data, sizeof(*sig_data) + len); | |
975 | + audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, | |
976 | + sig_data, sizeof(*sig_data) + len); | |
977 | 977 | kfree(sig_data); |
978 | 978 | break; |
979 | 979 | case AUDIT_TTY_GET: { |
... | ... | @@ -985,8 +985,7 @@ |
985 | 985 | s.log_passwd = tsk->signal->audit_tty_log_passwd; |
986 | 986 | spin_unlock(&tsk->sighand->siglock); |
987 | 987 | |
988 | - audit_send_reply(NETLINK_CB(skb).portid, seq, | |
989 | - AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); | |
988 | + audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); | |
990 | 989 | break; |
991 | 990 | } |
992 | 991 | case AUDIT_TTY_SET: { |
kernel/auditfilter.c
... | ... | @@ -32,6 +32,7 @@ |
32 | 32 | #include <linux/slab.h> |
33 | 33 | #include <linux/security.h> |
34 | 34 | #include <net/net_namespace.h> |
35 | +#include <net/sock.h> | |
35 | 36 | #include "audit.h" |
36 | 37 | |
37 | 38 | /* |
38 | 39 | |
... | ... | @@ -1071,8 +1072,10 @@ |
1071 | 1072 | * @portid: target portid for netlink audit messages |
1072 | 1073 | * @seq: netlink audit message sequence (serial) number |
1073 | 1074 | */ |
1074 | -int audit_list_rules_send(__u32 portid, int seq) | |
1075 | +int audit_list_rules_send(struct sk_buff *request_skb, int seq) | |
1075 | 1076 | { |
1077 | + u32 portid = NETLINK_CB(request_skb).portid; | |
1078 | + struct net *net = sock_net(NETLINK_CB(request_skb).sk); | |
1076 | 1079 | struct task_struct *tsk; |
1077 | 1080 | struct audit_netlink_list *dest; |
1078 | 1081 | int err = 0; |
... | ... | @@ -1086,7 +1089,7 @@ |
1086 | 1089 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); |
1087 | 1090 | if (!dest) |
1088 | 1091 | return -ENOMEM; |
1089 | - dest->net = get_net(current->nsproxy->net_ns); | |
1092 | + dest->net = get_net(net); | |
1090 | 1093 | dest->portid = portid; |
1091 | 1094 | skb_queue_head_init(&dest->q); |
1092 | 1095 |