diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2014-02-28 23:36:55 -0500 |
|---|---|---|
| committer | Eric Paris <eparis@redhat.com> | 2014-03-20 10:11:02 -0400 |
| commit | 099dd235113700bbb476e572cd191ddb77b9af46 (patch) | |
| tree | 7f8137af9685dbe6c2ddbd686feaf13808ab7d2c /kernel | |
| parent | 638a0fd2a062568c568661be0a780be8e8836d03 (diff) | |
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>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/audit.c | 21 | ||||
| -rw-r--r-- | kernel/auditfilter.c | 7 |
2 files changed, 15 insertions, 13 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 71fb41f393d7..7b44bd47759c 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -570,9 +570,11 @@ static int audit_send_reply_thread(void *arg) | |||
| 570 | * Allocates an skb, builds the netlink message, and sends it to the port id. | 570 | * Allocates an skb, builds the netlink message, and sends it to the port id. |
| 571 | * No failure notifications. | 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 | int multi, const void *payload, int size) | 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 | struct sk_buff *skb; | 578 | struct sk_buff *skb; |
| 577 | struct task_struct *tsk; | 579 | struct task_struct *tsk; |
| 578 | struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), | 580 | struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), |
| @@ -585,7 +587,7 @@ static void audit_send_reply(__u32 portid, int seq, int type, int done, | |||
| 585 | if (!skb) | 587 | if (!skb) |
| 586 | goto out; | 588 | goto out; |
| 587 | 589 | ||
| 588 | reply->net = get_net(current->nsproxy->net_ns); | 590 | reply->net = get_net(net); |
| 589 | reply->portid = portid; | 591 | reply->portid = portid; |
| 590 | reply->skb = skb; | 592 | reply->skb = skb; |
| 591 | 593 | ||
| @@ -675,8 +677,7 @@ static int audit_get_feature(struct sk_buff *skb) | |||
| 675 | 677 | ||
| 676 | seq = nlmsg_hdr(skb)->nlmsg_seq; | 678 | seq = nlmsg_hdr(skb)->nlmsg_seq; |
| 677 | 679 | ||
| 678 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | 680 | audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af)); |
| 679 | &af, sizeof(af)); | ||
| 680 | 681 | ||
| 681 | return 0; | 682 | return 0; |
| 682 | } | 683 | } |
| @@ -796,8 +797,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 796 | s.backlog = skb_queue_len(&audit_skb_queue); | 797 | s.backlog = skb_queue_len(&audit_skb_queue); |
| 797 | s.version = AUDIT_VERSION_LATEST; | 798 | s.version = AUDIT_VERSION_LATEST; |
| 798 | s.backlog_wait_time = audit_backlog_wait_time; | 799 | s.backlog_wait_time = audit_backlog_wait_time; |
| 799 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | 800 | audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s)); |
| 800 | &s, sizeof(s)); | ||
| 801 | break; | 801 | break; |
| 802 | } | 802 | } |
| 803 | case AUDIT_SET: { | 803 | case AUDIT_SET: { |
| @@ -907,7 +907,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 907 | seq, data, nlmsg_len(nlh)); | 907 | seq, data, nlmsg_len(nlh)); |
| 908 | break; | 908 | break; |
| 909 | case AUDIT_LIST_RULES: | 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 | break; | 911 | break; |
| 912 | case AUDIT_TRIM: | 912 | case AUDIT_TRIM: |
| 913 | audit_trim_trees(); | 913 | audit_trim_trees(); |
| @@ -972,8 +972,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 972 | memcpy(sig_data->ctx, ctx, len); | 972 | memcpy(sig_data->ctx, ctx, len); |
| 973 | security_release_secctx(ctx, len); | 973 | security_release_secctx(ctx, len); |
| 974 | } | 974 | } |
| 975 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_SIGNAL_INFO, | 975 | audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, |
| 976 | 0, 0, sig_data, sizeof(*sig_data) + len); | 976 | sig_data, sizeof(*sig_data) + len); |
| 977 | kfree(sig_data); | 977 | kfree(sig_data); |
| 978 | break; | 978 | break; |
| 979 | case AUDIT_TTY_GET: { | 979 | case AUDIT_TTY_GET: { |
| @@ -985,8 +985,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 985 | s.log_passwd = tsk->signal->audit_tty_log_passwd; | 985 | s.log_passwd = tsk->signal->audit_tty_log_passwd; |
| 986 | spin_unlock(&tsk->sighand->siglock); | 986 | spin_unlock(&tsk->sighand->siglock); |
| 987 | 987 | ||
| 988 | audit_send_reply(NETLINK_CB(skb).portid, seq, | 988 | audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); |
| 989 | AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); | ||
| 990 | break; | 989 | break; |
| 991 | } | 990 | } |
| 992 | case AUDIT_TTY_SET: { | 991 | case AUDIT_TTY_SET: { |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index a0d470131fd0..549bbb6e6597 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/security.h> | 33 | #include <linux/security.h> |
| 34 | #include <net/net_namespace.h> | 34 | #include <net/net_namespace.h> |
| 35 | #include <net/sock.h> | ||
| 35 | #include "audit.h" | 36 | #include "audit.h" |
| 36 | 37 | ||
| 37 | /* | 38 | /* |
| @@ -1071,8 +1072,10 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, | |||
| 1071 | * @portid: target portid for netlink audit messages | 1072 | * @portid: target portid for netlink audit messages |
| 1072 | * @seq: netlink audit message sequence (serial) number | 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 | struct task_struct *tsk; | 1079 | struct task_struct *tsk; |
| 1077 | struct audit_netlink_list *dest; | 1080 | struct audit_netlink_list *dest; |
| 1078 | int err = 0; | 1081 | int err = 0; |
| @@ -1086,7 +1089,7 @@ int audit_list_rules_send(__u32 portid, int seq) | |||
| 1086 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | 1089 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); |
| 1087 | if (!dest) | 1090 | if (!dest) |
| 1088 | return -ENOMEM; | 1091 | return -ENOMEM; |
| 1089 | dest->net = get_net(current->nsproxy->net_ns); | 1092 | dest->net = get_net(net); |
| 1090 | dest->portid = portid; | 1093 | dest->portid = portid; |
| 1091 | skb_queue_head_init(&dest->q); | 1094 | skb_queue_head_init(&dest->q); |
| 1092 | 1095 | ||
