Commit 6f285b19 authored by Eric W. Biederman's avatar Eric W. Biederman

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: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 48095d99
...@@ -43,6 +43,7 @@ struct mq_attr; ...@@ -43,6 +43,7 @@ struct mq_attr;
struct mqstat; struct mqstat;
struct audit_watch; struct audit_watch;
struct audit_tree; struct audit_tree;
struct sk_buff;
struct audit_krule { struct audit_krule {
int vers_ops; int vers_ops;
...@@ -463,7 +464,7 @@ extern int audit_filter_user(int type); ...@@ -463,7 +464,7 @@ extern int audit_filter_user(int type);
extern int audit_filter_type(int type); extern int audit_filter_type(int type);
extern int audit_rule_change(int type, __u32 portid, int seq, extern int audit_rule_change(int type, __u32 portid, int seq,
void *data, size_t datasz); void *data, size_t datasz);
extern int audit_list_rules_send(__u32 portid, int seq); extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
extern u32 audit_enabled; extern u32 audit_enabled;
#else /* CONFIG_AUDIT */ #else /* CONFIG_AUDIT */
......
...@@ -570,9 +570,11 @@ static int audit_send_reply_thread(void *arg) ...@@ -570,9 +570,11 @@ static int audit_send_reply_thread(void *arg)
* Allocates an skb, builds the netlink message, and sends it to the port id. * Allocates an skb, builds the netlink message, and sends it to the port id.
* No failure notifications. * No failure notifications.
*/ */
static void audit_send_reply(__u32 portid, int seq, int type, int done, static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
int multi, const void *payload, int size) int multi, const void *payload, int size)
{ {
u32 portid = NETLINK_CB(request_skb).portid;
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
struct sk_buff *skb; struct sk_buff *skb;
struct task_struct *tsk; struct task_struct *tsk;
struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), 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,7 +587,7 @@ static void audit_send_reply(__u32 portid, int seq, int type, int done,
if (!skb) if (!skb)
goto out; goto out;
reply->net = get_net(current->nsproxy->net_ns); reply->net = get_net(net);
reply->portid = portid; reply->portid = portid;
reply->skb = skb; reply->skb = skb;
...@@ -675,8 +677,7 @@ static int audit_get_feature(struct sk_buff *skb) ...@@ -675,8 +677,7 @@ static int audit_get_feature(struct sk_buff *skb)
seq = nlmsg_hdr(skb)->nlmsg_seq; seq = nlmsg_hdr(skb)->nlmsg_seq;
audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af));
&af, sizeof(af));
return 0; return 0;
} }
...@@ -796,8 +797,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -796,8 +797,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
s.backlog = skb_queue_len(&audit_skb_queue); s.backlog = skb_queue_len(&audit_skb_queue);
s.version = AUDIT_VERSION_LATEST; s.version = AUDIT_VERSION_LATEST;
s.backlog_wait_time = audit_backlog_wait_time; s.backlog_wait_time = audit_backlog_wait_time;
audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
&s, sizeof(s));
break; break;
} }
case AUDIT_SET: { case AUDIT_SET: {
...@@ -907,7 +907,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -907,7 +907,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
seq, data, nlmsg_len(nlh)); seq, data, nlmsg_len(nlh));
break; break;
case AUDIT_LIST_RULES: case AUDIT_LIST_RULES:
err = audit_list_rules_send(NETLINK_CB(skb).portid, seq); err = audit_list_rules_send(skb, seq);
break; break;
case AUDIT_TRIM: case AUDIT_TRIM:
audit_trim_trees(); audit_trim_trees();
...@@ -972,8 +972,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -972,8 +972,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
memcpy(sig_data->ctx, ctx, len); memcpy(sig_data->ctx, ctx, len);
security_release_secctx(ctx, len); security_release_secctx(ctx, len);
} }
audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_SIGNAL_INFO, audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
0, 0, sig_data, sizeof(*sig_data) + len); sig_data, sizeof(*sig_data) + len);
kfree(sig_data); kfree(sig_data);
break; break;
case AUDIT_TTY_GET: { case AUDIT_TTY_GET: {
...@@ -985,8 +985,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -985,8 +985,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
s.log_passwd = tsk->signal->audit_tty_log_passwd; s.log_passwd = tsk->signal->audit_tty_log_passwd;
spin_unlock(&tsk->sighand->siglock); spin_unlock(&tsk->sighand->siglock);
audit_send_reply(NETLINK_CB(skb).portid, seq, audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
break; break;
} }
case AUDIT_TTY_SET: { case AUDIT_TTY_SET: {
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/security.h> #include <linux/security.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/sock.h>
#include "audit.h" #include "audit.h"
/* /*
...@@ -1069,8 +1070,10 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, ...@@ -1069,8 +1070,10 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,
* @portid: target portid for netlink audit messages * @portid: target portid for netlink audit messages
* @seq: netlink audit message sequence (serial) number * @seq: netlink audit message sequence (serial) number
*/ */
int audit_list_rules_send(__u32 portid, int seq) int audit_list_rules_send(struct sk_buff *request_skb, int seq)
{ {
u32 portid = NETLINK_CB(request_skb).portid;
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
struct task_struct *tsk; struct task_struct *tsk;
struct audit_netlink_list *dest; struct audit_netlink_list *dest;
int err = 0; int err = 0;
...@@ -1084,7 +1087,7 @@ int audit_list_rules_send(__u32 portid, int seq) ...@@ -1084,7 +1087,7 @@ int audit_list_rules_send(__u32 portid, int seq)
dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
if (!dest) if (!dest)
return -ENOMEM; return -ENOMEM;
dest->net = get_net(current->nsproxy->net_ns); dest->net = get_net(net);
dest->portid = portid; dest->portid = portid;
skb_queue_head_init(&dest->q); skb_queue_head_init(&dest->q);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment