* [PATCH RFC 01/48] Audit: make audit kernel side netlink sock per userns
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 02/48] netlink: Add compare function for netlink_table Gao feng
` (32 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This patch try to make the audit_sock per user namespace,
not global.
Since sock is assigned to net namespace, when creating
a netns, we will allocate a audit_sock for the userns
which create this netns, and this netns will keep alive
until the creator userns being destroyed.
If userns create many netns, the audit_sock is only
allocated once.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/audit.h | 5 +++
include/linux/user_namespace.h | 9 ++++++
kernel/audit.c | 73 ++++++++++++++++++++++++++++++++++--------
kernel/user_namespace.c | 2 ++
4 files changed, 75 insertions(+), 14 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 5a6d718..690d7d8 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -429,6 +429,8 @@ static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
#endif
+extern void audit_free_user_ns(struct user_namespace *ns);
+
extern int audit_update_lsm_rules(void);
/* Private API (for audit.c only) */
@@ -476,6 +478,9 @@ static inline void audit_log_link_denied(const char *string,
{ }
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
+
+static inline void audit_free_user_ns(struct user_namespace *ns)
+{ }
#define audit_enabled 0
#endif /* CONFIG_AUDIT */
static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index b6b215f..8797421 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -17,6 +17,12 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
} extent[UID_GID_MAP_MAX_EXTENTS];
};
+#ifdef CONFIG_AUDIT
+struct audit_ctrl {
+ struct sock *sock;
+};
+#endif
+
struct user_namespace {
struct uid_gid_map uid_map;
struct uid_gid_map gid_map;
@@ -26,6 +32,9 @@ struct user_namespace {
kuid_t owner;
kgid_t group;
unsigned int proc_inum;
+#ifdef CONFIG_AUDIT
+ struct audit_ctrl audit;
+#endif
bool may_mount_sysfs;
bool may_mount_proc;
};
diff --git a/kernel/audit.c b/kernel/audit.c
index 0b084fa..766dcbf 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -62,6 +62,7 @@
#include <linux/freezer.h>
#include <linux/tty.h>
#include <linux/pid_namespace.h>
+#include <linux/user_namespace.h>
#include "audit.h"
@@ -118,9 +119,6 @@ u32 audit_sig_sid = 0;
*/
static atomic_t audit_lost = ATOMIC_INIT(0);
-/* The netlink socket. */
-static struct sock *audit_sock;
-
/* Hash for inode-based rules */
struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@ -404,7 +402,8 @@ static void kauditd_send_skb(struct sk_buff *skb)
int err;
/* take a reference in case we can't send it and we want to hold it */
skb_get(skb);
- err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
+ err = netlink_unicast(init_user_ns.audit.sock, skb,
+ audit_nlk_portid, 0);
if (err < 0) {
BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
@@ -481,7 +480,7 @@ int audit_send_list(void *_dest)
mutex_unlock(&audit_cmd_mutex);
while ((skb = __skb_dequeue(&dest->q)) != NULL)
- netlink_unicast(audit_sock, skb, pid, 0);
+ netlink_unicast(init_user_ns.audit.sock, skb, pid, 0);
kfree(dest);
@@ -522,7 +521,8 @@ static int audit_send_reply_thread(void *arg)
/* Ignore failure. It'll only happen if the sender goes away,
because our timeout is set to infinite. */
- netlink_unicast(audit_sock, reply->skb, reply->pid, 0);
+ netlink_unicast(init_user_ns.audit.sock, reply->skb,
+ reply->pid, 0);
kfree(reply);
return 0;
}
@@ -937,24 +937,56 @@ static void audit_receive(struct sk_buff *skb)
mutex_unlock(&audit_cmd_mutex);
}
+static int __net_init audit_net_init(struct net *net)
+{
+ struct user_namespace *ns = net->user_ns;
+
+ if (!ns->audit.sock) {
+ struct sock *sk = NULL;
+ /*
+ * create kernel side netlink socket for audit,
+ * make audit sock per user namespace.
+ */
+ struct netlink_kernel_cfg cfg = {
+ .input = audit_receive,
+ };
+
+ sk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
+ if (!sk) {
+ if (net_eq(net, &init_net))
+ audit_panic("cannot initialize netlink socket");
+ return -1;
+ }
+ sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+ ns->audit.sock = sk;
+ /*
+ * Get reference of net->passive, this force this netns
+ * to be alive, it will be destroyed when we destroy the
+ * userns.
+ */
+ atomic_inc(&net->passive);
+ }
+
+ return 0;
+}
+
+static struct pernet_operations audit_net_ops = {
+ .init = audit_net_init,
+};
+
/* Initialize audit support at boot time. */
static int __init audit_init(void)
{
int i;
- struct netlink_kernel_cfg cfg = {
- .input = audit_receive,
- };
if (audit_initialized == AUDIT_DISABLED)
return 0;
printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
audit_default ? "enabled" : "disabled");
- audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, &cfg);
- if (!audit_sock)
- audit_panic("cannot initialize netlink socket");
- else
- audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+
+ if (register_pernet_subsys(&audit_net_ops) < 0)
+ return -1;
skb_queue_head_init(&audit_skb_queue);
skb_queue_head_init(&audit_skb_hold_queue);
@@ -1549,7 +1581,20 @@ void audit_log_secctx(struct audit_buffer *ab, u32 secid)
EXPORT_SYMBOL(audit_log_secctx);
#endif
+void audit_free_user_ns(struct user_namespace *ns)
+{
+ if (audit_initialized == AUDIT_DISABLED)
+ return;
+
+ if (ns->audit.sock) {
+ struct net *net = sock_net(ns->audit.sock);
+ netlink_kernel_release(ns->audit.sock);
+ net_drop_ns(net);
+ }
+}
+
EXPORT_SYMBOL(audit_log_start);
EXPORT_SYMBOL(audit_log_end);
EXPORT_SYMBOL(audit_log_format);
EXPORT_SYMBOL(audit_log);
+EXPORT_SYMBOL(audit_free_user_ns);
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index d8c30db..99de920 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -22,6 +22,7 @@
#include <linux/ctype.h>
#include <linux/projid.h>
#include <linux/fs_struct.h>
+#include <linux/audit.h>
static struct kmem_cache *user_ns_cachep __read_mostly;
@@ -124,6 +125,7 @@ void free_user_ns(struct user_namespace *ns)
do {
parent = ns->parent;
proc_free_inum(ns->proc_inum);
+ audit_free_user_ns(ns);
kmem_cache_free(user_ns_cachep, ns);
ns = parent;
} while (atomic_dec_and_test(&parent->count));
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 02/48] netlink: Add compare function for netlink_table
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2013-05-07 2:20 ` [PATCH RFC 01/48] Audit: make audit kernel side netlink sock per userns Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 03/48] Audit: implement audit self-defined compare function Gao feng
` (31 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
As we know, netlink sockets can communicate with each other
only when they in the same net namespace. this works
well until we try to add namespace support for other
subsystems which use netlink.
Don't like ipv4,route table,it is not suited to make this
subsytems belongs to net namespace, Such as audit and crypto
subsystems,they are more suitable to user namespace.
So we must have the ability to make the netlink sockets in
same user namespace can communicate with each other.
This patch adds a new function pointer "compare" for
netlink_table, we can decide if the netlink sockets can
communicate with each other through this netlink_table
self-defined compare function.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/netlink.h | 1 +
net/netlink/af_netlink.c | 26 ++++++++++++++++++++------
net/netlink/af_netlink.h | 1 +
3 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 6358da5..f78b430 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -46,6 +46,7 @@ struct netlink_kernel_cfg {
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
void (*bind)(int group);
+ bool (*compare)(struct net *net, struct sock *sk);
};
extern struct sock *__netlink_kernel_create(struct net *net, int unit,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 12ac6b4..41cc3c8 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -854,16 +854,23 @@ netlink_unlock_table(void)
wake_up(&nl_table_wait);
}
+static bool netlink_compare(struct net *net, struct sock *sk)
+{
+ return net_eq(sock_net(sk), net);
+}
+
static struct sock *netlink_lookup(struct net *net, int protocol, u32 portid)
{
- struct nl_portid_hash *hash = &nl_table[protocol].hash;
+ struct netlink_table *table = &nl_table[protocol];
+ struct nl_portid_hash *hash = &table->hash;
struct hlist_head *head;
struct sock *sk;
read_lock(&nl_table_lock);
head = nl_portid_hashfn(hash, portid);
sk_for_each(sk, head) {
- if (net_eq(sock_net(sk), net) && (nlk_sk(sk)->portid == portid)) {
+ if (table->compare(net, sk) &&
+ (nlk_sk(sk)->portid == portid)) {
sock_hold(sk);
goto found;
}
@@ -976,7 +983,8 @@ netlink_update_listeners(struct sock *sk)
static int netlink_insert(struct sock *sk, struct net *net, u32 portid)
{
- struct nl_portid_hash *hash = &nl_table[sk->sk_protocol].hash;
+ struct netlink_table *table = &nl_table[sk->sk_protocol];
+ struct nl_portid_hash *hash = &table->hash;
struct hlist_head *head;
int err = -EADDRINUSE;
struct sock *osk;
@@ -986,7 +994,8 @@ static int netlink_insert(struct sock *sk, struct net *net, u32 portid)
head = nl_portid_hashfn(hash, portid);
len = 0;
sk_for_each(osk, head) {
- if (net_eq(sock_net(osk), net) && (nlk_sk(osk)->portid == portid))
+ if (table->compare(net, osk) &&
+ (nlk_sk(osk)->portid == portid))
break;
len++;
}
@@ -1161,6 +1170,7 @@ static int netlink_release(struct socket *sock)
kfree_rcu(old, rcu);
nl_table[sk->sk_protocol].module = NULL;
nl_table[sk->sk_protocol].bind = NULL;
+ nl_table[sk->sk_protocol].compare = NULL;
nl_table[sk->sk_protocol].flags = 0;
nl_table[sk->sk_protocol].registered = 0;
}
@@ -1183,7 +1193,8 @@ static int netlink_autobind(struct socket *sock)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
- struct nl_portid_hash *hash = &nl_table[sk->sk_protocol].hash;
+ struct netlink_table *table = &nl_table[sk->sk_protocol];
+ struct nl_portid_hash *hash = &table->hash;
struct hlist_head *head;
struct sock *osk;
s32 portid = task_tgid_vnr(current);
@@ -1195,7 +1206,7 @@ retry:
netlink_table_grab();
head = nl_portid_hashfn(hash, portid);
sk_for_each(osk, head) {
- if (!net_eq(sock_net(osk), net))
+ if (!table->compare(net, osk))
continue;
if (nlk_sk(osk)->portid == portid) {
/* Bind collision, search negative portid values. */
@@ -2282,9 +2293,12 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
rcu_assign_pointer(nl_table[unit].listeners, listeners);
nl_table[unit].cb_mutex = cb_mutex;
nl_table[unit].module = module;
+ nl_table[unit].compare = netlink_compare;
if (cfg) {
nl_table[unit].bind = cfg->bind;
nl_table[unit].flags = cfg->flags;
+ if (cfg->compare)
+ nl_table[unit].compare = cfg->compare;
}
nl_table[unit].registered = 1;
} else {
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index ed85222..eaa88d1 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -73,6 +73,7 @@ struct netlink_table {
struct mutex *cb_mutex;
struct module *module;
void (*bind)(int group);
+ bool (*compare)(struct net *net, struct sock *sock);
int registered;
};
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 03/48] Audit: implement audit self-defined compare function
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2013-05-07 2:20 ` [PATCH RFC 01/48] Audit: make audit kernel side netlink sock per userns Gao feng
2013-05-07 2:20 ` [PATCH RFC 02/48] netlink: Add compare function for netlink_table Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 04/48] Audit: make audit_skb_queue per user namespace Gao feng
` (30 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
After this patch, audit netlink sockets can
communicate with each other when they belong
to the same user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/kernel/audit.c b/kernel/audit.c
index 766dcbf..3ae8793 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -937,6 +937,11 @@ static void audit_receive(struct sk_buff *skb)
mutex_unlock(&audit_cmd_mutex);
}
+static bool audit_compare(struct net *net, struct sock *sk)
+{
+ return (sock_net(sk)->user_ns == net->user_ns);
+}
+
static int __net_init audit_net_init(struct net *net)
{
struct user_namespace *ns = net->user_ns;
@@ -949,6 +954,7 @@ static int __net_init audit_net_init(struct net *net)
*/
struct netlink_kernel_cfg cfg = {
.input = audit_receive,
+ .compare = audit_compare,
};
sk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 04/48] Audit: make audit_skb_queue per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (2 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 03/48] Audit: implement audit self-defined compare function Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 05/48] Audit: make audit_skb_hold_queue " Gao feng
` (29 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
After this patch, ervery user namespace has one
audit_skb_queue. Since we havn't finish the preparations,
only allow user to operate the skb queue of init user
namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/audit.h | 4 ++++
include/linux/user_namespace.h | 2 ++
kernel/audit.c | 35 ++++++++++++++++++++++++++---------
kernel/user_namespace.c | 1 +
4 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 690d7d8..78f51ae 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -429,6 +429,7 @@ static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
#endif
+extern void audit_set_user_ns(struct user_namespace *ns);
extern void audit_free_user_ns(struct user_namespace *ns);
extern int audit_update_lsm_rules(void);
@@ -479,6 +480,9 @@ static inline void audit_log_link_denied(const char *string,
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
+static inline void audit_set_user_ns(struct user_namespace *ns)
+{ }
+
static inline void audit_free_user_ns(struct user_namespace *ns)
{ }
#define audit_enabled 0
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 8797421..e322f20 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -5,6 +5,7 @@
#include <linux/nsproxy.h>
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/skbuff.h>
#define UID_GID_MAP_MAX_EXTENTS 5
@@ -20,6 +21,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
#ifdef CONFIG_AUDIT
struct audit_ctrl {
struct sock *sock;
+ struct sk_buff_head queue;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 3ae8793..2a727af 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -129,7 +129,6 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
static int audit_freelist_count;
static LIST_HEAD(audit_freelist);
-static struct sk_buff_head audit_skb_queue;
/* queue of skbs to send to auditd when/if it comes back */
static struct sk_buff_head audit_skb_hold_queue;
static struct task_struct *kauditd_task;
@@ -419,6 +418,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
static int kauditd_thread(void *dummy)
{
struct sk_buff *skb;
+ struct sk_buff_head *queue = &init_user_ns.audit.queue;
set_freezable();
while (!kthread_should_stop()) {
@@ -445,7 +445,7 @@ static int kauditd_thread(void *dummy)
}
}
- skb = skb_dequeue(&audit_skb_queue);
+ skb = skb_dequeue(queue);
wake_up(&audit_backlog_wait);
if (skb) {
if (audit_pid)
@@ -457,7 +457,7 @@ static int kauditd_thread(void *dummy)
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&kauditd_wait, &wait);
- if (!skb_queue_len(&audit_skb_queue)) {
+ if (!skb_queue_len(queue)) {
try_to_freeze();
schedule();
}
@@ -653,11 +653,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct audit_sig_info *sig_data;
char *ctx = NULL;
u32 len;
+ struct user_namespace *ns;
err = audit_netlink_ok(skb, msg_type);
if (err)
return err;
+ ns = current_user_ns();
/* As soon as there's any sign of userspace auditd,
* start kauditd to talk to it */
if (!kauditd_task) {
@@ -682,7 +684,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
status_set.rate_limit = audit_rate_limit;
status_set.backlog_limit = audit_backlog_limit;
status_set.lost = atomic_read(&audit_lost);
- status_set.backlog = skb_queue_len(&audit_skb_queue);
+ status_set.backlog =
+ skb_queue_len(&ns->audit.queue);
audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0,
&status_set, sizeof(status_set));
break;
@@ -994,7 +997,7 @@ static int __init audit_init(void)
if (register_pernet_subsys(&audit_net_ops) < 0)
return -1;
- skb_queue_head_init(&audit_skb_queue);
+ audit_set_user_ns(&init_user_ns);
skb_queue_head_init(&audit_skb_hold_queue);
audit_initialized = AUDIT_INITIALIZED;
audit_enabled = audit_default;
@@ -1144,12 +1147,13 @@ static inline void audit_get_stamp(struct audit_context *ctx,
*/
static void wait_for_auditd(unsigned long sleep_time)
{
+ const struct sk_buff_head *queue = &init_user_ns.audit.queue;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&audit_backlog_wait, &wait);
if (audit_backlog_limit &&
- skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
+ skb_queue_len(queue) > audit_backlog_limit)
schedule_timeout(sleep_time);
__set_current_state(TASK_RUNNING);
@@ -1186,6 +1190,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
unsigned int uninitialized_var(serial);
int reserve;
unsigned long timeout_start = jiffies;
+ struct sk_buff_head *queue = &init_user_ns.audit.queue;
if (audit_initialized != AUDIT_INITIALIZED)
return NULL;
@@ -1200,7 +1205,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
entries over the normal backlog limit */
while (audit_backlog_limit
- && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
+ && skb_queue_len(queue) > audit_backlog_limit + reserve) {
if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) {
unsigned long sleep_time;
@@ -1214,7 +1219,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
printk(KERN_WARNING
"audit: audit_backlog=%d > "
"audit_backlog_limit=%d\n",
- skb_queue_len(&audit_skb_queue),
+ skb_queue_len(queue),
audit_backlog_limit);
audit_log_lost("backlog limit exceeded");
audit_backlog_wait_time = audit_backlog_wait_overflow;
@@ -1524,7 +1529,8 @@ void audit_log_end(struct audit_buffer *ab)
nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
if (audit_pid) {
- skb_queue_tail(&audit_skb_queue, ab->skb);
+ skb_queue_tail(&init_user_ns.audit.queue,
+ ab->skb);
wake_up_interruptible(&kauditd_wait);
} else {
audit_printk_skb(ab->skb);
@@ -1587,6 +1593,14 @@ void audit_log_secctx(struct audit_buffer *ab, u32 secid)
EXPORT_SYMBOL(audit_log_secctx);
#endif
+void audit_set_user_ns(struct user_namespace *ns)
+{
+ if (audit_initialized == AUDIT_DISABLED)
+ return;
+
+ skb_queue_head_init(&ns->audit.queue);
+}
+
void audit_free_user_ns(struct user_namespace *ns)
{
if (audit_initialized == AUDIT_DISABLED)
@@ -1597,10 +1611,13 @@ void audit_free_user_ns(struct user_namespace *ns)
netlink_kernel_release(ns->audit.sock);
net_drop_ns(net);
}
+
+ skb_queue_purge(&ns->audit.queue);
}
EXPORT_SYMBOL(audit_log_start);
EXPORT_SYMBOL(audit_log_end);
EXPORT_SYMBOL(audit_log_format);
EXPORT_SYMBOL(audit_log);
+EXPORT_SYMBOL(audit_set_user_ns);
EXPORT_SYMBOL(audit_free_user_ns);
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 99de920..047921a 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -100,6 +100,7 @@ int create_user_ns(struct cred *new)
update_mnt_policy(ns);
+ audit_set_user_ns(ns);
return 0;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 05/48] Audit: make audit_skb_hold_queue per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (3 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 04/48] Audit: make audit_skb_queue per user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 06/48] Audit: make kauditd_task " Gao feng
` (28 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
After this patch, ervery user namespace has one
audit_skb_hold_queue. Since we havn't finish the
preparations, only allow user to operate the skb
hold queue of init user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 16 +++++++++-------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index e322f20..53420a4 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -22,6 +22,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
struct audit_ctrl {
struct sock *sock;
struct sk_buff_head queue;
+ struct sk_buff_head hold_queue;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 2a727af..61562c5 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -129,8 +129,6 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
static int audit_freelist_count;
static LIST_HEAD(audit_freelist);
-/* queue of skbs to send to auditd when/if it comes back */
-static struct sk_buff_head audit_skb_hold_queue;
static struct task_struct *kauditd_task;
static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
@@ -370,9 +368,11 @@ static int audit_set_failure(int state, kuid_t loginuid, u32 sessionid, u32 sid)
*/
static void audit_hold_skb(struct sk_buff *skb)
{
+ struct sk_buff_head *list = &init_user_ns.audit.hold_queue;
+
if (audit_default &&
- skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit)
- skb_queue_tail(&audit_skb_hold_queue, skb);
+ skb_queue_len(list) < audit_backlog_limit)
+ skb_queue_tail(list, skb);
else
kfree_skb(skb);
}
@@ -419,6 +419,7 @@ static int kauditd_thread(void *dummy)
{
struct sk_buff *skb;
struct sk_buff_head *queue = &init_user_ns.audit.queue;
+ struct sk_buff_head *hold_queue = &init_user_ns.audit.hold_queue;
set_freezable();
while (!kthread_should_stop()) {
@@ -436,11 +437,11 @@ static int kauditd_thread(void *dummy)
* note and still have no friggin idea what i'm thinking today.
*/
if (audit_default && audit_pid) {
- skb = skb_dequeue(&audit_skb_hold_queue);
+ skb = skb_dequeue(hold_queue);
if (unlikely(skb)) {
while (skb && audit_pid) {
kauditd_send_skb(skb);
- skb = skb_dequeue(&audit_skb_hold_queue);
+ skb = skb_dequeue(hold_queue);
}
}
}
@@ -998,7 +999,6 @@ static int __init audit_init(void)
return -1;
audit_set_user_ns(&init_user_ns);
- skb_queue_head_init(&audit_skb_hold_queue);
audit_initialized = AUDIT_INITIALIZED;
audit_enabled = audit_default;
audit_ever_enabled |= !!audit_default;
@@ -1599,6 +1599,7 @@ void audit_set_user_ns(struct user_namespace *ns)
return;
skb_queue_head_init(&ns->audit.queue);
+ skb_queue_head_init(&ns->audit.hold_queue);
}
void audit_free_user_ns(struct user_namespace *ns)
@@ -1613,6 +1614,7 @@ void audit_free_user_ns(struct user_namespace *ns)
}
skb_queue_purge(&ns->audit.queue);
+ skb_queue_purge(&ns->audit.hold_queue);
}
EXPORT_SYMBOL(audit_log_start);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 06/48] Audit: make kauditd_task per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (4 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 05/48] Audit: make audit_skb_hold_queue " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 07/48] Audit: make audit_pid " Gao feng
` (27 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This patch makes kauditd_task per user namespace,
Since right now we only allow user in init user
namesapce to send audit netlink message to kernel,
so actually the kauditd_task belongs to other user
namespace will still not run.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 25 +++++++++++++++----------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 53420a4..24f7c2f 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -23,6 +23,7 @@ struct audit_ctrl {
struct sock *sock;
struct sk_buff_head queue;
struct sk_buff_head hold_queue;
+ struct task_struct *kauditd_task;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 61562c5..839c4c0 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -129,7 +129,6 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
static int audit_freelist_count;
static LIST_HEAD(audit_freelist);
-static struct task_struct *kauditd_task;
static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
@@ -418,8 +417,9 @@ static void kauditd_send_skb(struct sk_buff *skb)
static int kauditd_thread(void *dummy)
{
struct sk_buff *skb;
- struct sk_buff_head *queue = &init_user_ns.audit.queue;
- struct sk_buff_head *hold_queue = &init_user_ns.audit.hold_queue;
+ struct user_namespace *ns = dummy;
+ struct sk_buff_head *queue = &ns->audit.queue;
+ struct sk_buff_head *hold_queue = &ns->audit.hold_queue;
set_freezable();
while (!kthread_should_stop()) {
@@ -663,14 +663,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
ns = current_user_ns();
/* As soon as there's any sign of userspace auditd,
* start kauditd to talk to it */
- if (!kauditd_task) {
- kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
- if (IS_ERR(kauditd_task)) {
- err = PTR_ERR(kauditd_task);
- kauditd_task = NULL;
- return err;
- }
+ if (!ns->audit.kauditd_task) {
+ struct task_struct *tsk;
+
+ tsk = kthread_run(kauditd_thread, ns, "kauditd");
+ if (IS_ERR(tsk))
+ return PTR_ERR(tsk);
+
+ ns->audit.kauditd_task = tsk;
}
+
loginuid = audit_get_loginuid(current);
sessionid = audit_get_sessionid(current);
security_task_getsecid(current, &sid);
@@ -1615,6 +1617,9 @@ void audit_free_user_ns(struct user_namespace *ns)
skb_queue_purge(&ns->audit.queue);
skb_queue_purge(&ns->audit.hold_queue);
+
+ if (ns->audit.kauditd_task)
+ kthread_stop(ns->audit.kauditd_task);
}
EXPORT_SYMBOL(audit_log_start);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 07/48] Audit: make audit_pid per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (5 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 06/48] Audit: make kauditd_task " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 08/48] Audit: make audit_nlk_portid per user namesapce Gao feng
` (26 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
After this patch, audit_pid is per user namespace.
Since we havn't prepared to enable audit for uninit
user namespace now, use the audit_pid of init_user_ns
instead of the audit_pid of per user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/audit.h | 1 +
include/linux/user_namespace.h | 1 +
kernel/audit.c | 22 +++++++++++-----------
kernel/audit.h | 5 ++---
kernel/auditsc.c | 6 +++---
5 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 78f51ae..684599b 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <uapi/linux/audit.h>
+#include <linux/user_namespace.h>
struct audit_sig_info {
uid_t uid;
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 24f7c2f..a6c6174 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -21,6 +21,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
#ifdef CONFIG_AUDIT
struct audit_ctrl {
struct sock *sock;
+ int pid;
struct sk_buff_head queue;
struct sk_buff_head hold_queue;
struct task_struct *kauditd_task;
diff --git a/kernel/audit.c b/kernel/audit.c
index 839c4c0..2ce7a21 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -92,7 +92,6 @@ static int audit_failure = AUDIT_FAIL_PRINTK;
* contains the pid of the auditd process and audit_nlk_portid contains
* the portid to use to send netlink messages to that process.
*/
-int audit_pid;
static int audit_nlk_portid;
/* If audit_rate_limit is non-zero, limit the rate of sending audit records
@@ -181,7 +180,7 @@ void audit_panic(const char *message)
break;
case AUDIT_FAIL_PANIC:
/* test audit_pid since printk is always losey, why bother? */
- if (audit_pid)
+ if (&init_user_ns.audit.pid)
panic("audit: %s\n", message);
break;
}
@@ -404,9 +403,10 @@ static void kauditd_send_skb(struct sk_buff *skb)
audit_nlk_portid, 0);
if (err < 0) {
BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
- printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
+ printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n",
+ init_user_ns.audit.pid);
audit_log_lost("auditd disappeared\n");
- audit_pid = 0;
+ init_user_ns.audit.pid = 0;
/* we might get lucky and get this in the next auditd */
audit_hold_skb(skb);
} else
@@ -436,10 +436,10 @@ static int kauditd_thread(void *dummy)
* in 5 years when I want to play with this again I'll see this
* note and still have no friggin idea what i'm thinking today.
*/
- if (audit_default && audit_pid) {
+ if (audit_default && ns->audit.pid) {
skb = skb_dequeue(hold_queue);
if (unlikely(skb)) {
- while (skb && audit_pid) {
+ while (skb && ns->audit.pid) {
kauditd_send_skb(skb);
skb = skb_dequeue(hold_queue);
}
@@ -449,7 +449,7 @@ static int kauditd_thread(void *dummy)
skb = skb_dequeue(queue);
wake_up(&audit_backlog_wait);
if (skb) {
- if (audit_pid)
+ if (ns->audit.pid)
kauditd_send_skb(skb);
else
audit_printk_skb(skb);
@@ -683,7 +683,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_GET:
status_set.enabled = audit_enabled;
status_set.failure = audit_failure;
- status_set.pid = audit_pid;
+ status_set.pid = ns->audit.pid;
status_set.rate_limit = audit_rate_limit;
status_set.backlog_limit = audit_backlog_limit;
status_set.lost = atomic_read(&audit_lost);
@@ -713,10 +713,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (audit_enabled != AUDIT_OFF)
audit_log_config_change("audit_pid", new_pid,
- audit_pid, loginuid,
+ ns->audit.pid, loginuid,
sessionid, sid, 1);
- audit_pid = new_pid;
+ ns->audit.pid = new_pid;
audit_nlk_portid = NETLINK_CB(skb).portid;
}
if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) {
@@ -1530,7 +1530,7 @@ void audit_log_end(struct audit_buffer *ab)
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
- if (audit_pid) {
+ if (init_user_ns.audit.pid) {
skb_queue_tail(&init_user_ns.audit.queue,
ab->skb);
wake_up_interruptible(&kauditd_wait);
diff --git a/kernel/audit.h b/kernel/audit.h
index 11468d9..ced93fe 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -61,8 +61,6 @@ struct audit_entry {
extern int audit_ever_enabled;
-extern int audit_pid;
-
#define AUDIT_INODE_BUCKETS 32
extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@ -153,7 +151,8 @@ extern u32 audit_sig_sid;
extern int __audit_signal_info(int sig, struct task_struct *t);
static inline int audit_signal_info(int sig, struct task_struct *t)
{
- if (unlikely((audit_pid && t->tgid == audit_pid) ||
+ if (unlikely((init_user_ns.audit.pid &&
+ t->tgid == init_user_ns.audit.pid) ||
(audit_signals && !audit_dummy_context())))
return __audit_signal_info(sig, t);
return 0;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index c682294..6c97f36 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -871,7 +871,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
struct audit_entry *e;
enum audit_state state;
- if (audit_pid && tsk->tgid == audit_pid)
+ if (init_user_ns.audit.pid && tsk->tgid == init_user_ns.audit.pid)
return AUDIT_DISABLED;
rcu_read_lock();
@@ -932,7 +932,7 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
{
struct audit_names *n;
- if (audit_pid && tsk->tgid == audit_pid)
+ if (init_user_ns.audit.pid && tsk->tgid == init_user_ns.audit.pid)
return;
rcu_read_lock();
@@ -2547,7 +2547,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
struct audit_context *ctx = tsk->audit_context;
kuid_t uid = current_uid(), t_uid = task_uid(t);
- if (audit_pid && t->tgid == audit_pid) {
+ if (init_user_ns.audit.pid && t->tgid == init_user_ns.audit.pid) {
if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
audit_sig_pid = tsk->pid;
if (uid_valid(tsk->loginuid))
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 08/48] Audit: make audit_nlk_portid per user namesapce
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (6 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 07/48] Audit: make audit_pid " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 09/48] Audit: make audit_enabled per user namespace Gao feng
` (25 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
After this patch, audit_nlk_port is per user namespace.
Just like prev patch does,use audit_nlk_portid of init
user namespace in kauditd_send_skb.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 11 ++---------
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index a6c6174..769a12b 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -22,6 +22,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
struct audit_ctrl {
struct sock *sock;
int pid;
+ int portid;
struct sk_buff_head queue;
struct sk_buff_head hold_queue;
struct task_struct *kauditd_task;
diff --git a/kernel/audit.c b/kernel/audit.c
index 2ce7a21..b946b29 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -87,13 +87,6 @@ static int audit_default;
/* If auditing cannot proceed, audit_failure selects what happens. */
static int audit_failure = AUDIT_FAIL_PRINTK;
-/*
- * If audit records are to be written to the netlink socket, audit_pid
- * contains the pid of the auditd process and audit_nlk_portid contains
- * the portid to use to send netlink messages to that process.
- */
-static int audit_nlk_portid;
-
/* If audit_rate_limit is non-zero, limit the rate of sending audit records
* to that number per second. This prevents DoS attacks, but results in
* audit records being dropped. */
@@ -400,7 +393,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
/* take a reference in case we can't send it and we want to hold it */
skb_get(skb);
err = netlink_unicast(init_user_ns.audit.sock, skb,
- audit_nlk_portid, 0);
+ init_user_ns.audit.portid, 0);
if (err < 0) {
BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n",
@@ -717,7 +710,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
sessionid, sid, 1);
ns->audit.pid = new_pid;
- audit_nlk_portid = NETLINK_CB(skb).portid;
+ ns->audit.portid = NETLINK_CB(skb).portid;
}
if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) {
err = audit_set_rate_limit(status_get->rate_limit,
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 09/48] Audit: make audit_enabled per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (7 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 08/48] Audit: make audit_nlk_portid per user namesapce Gao feng
@ 2013-05-07 2:20 ` Gao feng
[not found] ` <1367893269-9308-10-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2013-05-07 2:20 ` [PATCH RFC 10/48] Audit: change type of audit_ever_enabled to bool Gao feng
` (24 subsequent siblings)
33 siblings, 1 reply; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This patch makes audit_enabled per user namespace,
Right now,use audit_enabled of init user namespace to
decide if audit is enabled no matter which user namespace
we belong to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/audit.h | 4 +++-
include/linux/user_namespace.h | 1 +
kernel/audit.c | 37 ++++++++++++++++++-------------------
3 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 684599b..33e6584 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -441,7 +441,8 @@ extern int audit_filter_type(int type);
extern int audit_receive_filter(int type, int pid, int seq,
void *data, size_t datasz, kuid_t loginuid,
u32 sessionid, u32 sid);
-extern int audit_enabled;
+#define audit_enabled (init_user_ns.audit.enabled)
+#define audit_enabled_ns (ns->audit.enabled)
#else /* CONFIG_AUDIT */
static inline __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
@@ -487,6 +488,7 @@ static inline void audit_set_user_ns(struct user_namespace *ns)
static inline void audit_free_user_ns(struct user_namespace *ns)
{ }
#define audit_enabled 0
+#define audit_enabled_ns(ns) 0
#endif /* CONFIG_AUDIT */
static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
{
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 769a12b..3b2ed90 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -21,6 +21,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
#ifdef CONFIG_AUDIT
struct audit_ctrl {
struct sock *sock;
+ int enabled;
int pid;
int portid;
struct sk_buff_head queue;
diff --git a/kernel/audit.c b/kernel/audit.c
index b946b29..4595a9e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -76,11 +76,8 @@ static int audit_initialized;
#define AUDIT_OFF 0
#define AUDIT_ON 1
#define AUDIT_LOCKED 2
-int audit_enabled;
int audit_ever_enabled;
-EXPORT_SYMBOL_GPL(audit_enabled);
-
/* Default state when kernel boots without any parameters. */
static int audit_default;
@@ -285,14 +282,15 @@ static int audit_do_config_change(char *function_name, int *to_change,
u32 sid)
{
int allow_changes, rc = 0, old = *to_change;
+ struct user_namespace *ns = current_user_ns();
/* check if we are locked */
- if (audit_enabled == AUDIT_LOCKED)
+ if (ns->audit.enabled == AUDIT_LOCKED)
allow_changes = 0;
else
allow_changes = 1;
- if (audit_enabled != AUDIT_OFF) {
+ if (ns->audit.enabled != AUDIT_OFF) {
rc = audit_log_config_change(function_name, new, old, loginuid,
sessionid, sid, allow_changes);
if (rc)
@@ -322,14 +320,15 @@ static int audit_set_backlog_limit(int limit, kuid_t loginuid, u32 sessionid,
limit, loginuid, sessionid, sid);
}
-static int audit_set_enabled(int state, kuid_t loginuid, u32 sessionid, u32 sid)
+static int audit_set_enabled(struct user_namespace *ns, int state,
+ kuid_t loginuid, u32 sessionid, u32 sid)
{
int rc;
if (state < AUDIT_OFF || state > AUDIT_LOCKED)
return -EINVAL;
- rc = audit_do_config_change("audit_enabled", &audit_enabled, state,
- loginuid, sessionid, sid);
+ rc = audit_do_config_change("audit_enabled", &ns->audit.enabled,
+ state, loginuid, sessionid, sid);
if (!rc)
audit_ever_enabled |= !!state;
@@ -609,7 +608,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
char *ctx = NULL;
u32 len;
- if (!audit_enabled) {
+ if (!init_user_ns.audit.enabled) {
*ab = NULL;
return rc;
}
@@ -674,7 +673,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
switch (msg_type) {
case AUDIT_GET:
- status_set.enabled = audit_enabled;
+ status_set.enabled = ns->audit.enabled;
status_set.failure = audit_failure;
status_set.pid = ns->audit.pid;
status_set.rate_limit = audit_rate_limit;
@@ -690,7 +689,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EINVAL;
status_get = (struct audit_status *)data;
if (status_get->mask & AUDIT_STATUS_ENABLED) {
- err = audit_set_enabled(status_get->enabled,
+ err = audit_set_enabled(ns, status_get->enabled,
loginuid, sessionid, sid);
if (err < 0)
return err;
@@ -704,7 +703,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (status_get->mask & AUDIT_STATUS_PID) {
int new_pid = status_get->pid;
- if (audit_enabled != AUDIT_OFF)
+ if (ns->audit.enabled != AUDIT_OFF)
audit_log_config_change("audit_pid", new_pid,
ns->audit.pid, loginuid,
sessionid, sid, 1);
@@ -725,7 +724,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
- if (!audit_enabled && msg_type != AUDIT_USER_AVC)
+ if (!ns->audit.enabled && msg_type != AUDIT_USER_AVC)
return 0;
err = audit_filter_user();
@@ -761,12 +760,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_DEL:
if (nlmsg_len(nlh) < sizeof(struct audit_rule))
return -EINVAL;
- if (audit_enabled == AUDIT_LOCKED) {
+ if (ns->audit.enabled == AUDIT_LOCKED) {
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE,
loginuid, sessionid, sid);
audit_log_format(ab, " audit_enabled=%d res=0",
- audit_enabled);
+ ns->audit.enabled);
audit_log_end(ab);
return -EPERM;
}
@@ -780,12 +779,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_DEL_RULE:
if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
return -EINVAL;
- if (audit_enabled == AUDIT_LOCKED) {
+ if (ns->audit.enabled == AUDIT_LOCKED) {
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE,
loginuid, sessionid, sid);
audit_log_format(ab, " audit_enabled=%d res=0",
- audit_enabled);
+ ns->audit.enabled);
audit_log_end(ab);
return -EPERM;
}
@@ -995,7 +994,6 @@ static int __init audit_init(void)
audit_set_user_ns(&init_user_ns);
audit_initialized = AUDIT_INITIALIZED;
- audit_enabled = audit_default;
audit_ever_enabled |= !!audit_default;
audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
@@ -1017,7 +1015,7 @@ static int __init audit_enable(char *str)
printk(KERN_INFO "audit: %s", audit_default ? "enabled" : "disabled");
if (audit_initialized == AUDIT_INITIALIZED) {
- audit_enabled = audit_default;
+ init_user_ns.audit.enabled = audit_default;
audit_ever_enabled |= !!audit_default;
} else if (audit_initialized == AUDIT_UNINITIALIZED) {
printk(" (after initialization)");
@@ -1595,6 +1593,7 @@ void audit_set_user_ns(struct user_namespace *ns)
skb_queue_head_init(&ns->audit.queue);
skb_queue_head_init(&ns->audit.hold_queue);
+ ns->audit.enabled = audit_default;
}
void audit_free_user_ns(struct user_namespace *ns)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 10/48] Audit: change type of audit_ever_enabled to bool
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (8 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 09/48] Audit: make audit_enabled per user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
[not found] ` <1367893269-9308-11-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2013-05-07 2:20 ` [PATCH RFC 11/48] Audit: make audit_ever_enabled per user namespace Gao feng
` (23 subsequent siblings)
33 siblings, 1 reply; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
It's better to define audit_ever_enabled as bool
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 4595a9e..1138ff5 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -76,7 +76,7 @@ static int audit_initialized;
#define AUDIT_OFF 0
#define AUDIT_ON 1
#define AUDIT_LOCKED 2
-int audit_ever_enabled;
+bool audit_ever_enabled;
/* Default state when kernel boots without any parameters. */
static int audit_default;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 11/48] Audit: make audit_ever_enabled per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (9 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 10/48] Audit: change type of audit_ever_enabled to bool Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 12/48] Audit: make audit_initialized " Gao feng
` (22 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
We set audit_ever_enabled true after we enabled audit once.
and if audit_ever_enabled is true, we will allocate audit
context for task.
We should decide if to allocate audit context for tasks based on
if the audit is enabled once in the user namespace which the
task belongs to.
So audit_ever_enabled should be per user namespace too.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 7 +++----
kernel/auditsc.c | 5 ++++-
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 3b2ed90..d5a22b2 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -27,6 +27,7 @@ struct audit_ctrl {
struct sk_buff_head queue;
struct sk_buff_head hold_queue;
struct task_struct *kauditd_task;
+ bool ever_enabled;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 1138ff5..9ea5b27 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -76,7 +76,6 @@ static int audit_initialized;
#define AUDIT_OFF 0
#define AUDIT_ON 1
#define AUDIT_LOCKED 2
-bool audit_ever_enabled;
/* Default state when kernel boots without any parameters. */
static int audit_default;
@@ -331,7 +330,7 @@ static int audit_set_enabled(struct user_namespace *ns, int state,
state, loginuid, sessionid, sid);
if (!rc)
- audit_ever_enabled |= !!state;
+ ns->audit.ever_enabled |= !!state;
return rc;
}
@@ -994,7 +993,6 @@ static int __init audit_init(void)
audit_set_user_ns(&init_user_ns);
audit_initialized = AUDIT_INITIALIZED;
- audit_ever_enabled |= !!audit_default;
audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
@@ -1016,7 +1014,7 @@ static int __init audit_enable(char *str)
if (audit_initialized == AUDIT_INITIALIZED) {
init_user_ns.audit.enabled = audit_default;
- audit_ever_enabled |= !!audit_default;
+ init_user_ns.audit.ever_enabled |= !!audit_default;
} else if (audit_initialized == AUDIT_UNINITIALIZED) {
printk(" (after initialization)");
} else {
@@ -1594,6 +1592,7 @@ void audit_set_user_ns(struct user_namespace *ns)
skb_queue_head_init(&ns->audit.queue);
skb_queue_head_init(&ns->audit.hold_queue);
ns->audit.enabled = audit_default;
+ ns->audit.ever_enabled |= !!audit_default;
}
void audit_free_user_ns(struct user_namespace *ns)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6c97f36..290cce6 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1062,8 +1062,11 @@ int audit_alloc(struct task_struct *tsk)
struct audit_context *context;
enum audit_state state;
char *key = NULL;
+ struct user_namespace *ns = current_user_ns();
+ /* Use current_user_ns, since this new task may run
+ * in new user namespace */
- if (likely(!audit_ever_enabled))
+ if (likely(!ns->audit.ever_enabled))
return 0; /* Return if not auditing. */
state = audit_filter_task(tsk, &key);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 12/48] Audit: make audit_initialized per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (10 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 11/48] Audit: make audit_ever_enabled per user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 13/48] Audit: only allow init user namespace to change audit_rate_limit Gao feng
` (21 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
audit_initialized is used to identify if the audit
related resources have been initialized. it should
be per user namespace too.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 21 +++++++++++----------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index d5a22b2..c7b5bf7 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -21,6 +21,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
#ifdef CONFIG_AUDIT
struct audit_ctrl {
struct sock *sock;
+ int initialized;
int enabled;
int pid;
int portid;
diff --git a/kernel/audit.c b/kernel/audit.c
index 9ea5b27..bf8b59c 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -66,12 +66,12 @@
#include "audit.h"
-/* No auditing will take place until audit_initialized == AUDIT_INITIALIZED.
+/* No auditing will take place until user namespace's
+ * audit.initialized == AUDIT_INITIALIZED.
* (Initialization happens after skb_init is called.) */
#define AUDIT_DISABLED -1
#define AUDIT_UNINITIALIZED 0
#define AUDIT_INITIALIZED 1
-static int audit_initialized;
#define AUDIT_OFF 0
#define AUDIT_ON 1
@@ -982,7 +982,7 @@ static int __init audit_init(void)
{
int i;
- if (audit_initialized == AUDIT_DISABLED)
+ if (init_user_ns.audit.initialized == AUDIT_DISABLED)
return 0;
printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
@@ -992,7 +992,6 @@ static int __init audit_init(void)
return -1;
audit_set_user_ns(&init_user_ns);
- audit_initialized = AUDIT_INITIALIZED;
audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
@@ -1008,14 +1007,14 @@ static int __init audit_enable(char *str)
{
audit_default = !!simple_strtol(str, NULL, 0);
if (!audit_default)
- audit_initialized = AUDIT_DISABLED;
+ init_user_ns.audit.initialized = AUDIT_DISABLED;
printk(KERN_INFO "audit: %s", audit_default ? "enabled" : "disabled");
- if (audit_initialized == AUDIT_INITIALIZED) {
+ if (init_user_ns.audit.initialized == AUDIT_INITIALIZED) {
init_user_ns.audit.enabled = audit_default;
init_user_ns.audit.ever_enabled |= !!audit_default;
- } else if (audit_initialized == AUDIT_UNINITIALIZED) {
+ } else if (init_user_ns.audit.initialized == AUDIT_UNINITIALIZED) {
printk(" (after initialization)");
} else {
printk(" (until reboot)");
@@ -1183,7 +1182,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
unsigned long timeout_start = jiffies;
struct sk_buff_head *queue = &init_user_ns.audit.queue;
- if (audit_initialized != AUDIT_INITIALIZED)
+ if (init_user_ns.audit.initialized != AUDIT_INITIALIZED)
return NULL;
if (unlikely(audit_filter_type(type)))
@@ -1586,18 +1585,20 @@ EXPORT_SYMBOL(audit_log_secctx);
void audit_set_user_ns(struct user_namespace *ns)
{
- if (audit_initialized == AUDIT_DISABLED)
+ if (init_user_ns.audit.initialized == AUDIT_DISABLED)
return;
skb_queue_head_init(&ns->audit.queue);
skb_queue_head_init(&ns->audit.hold_queue);
ns->audit.enabled = audit_default;
ns->audit.ever_enabled |= !!audit_default;
+
+ ns->audit.initialized = AUDIT_INITIALIZED;
}
void audit_free_user_ns(struct user_namespace *ns)
{
- if (audit_initialized == AUDIT_DISABLED)
+ if (init_user_ns.audit.initialized == AUDIT_DISABLED)
return;
if (ns->audit.sock) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 13/48] Audit: only allow init user namespace to change audit_rate_limit
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (11 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 12/48] Audit: make audit_initialized " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 14/48] Audit: only allow init user namespace to change audit_failure Gao feng
` (20 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Because We want to avoid the DoS attack caused by other user
namespace,so don't make audit_rate_limit per user namespace.
And only init user namespace has rights to change it.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/audit.c b/kernel/audit.c
index bf8b59c..8a3ea47 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -308,6 +308,9 @@ static int audit_do_config_change(char *function_name, int *to_change,
static int audit_set_rate_limit(int limit, kuid_t loginuid, u32 sessionid,
u32 sid)
{
+ if (current_user_ns() != &init_user_ns)
+ return -EPERM;
+
return audit_do_config_change("audit_rate_limit", &audit_rate_limit,
limit, loginuid, sessionid, sid);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 14/48] Audit: only allow init user namespace to change audit_failure
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (12 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 13/48] Audit: only allow init user namespace to change audit_rate_limit Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 16/48] Audit: user proper user namespace in audit_log_config_change Gao feng
` (19 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Setting audit_failure to AUDIT_FAIL_PANIC may
cause system panic.
We should disallow uninit user namesapce to change it.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/audit.c b/kernel/audit.c
index 8a3ea47..18cf5ce 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -345,6 +345,9 @@ static int audit_set_failure(int state, kuid_t loginuid, u32 sessionid, u32 sid)
&& state != AUDIT_FAIL_PANIC)
return -EINVAL;
+ if (current_user_ns() != &init_user_ns)
+ return -EPERM;
+
return audit_do_config_change("audit_failure", &audit_failure, state,
loginuid, sessionid, sid);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 16/48] Audit: user proper user namespace in audit_log_config_change
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (13 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 14/48] Audit: only allow init user namespace to change audit_failure Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 17/48] Audit: make kauditd_wait per user namespace Gao feng
` (18 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
We should user current_user_ns instead of init_user_ns.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index d39296b..f5e106f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -251,13 +251,14 @@ static int audit_log_config_change(char *function_name, int new, int old,
int allow_changes)
{
struct audit_buffer *ab;
+ struct user_namespace *ns = current_user_ns();
int rc = 0;
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return rc;
audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new,
- old, from_kuid(&init_user_ns, loginuid), sessionid);
+ old, from_kuid(ns, loginuid), sessionid);
if (sid) {
char *ctx = NULL;
u32 len;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 17/48] Audit: make kauditd_wait per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (14 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 16/48] Audit: user proper user namespace in audit_log_config_change Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 18/48] Audit: make audit_backlog_wait " Gao feng
` (17 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
kauditd_task is added to the wait queue kaudit_wait when
there is no audit message being generated in user namespace,
so the kaudit_wait should be per user namespace too.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 8 ++++----
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index c7b5bf7..7c2c65c 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -28,6 +28,7 @@ struct audit_ctrl {
struct sk_buff_head queue;
struct sk_buff_head hold_queue;
struct task_struct *kauditd_task;
+ wait_queue_head_t kauditd_wait;
bool ever_enabled;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index f5e106f..ad03f4f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -117,7 +117,6 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
static int audit_freelist_count;
static LIST_HEAD(audit_freelist);
-static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
/* Serialize requests from userspace. */
@@ -454,7 +453,7 @@ static int kauditd_thread(void *dummy)
} else {
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&kauditd_wait, &wait);
+ add_wait_queue(&ns->audit.kauditd_wait, &wait);
if (!skb_queue_len(queue)) {
try_to_freeze();
@@ -462,7 +461,7 @@ static int kauditd_thread(void *dummy)
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&kauditd_wait, &wait);
+ remove_wait_queue(&ns->audit.kauditd_wait, &wait);
}
}
return 0;
@@ -1528,7 +1527,7 @@ void audit_log_end(struct audit_buffer *ab)
if (init_user_ns.audit.pid) {
skb_queue_tail(&init_user_ns.audit.queue,
ab->skb);
- wake_up_interruptible(&kauditd_wait);
+ wake_up_interruptible(&init_user_ns.audit.kauditd_wait);
} else {
audit_printk_skb(&init_user_ns, ab->skb);
}
@@ -1599,6 +1598,7 @@ void audit_set_user_ns(struct user_namespace *ns)
skb_queue_head_init(&ns->audit.hold_queue);
ns->audit.enabled = audit_default;
ns->audit.ever_enabled |= !!audit_default;
+ init_waitqueue_head(&ns->audit.kauditd_wait);
ns->audit.initialized = AUDIT_INITIALIZED;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 18/48] Audit: make audit_backlog_wait per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (15 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 17/48] Audit: make kauditd_wait per user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 19/48] Audit: remove duplicate comments Gao feng
` (16 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Tasks are added to audit_backlog_wait when the
audit_skb_queue of user namespace is full, so
audit_backlog_wait should be per user namespace too.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 1 +
kernel/audit.c | 11 +++++------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 7c2c65c..5a778f8 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -29,6 +29,7 @@ struct audit_ctrl {
struct sk_buff_head hold_queue;
struct task_struct *kauditd_task;
wait_queue_head_t kauditd_wait;
+ wait_queue_head_t backlog_wait;
bool ever_enabled;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index ad03f4f..62f244b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -117,8 +117,6 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
static int audit_freelist_count;
static LIST_HEAD(audit_freelist);
-static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
-
/* Serialize requests from userspace. */
DEFINE_MUTEX(audit_cmd_mutex);
@@ -444,7 +442,7 @@ static int kauditd_thread(void *dummy)
}
skb = skb_dequeue(queue);
- wake_up(&audit_backlog_wait);
+ wake_up(&ns->audit.backlog_wait);
if (skb) {
if (ns->audit.pid)
kauditd_send_skb(ns, skb);
@@ -1146,14 +1144,14 @@ static void wait_for_auditd(unsigned long sleep_time)
const struct sk_buff_head *queue = &init_user_ns.audit.queue;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&audit_backlog_wait, &wait);
+ add_wait_queue(&init_user_ns.audit.backlog_wait, &wait);
if (audit_backlog_limit &&
skb_queue_len(queue) > audit_backlog_limit)
schedule_timeout(sleep_time);
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&audit_backlog_wait, &wait);
+ remove_wait_queue(&init_user_ns.audit.backlog_wait, &wait);
}
/* Obtain an audit buffer. This routine does locking to obtain the
@@ -1219,7 +1217,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
audit_backlog_limit);
audit_log_lost("backlog limit exceeded");
audit_backlog_wait_time = audit_backlog_wait_overflow;
- wake_up(&audit_backlog_wait);
+ wake_up(&init_user_ns.audit.backlog_wait);
return NULL;
}
@@ -1599,6 +1597,7 @@ void audit_set_user_ns(struct user_namespace *ns)
ns->audit.enabled = audit_default;
ns->audit.ever_enabled |= !!audit_default;
init_waitqueue_head(&ns->audit.kauditd_wait);
+ init_waitqueue_head(&ns->audit.backlog_wait);
ns->audit.initialized = AUDIT_INITIALIZED;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 19/48] Audit: remove duplicate comments
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (16 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 18/48] Audit: make audit_backlog_wait " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 20/48] Audit: introduce new audit logging interface for user namespace Gao feng
` (15 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Remove it.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 62f244b..5ac9acd 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1154,13 +1154,6 @@ static void wait_for_auditd(unsigned long sleep_time)
remove_wait_queue(&init_user_ns.audit.backlog_wait, &wait);
}
-/* Obtain an audit buffer. This routine does locking to obtain the
- * audit buffer, but then no locking is required for calls to
- * audit_log_*format. If the tsk is a task that is currently in a
- * syscall, then the syscall is marked as auditable and an audit record
- * will be written at syscall exit. If there is no associated task, tsk
- * should be NULL. */
-
/**
* audit_log_start - obtain an audit buffer
* @ctx: audit_context (may be NULL)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 20/48] Audit: introduce new audit logging interface for user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (17 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 19/48] Audit: remove duplicate comments Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 21/48] Audit: pass proper user namespace to audit_log_common_recv_msg Gao feng
` (14 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This interface audit_log_start_ns and audit_log_end_ns
will be used for logging audit logs in user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/audit.h | 25 ++++++++++++--
kernel/audit.c | 95 ++++++++++++++++++++++++++++++---------------------
2 files changed, 78 insertions(+), 42 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 33e6584..f16db07 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -398,10 +398,18 @@ extern __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...);
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
+extern struct audit_buffer *
+audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
+
+extern struct audit_buffer *
+audit_log_start_ns(struct user_namespace *ns, struct audit_context *ctx,
+ gfp_t gfp_mask, int type);
+
extern __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
extern void audit_log_end(struct audit_buffer *ab);
+extern void audit_log_end_ns(struct user_namespace *ns,
+ struct audit_buffer *ab);
extern int audit_string_contains_control(const char *string,
size_t len);
extern void audit_log_n_hex(struct audit_buffer *ab,
@@ -448,8 +456,16 @@ static inline __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{ }
-static inline struct audit_buffer *audit_log_start(struct audit_context *ctx,
- gfp_t gfp_mask, int type)
+static inline
+struct audit_buffer *audit_log_start(struct audit_context *ctx,
+ gfp_t gfp_mask, int type)
+{
+ return NULL;
+}
+static inline
+struct audit_buffer *audit_log_start_ns(struct user_namespace *ns,
+ struct audit_context *ctx,
+ gfp_t gfp_mask, int type)
{
return NULL;
}
@@ -458,6 +474,9 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
{ }
static inline void audit_log_end(struct audit_buffer *ab)
{ }
+static inline void audit_log_end_ns(struct user_namespace *ns,
+ struct audit_buffer *ab)
+{ }
static inline void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf, size_t len)
{ }
diff --git a/kernel/audit.c b/kernel/audit.c
index 5ac9acd..594e4e1 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1139,47 +1139,35 @@ static inline void audit_get_stamp(struct audit_context *ctx,
/*
* Wait for auditd to drain the queue a little
*/
-static void wait_for_auditd(unsigned long sleep_time)
+static void wait_for_auditd(struct user_namespace *ns,
+ unsigned long sleep_time)
{
- const struct sk_buff_head *queue = &init_user_ns.audit.queue;
+ const struct sk_buff_head *queue = &ns->audit.queue;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&init_user_ns.audit.backlog_wait, &wait);
+ add_wait_queue(&ns->audit.backlog_wait, &wait);
if (audit_backlog_limit &&
skb_queue_len(queue) > audit_backlog_limit)
schedule_timeout(sleep_time);
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&init_user_ns.audit.backlog_wait, &wait);
+ remove_wait_queue(&ns->audit.backlog_wait, &wait);
}
-/**
- * audit_log_start - obtain an audit buffer
- * @ctx: audit_context (may be NULL)
- * @gfp_mask: type of allocation
- * @type: audit message type
- *
- * Returns audit_buffer pointer on success or NULL on error.
- *
- * Obtain an audit buffer. This routine does locking to obtain the
- * audit buffer, but then no locking is required for calls to
- * audit_log_*format. If the task (ctx) is a task that is currently in a
- * syscall, then the syscall is marked as auditable and an audit record
- * will be written at syscall exit. If there is no associated task, then
- * task context (ctx) should be NULL.
- */
-struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
- int type)
+struct audit_buffer *audit_log_start_ns(struct user_namespace *ns,
+ struct audit_context *ctx,
+ gfp_t gfp_mask,
+ int type)
{
struct audit_buffer *ab = NULL;
struct timespec t;
unsigned int uninitialized_var(serial);
int reserve;
unsigned long timeout_start = jiffies;
- struct sk_buff_head *queue = &init_user_ns.audit.queue;
+ struct sk_buff_head *queue = &ns->audit.queue;
- if (init_user_ns.audit.initialized != AUDIT_INITIALIZED)
+ if (ns->audit.initialized != AUDIT_INITIALIZED)
return NULL;
if (unlikely(audit_filter_type(type)))
@@ -1199,7 +1187,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
sleep_time = timeout_start + audit_backlog_wait_time -
jiffies;
if ((long)sleep_time > 0)
- wait_for_auditd(sleep_time);
+ wait_for_auditd(ns, sleep_time);
continue;
}
if (audit_rate_check() && printk_ratelimit())
@@ -1210,7 +1198,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
audit_backlog_limit);
audit_log_lost("backlog limit exceeded");
audit_backlog_wait_time = audit_backlog_wait_overflow;
- wake_up(&init_user_ns.audit.backlog_wait);
+ wake_up(&ns->audit.backlog_wait);
return NULL;
}
@@ -1227,6 +1215,28 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
return ab;
}
+
+/**
+ * audit_log_start - obtain an audit buffer
+ * @ctx: audit_context (may be NULL)
+ * @gfp_mask: type of allocation
+ * @type: audit message type
+ *
+ * Returns audit_buffer pointer on success or NULL on error.
+ *
+ * Obtain an audit buffer. This routine does locking to obtain the
+ * audit buffer, but then no locking is required for calls to
+ * audit_log_*format. If the task (ctx) is a task that is currently in a
+ * syscall, then the syscall is marked as auditable and an audit record
+ * will be written at syscall exit. If there is no associated task, then
+ * task context (ctx) should be NULL.
+ */
+struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
+ int type)
+{
+ return audit_log_start_ns(&init_user_ns, ctx, gfp_mask, type);
+}
+
/**
* audit_expand - expand skb in the audit buffer
* @ab: audit_buffer
@@ -1496,16 +1506,7 @@ void audit_log_link_denied(const char *operation, struct path *link)
audit_log_end(ab);
}
-/**
- * audit_log_end - end one audit record
- * @ab: the audit_buffer
- *
- * The netlink_* functions cannot be called inside an irq context, so
- * the audit buffer is placed on a queue and a tasklet is scheduled to
- * remove them from the queue outside the irq context. May be called in
- * any context.
- */
-void audit_log_end(struct audit_buffer *ab)
+void audit_log_end_ns(struct user_namespace *ns, struct audit_buffer *ab)
{
if (!ab)
return;
@@ -1515,12 +1516,12 @@ void audit_log_end(struct audit_buffer *ab)
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
- if (init_user_ns.audit.pid) {
- skb_queue_tail(&init_user_ns.audit.queue,
+ if (ns->audit.pid) {
+ skb_queue_tail(&ns->audit.queue,
ab->skb);
- wake_up_interruptible(&init_user_ns.audit.kauditd_wait);
+ wake_up_interruptible(&ns->audit.kauditd_wait);
} else {
- audit_printk_skb(&init_user_ns, ab->skb);
+ audit_printk_skb(ns, ab->skb);
}
ab->skb = NULL;
}
@@ -1528,6 +1529,20 @@ void audit_log_end(struct audit_buffer *ab)
}
/**
+ * audit_log_end - end one audit record
+ * @ab: the audit_buffer
+ *
+ * The netlink_* functions cannot be called inside an irq context, so
+ * the audit buffer is placed on a queue and a tasklet is scheduled to
+ * remove them from the queue outside the irq context. May be called in
+ * any context.
+ */
+void audit_log_end(struct audit_buffer *ab)
+{
+ audit_log_end_ns(&init_user_ns, ab);
+}
+
+/**
* audit_log - Log an audit record
* @ctx: audit context
* @gfp_mask: type of allocation
@@ -1614,7 +1629,9 @@ void audit_free_user_ns(struct user_namespace *ns)
}
EXPORT_SYMBOL(audit_log_start);
+EXPORT_SYMBOL(audit_log_start_ns);
EXPORT_SYMBOL(audit_log_end);
+EXPORT_SYMBOL(audit_log_end_ns);
EXPORT_SYMBOL(audit_log_format);
EXPORT_SYMBOL(audit_log);
EXPORT_SYMBOL(audit_set_user_ns);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 21/48] Audit: pass proper user namespace to audit_log_common_recv_msg
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (18 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 20/48] Audit: introduce new audit logging interface for user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 22/48] Audit: Log audit config change in uninit user namespace Gao feng
` (13 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
The audit log that generated in user namespace should be
received by the auditd running in this user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 594e4e1..c8329ce 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -604,25 +604,26 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
return err;
}
-static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
+static int audit_log_common_recv_msg(struct user_namespace *ns,
+ struct audit_buffer **ab, u16 msg_type,
kuid_t auid, u32 ses, u32 sid)
{
int rc = 0;
char *ctx = NULL;
u32 len;
- if (!init_user_ns.audit.enabled) {
+ if (!ns->audit.enabled) {
*ab = NULL;
return rc;
}
- *ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+ *ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, msg_type);
if (unlikely(!*ab))
return rc;
audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u",
task_tgid_vnr(current),
- from_kuid(&init_user_ns, current_uid()),
- from_kuid(&init_user_ns, auid), ses);
+ from_kuid(ns, current_uid()),
+ from_kuid(ns, auid), ses);
if (sid) {
rc = security_secid_to_secctx(sid, &ctx, &len);
if (rc)
@@ -739,7 +740,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (err)
break;
}
- audit_log_common_recv_msg(&ab, msg_type,
+ audit_log_common_recv_msg(ns, &ab, msg_type,
loginuid, sessionid, sid);
if (msg_type != AUDIT_USER_TTY)
@@ -756,7 +757,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_n_untrustedstring(ab, data, size);
}
audit_set_pid(ab, NETLINK_CB(skb).portid);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
break;
case AUDIT_ADD:
@@ -764,12 +765,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (nlmsg_len(nlh) < sizeof(struct audit_rule))
return -EINVAL;
if (ns->audit.enabled == AUDIT_LOCKED) {
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE,
+ audit_log_common_recv_msg(ns, &ab, AUDIT_CONFIG_CHANGE,
loginuid, sessionid, sid);
audit_log_format(ab, " audit_enabled=%d res=0",
ns->audit.enabled);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
return -EPERM;
}
/* fallthrough */
@@ -783,12 +784,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
return -EINVAL;
if (ns->audit.enabled == AUDIT_LOCKED) {
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE,
+ audit_log_common_recv_msg(ns, &ab, AUDIT_CONFIG_CHANGE,
loginuid, sessionid, sid);
audit_log_format(ab, " audit_enabled=%d res=0",
ns->audit.enabled);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
return -EPERM;
}
/* fallthrough */
@@ -800,11 +801,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_TRIM:
audit_trim_trees();
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE,
+ audit_log_common_recv_msg(ns, &ab, AUDIT_CONFIG_CHANGE,
loginuid, sessionid, sid);
audit_log_format(ab, " op=trim res=1");
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
break;
case AUDIT_MAKE_EQUIV: {
void *bufp = data;
@@ -832,7 +833,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
/* OK, here comes... */
err = audit_tag_tree(old, new);
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE,
+ audit_log_common_recv_msg(ns, &ab, AUDIT_CONFIG_CHANGE,
loginuid, sessionid, sid);
audit_log_format(ab, " op=make_equiv old=");
@@ -840,7 +841,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_format(ab, " new=");
audit_log_untrustedstring(ab, new);
audit_log_format(ab, " res=%d", !err);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
kfree(old);
kfree(new);
break;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 22/48] Audit: Log audit config change in uninit user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (19 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 21/48] Audit: pass proper user namespace to audit_log_common_recv_msg Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 23/48] Audit: netfilter: Log xt table replace behavior in proper " Gao feng
` (12 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This patch allow to log audit config change in
uninit user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index c8329ce..cac4b21 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -251,7 +251,7 @@ static int audit_log_config_change(char *function_name, int new, int old,
struct user_namespace *ns = current_user_ns();
int rc = 0;
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return rc;
audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new,
@@ -270,7 +270,7 @@ static int audit_log_config_change(char *function_name, int new, int old,
}
}
audit_log_format(ab, " res=%d", allow_changes);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
return rc;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 23/48] Audit: netfilter: Log xt table replace behavior in proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (20 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 22/48] Audit: Log audit config change in uninit user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 24/48] Audit: xt_AUDIT: Log audit message " Gao feng
` (11 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Log the audit message in the user namespace which
current task belongs to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
net/netfilter/x_tables.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8b03028..ba90a1b 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -824,6 +824,7 @@ xt_replace_table(struct xt_table *table,
int *error)
{
struct xt_table_info *private;
+ struct user_namespace *ns = current_user_ns();
int ret;
ret = xt_jumpstack_alloc(newinfo);
@@ -857,16 +858,16 @@ xt_replace_table(struct xt_table *table,
local_bh_enable();
#ifdef CONFIG_AUDIT
- if (audit_enabled) {
+ if (audit_enabled_ns(ns)) {
struct audit_buffer *ab;
- ab = audit_log_start(current->audit_context, GFP_KERNEL,
- AUDIT_NETFILTER_CFG);
+ ab = audit_log_start_ns(ns, current->audit_context,
+ GFP_KERNEL, AUDIT_NETFILTER_CFG);
if (ab) {
audit_log_format(ab, "table=%s family=%u entries=%u",
table->name, table->af,
private->number);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
}
#endif
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 24/48] Audit: xt_AUDIT: Log audit message in proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (21 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 23/48] Audit: netfilter: Log xt table replace behavior in proper " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 25/48] Audit: send reply message to the auditd " Gao feng
` (10 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
we can log audit message in the user namespace which
netfilter xt_AUDIT rules belongs to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
net/netfilter/xt_AUDIT.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/xt_AUDIT.c b/net/netfilter/xt_AUDIT.c
index 3228d7f..b1ffba2 100644
--- a/net/netfilter/xt_AUDIT.c
+++ b/net/netfilter/xt_AUDIT.c
@@ -122,12 +122,14 @@ static unsigned int
audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_audit_info *info = par->targinfo;
+ struct net *net = dev_net(par->in ? par->in : par->out);
+ struct user_namespace *ns = net->user_ns;
struct audit_buffer *ab;
- if (audit_enabled == 0)
+ if (audit_enabled_ns(ns) == 0)
goto errout;
- ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
+ ab = audit_log_start_ns(ns, NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
if (ab == NULL)
goto errout;
@@ -172,7 +174,7 @@ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
audit_log_secctx(ab, skb->secmark);
#endif
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
errout:
return XT_CONTINUE;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 25/48] Audit: send reply message to the auditd in proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (22 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 24/48] Audit: xt_AUDIT: Log audit message " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 26/48] Audit: make audit_inode_hash per " Gao feng
` (9 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
We can send the audit reply message to userspace auditd
process which running in the same user namespace with the
process which send the audit request message to kernel.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index cac4b21..ca9e046 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -144,6 +144,7 @@ struct audit_buffer {
struct audit_reply {
int pid;
struct sk_buff *skb;
+ struct user_namespace *ns;
};
static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
@@ -517,8 +518,9 @@ static int audit_send_reply_thread(void *arg)
/* Ignore failure. It'll only happen if the sender goes away,
because our timeout is set to infinite. */
- netlink_unicast(init_user_ns.audit.sock, reply->skb,
+ netlink_unicast(reply->ns->audit.sock, reply->skb,
reply->pid, 0);
+ put_user_ns(reply->ns);
kfree(reply);
return 0;
}
@@ -552,11 +554,13 @@ static void audit_send_reply(int pid, int seq, int type, int done, int multi,
reply->pid = pid;
reply->skb = skb;
+ reply->ns = get_user_ns(current_user_ns());
tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
if (!IS_ERR(tsk))
return;
kfree_skb(skb);
+ put_user_ns(reply->ns);
out:
kfree(reply);
}
@@ -859,7 +863,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
security_release_secctx(ctx, len);
return -ENOMEM;
}
- sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
+ sig_data->uid = from_kuid(ns, audit_sig_uid);
sig_data->pid = audit_sig_pid;
if (audit_sig_sid) {
memcpy(sig_data->ctx, ctx, len);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 26/48] Audit: make audit_inode_hash per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (23 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 25/48] Audit: send reply message to the auditd " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 28/48] Audit: make audit filter list " Gao feng
` (8 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
audit_inode_hash is used to hash inode related audit rules,
and the audit rule should be per user namespace. So we
should make audit_inode_hash per user namespace too.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 2 ++
kernel/audit.c | 13 +++++--------
kernel/audit.h | 5 ++---
kernel/audit_watch.c | 5 +++--
kernel/auditfilter.c | 22 +++++++++++++---------
kernel/auditsc.c | 2 +-
6 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 5a778f8..c56e276 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -30,6 +30,8 @@ struct audit_ctrl {
struct task_struct *kauditd_task;
wait_queue_head_t kauditd_wait;
wait_queue_head_t backlog_wait;
+#define AUDIT_INODE_BUCKETS 32
+ struct list_head inode_hash[AUDIT_INODE_BUCKETS];
bool ever_enabled;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index ca9e046..d254827 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -107,9 +107,6 @@ u32 audit_sig_sid = 0;
*/
static atomic_t audit_lost = ATOMIC_INIT(0);
-/* Hash for inode-based rules */
-struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
-
/* The audit_freelist is a list of pre-allocated audit buffers (if more
* than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
* being placed on the freelist). */
@@ -989,8 +986,6 @@ static struct pernet_operations audit_net_ops = {
/* Initialize audit support at boot time. */
static int __init audit_init(void)
{
- int i;
-
if (init_user_ns.audit.initialized == AUDIT_DISABLED)
return 0;
@@ -1004,9 +999,6 @@ static int __init audit_init(void)
audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
- for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
- INIT_LIST_HEAD(&audit_inode_hash[i]);
-
return 0;
}
__initcall(audit_init);
@@ -1602,6 +1594,8 @@ EXPORT_SYMBOL(audit_log_secctx);
void audit_set_user_ns(struct user_namespace *ns)
{
+ int i;
+
if (init_user_ns.audit.initialized == AUDIT_DISABLED)
return;
@@ -1612,6 +1606,9 @@ void audit_set_user_ns(struct user_namespace *ns)
init_waitqueue_head(&ns->audit.kauditd_wait);
init_waitqueue_head(&ns->audit.backlog_wait);
+ for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
+ INIT_LIST_HEAD(&ns->audit.inode_hash[i]);
+
ns->audit.initialized = AUDIT_INITIALIZED;
}
diff --git a/kernel/audit.h b/kernel/audit.h
index ced93fe..a01c892 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -61,13 +61,12 @@ struct audit_entry {
extern int audit_ever_enabled;
-#define AUDIT_INODE_BUCKETS 32
-extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
-
+#ifdef CONFIG_AUDIT
static inline int audit_hash_ino(u32 ino)
{
return (ino & (AUDIT_INODE_BUCKETS-1));
}
+#endif
/* Indicates that audit should log the full pathname. */
#define AUDIT_NAME_FULL -1
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 22831c4..27c7a3b 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -309,7 +309,8 @@ static void audit_update_watch(struct audit_parent *parent,
audit_get_watch(nwatch);
nentry->rule.watch = nwatch;
list_add(&nentry->rule.rlist, &nwatch->rules);
- list_add_rcu(&nentry->list, &audit_inode_hash[h]);
+ list_add_rcu(&nentry->list,
+ &init_user_ns.audit.inode_hash[h]);
list_replace(&oentry->rule.list,
&nentry->rule.list);
}
@@ -441,7 +442,7 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)
audit_put_parent(parent);
h = audit_hash_ino((u32)watch->ino);
- *list = &audit_inode_hash[h];
+ *list = &init_user_ns.audit.inode_hash[h];
error:
path_put(&parent_path);
return ret;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 2674368..573385b 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -885,7 +885,8 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
/* Find an existing audit rule.
* Caller must hold audit_filter_mutex to prevent stale rule data. */
-static struct audit_entry *audit_find_rule(struct audit_entry *entry,
+static struct audit_entry *audit_find_rule(struct user_namespace *ns,
+ struct audit_entry *entry,
struct list_head **p)
{
struct audit_entry *e, *found = NULL;
@@ -894,11 +895,11 @@ static struct audit_entry *audit_find_rule(struct audit_entry *entry,
if (entry->rule.inode_f) {
h = audit_hash_ino(entry->rule.inode_f->val);
- *p = list = &audit_inode_hash[h];
+ *p = list = &ns->audit.inode_hash[h];
} else if (entry->rule.watch) {
/* we don't know the inode number, so must walk entire hash */
for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
- list = &audit_inode_hash[h];
+ list = &ns->audit.inode_hash[h];
list_for_each_entry(e, list, list)
if (!audit_compare_rule(&entry->rule, &e->rule)) {
found = e;
@@ -924,7 +925,8 @@ static u64 prio_low = ~0ULL/2;
static u64 prio_high = ~0ULL/2 - 1;
/* Add rule to given filterlist if not a duplicate. */
-static inline int audit_add_rule(struct audit_entry *entry)
+static inline int audit_add_rule(struct user_namespace *ns,
+ struct audit_entry *entry)
{
struct audit_entry *e;
struct audit_watch *watch = entry->rule.watch;
@@ -941,7 +943,7 @@ static inline int audit_add_rule(struct audit_entry *entry)
#endif
mutex_lock(&audit_filter_mutex);
- e = audit_find_rule(entry, &list);
+ e = audit_find_rule(ns, entry, &list);
if (e) {
mutex_unlock(&audit_filter_mutex);
err = -EEXIST;
@@ -1003,7 +1005,8 @@ error:
}
/* Remove an existing rule from filterlist. */
-static inline int audit_del_rule(struct audit_entry *entry)
+static inline int audit_del_rule(struct user_namespace *ns,
+ struct audit_entry *entry)
{
struct audit_entry *e;
struct audit_watch *watch = entry->rule.watch;
@@ -1020,7 +1023,7 @@ static inline int audit_del_rule(struct audit_entry *entry)
#endif
mutex_lock(&audit_filter_mutex);
- e = audit_find_rule(entry, &list);
+ e = audit_find_rule(ns, entry, &list);
if (!e) {
mutex_unlock(&audit_filter_mutex);
ret = -ENOENT;
@@ -1162,6 +1165,7 @@ int audit_receive_filter(int type, int pid, int seq, void *data,
struct audit_netlink_list *dest;
int err = 0;
struct audit_entry *entry;
+ struct user_namespace *ns = current_user_ns();
switch (type) {
case AUDIT_LIST:
@@ -1201,7 +1205,7 @@ int audit_receive_filter(int type, int pid, int seq, void *data,
if (IS_ERR(entry))
return PTR_ERR(entry);
- err = audit_add_rule(entry);
+ err = audit_add_rule(ns, entry);
audit_log_rule_change(loginuid, sessionid, sid, "add rule",
&entry->rule, !err);
@@ -1217,7 +1221,7 @@ int audit_receive_filter(int type, int pid, int seq, void *data,
if (IS_ERR(entry))
return PTR_ERR(entry);
- err = audit_del_rule(entry);
+ err = audit_del_rule(ns, entry);
audit_log_rule_change(loginuid, sessionid, sid, "remove rule",
&entry->rule, !err);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 290cce6..55bd99e 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -902,7 +902,7 @@ static int audit_filter_inode_name(struct task_struct *tsk,
struct audit_context *ctx) {
int word, bit;
int h = audit_hash_ino((u32)n->ino);
- struct list_head *list = &audit_inode_hash[h];
+ struct list_head *list = &init_user_ns.audit.inode_hash[h];
struct audit_entry *e;
enum audit_state state;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 28/48] Audit: make audit filter list per user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (24 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 26/48] Audit: make audit_inode_hash per " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 29/48] Audit: make audit_krule belongs to " Gao feng
` (7 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This patch just make the audit filter list per user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/user_namespace.h | 2 ++
kernel/audit.c | 4 ++++
kernel/auditfilter.c | 23 +++++++----------------
kernel/auditsc.c | 12 +++++++++---
kernel/user.c | 19 +++++++++++++++++++
5 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index c870e28..d1dd5b9 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -6,6 +6,7 @@
#include <linux/sched.h>
#include <linux/err.h>
#include <linux/skbuff.h>
+#include <uapi/linux/audit.h>
#define UID_GID_MAP_MAX_EXTENTS 5
@@ -33,6 +34,7 @@ struct audit_ctrl {
#define AUDIT_INODE_BUCKETS 32
struct list_head inode_hash[AUDIT_INODE_BUCKETS];
struct list_head tree_list;
+ struct list_head filter_list[AUDIT_NR_FILTERS];
bool ever_enabled;
};
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index a0544b1..1ca1714 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1609,6 +1609,10 @@ void audit_set_user_ns(struct user_namespace *ns)
for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
INIT_LIST_HEAD(&ns->audit.inode_hash[i]);
+ if (ns != &init_user_ns)
+ for (i = 0; i < AUDIT_NR_FILTERS; i++)
+ INIT_LIST_HEAD(&ns->audit.filter_list[i]);
+
INIT_LIST_HEAD(&ns->audit.tree_list);
ns->audit.initialized = AUDIT_INITIALIZED;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 3c8fb2e..dbf05a9 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -44,18 +44,6 @@
* be written directly provided audit_filter_mutex is held.
*/
-/* Audit filter lists, defined in <linux/audit.h> */
-struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
- LIST_HEAD_INIT(audit_filter_list[0]),
- LIST_HEAD_INIT(audit_filter_list[1]),
- LIST_HEAD_INIT(audit_filter_list[2]),
- LIST_HEAD_INIT(audit_filter_list[3]),
- LIST_HEAD_INIT(audit_filter_list[4]),
- LIST_HEAD_INIT(audit_filter_list[5]),
-#if AUDIT_NR_FILTERS != 6
-#error Fix audit_filter_list initialiser
-#endif
-};
static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
LIST_HEAD_INIT(audit_rules_list[0]),
LIST_HEAD_INIT(audit_rules_list[1]),
@@ -908,7 +896,7 @@ static struct audit_entry *audit_find_rule(struct user_namespace *ns,
}
goto out;
} else {
- *p = list = &audit_filter_list[entry->rule.listnr];
+ *p = list = &ns->audit.filter_list[entry->rule.listnr];
}
list_for_each_entry(e, list, list)
@@ -1416,10 +1404,12 @@ int audit_filter_user(void)
{
enum audit_state state = AUDIT_DISABLED;
struct audit_entry *e;
+ struct user_namespace *ns = current_user_ns();
int ret = 1;
rcu_read_lock();
- list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
+ list_for_each_entry_rcu(e, &ns->audit.filter_list[AUDIT_FILTER_USER],
+ list) {
if (audit_filter_user_rules(&e->rule, &state)) {
if (state == AUDIT_DISABLED)
ret = 0;
@@ -1434,13 +1424,14 @@ int audit_filter_user(void)
int audit_filter_type(int type)
{
struct audit_entry *e;
+ struct user_namespace *ns = current_user_ns();
int result = 0;
rcu_read_lock();
- if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
+ if (list_empty(&ns->audit.filter_list[AUDIT_FILTER_TYPE]))
goto unlock_and_return;
- list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
+ list_for_each_entry_rcu(e, &ns->audit.filter_list[AUDIT_FILTER_TYPE],
list) {
int i;
for (i = 0; i < e->rule.field_count; i++) {
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 55bd99e..29c3e05 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -844,9 +844,11 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
{
struct audit_entry *e;
enum audit_state state;
+ struct user_namespace *ns = current_user_ns();
rcu_read_lock();
- list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
+ list_for_each_entry_rcu(e, &ns->audit.filter_list[AUDIT_FILTER_TASK],
+ list) {
if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
&state, true)) {
if (state == AUDIT_RECORD_CONTEXT)
@@ -949,6 +951,7 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
long return_code)
{
struct audit_context *context = tsk->audit_context;
+ struct user_namespace *ns = task_cred_xxx(tsk, user_ns);
if (!context)
return NULL;
@@ -973,7 +976,8 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
context->return_code = return_code;
if (context->in_syscall && !context->dummy) {
- audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
+ audit_filter_syscall(tsk, context,
+ &ns->audit.filter_list[AUDIT_FILTER_EXIT]);
audit_filter_inodes(tsk, context);
}
@@ -1759,6 +1763,7 @@ void __audit_syscall_entry(int arch, int major,
struct task_struct *tsk = current;
struct audit_context *context = tsk->audit_context;
enum audit_state state;
+ struct user_namespace *ns = current_user_ns();
if (!context)
return;
@@ -1779,7 +1784,8 @@ void __audit_syscall_entry(int arch, int major,
context->dummy = !audit_n_rules;
if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
context->prio = 0;
- state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
+ state = audit_filter_syscall(tsk, context,
+ &ns->audit.filter_list[AUDIT_FILTER_ENTRY]);
}
if (state == AUDIT_DISABLED)
return;
diff --git a/kernel/user.c b/kernel/user.c
index 69b4c3d..637bd39 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -51,6 +51,25 @@ struct user_namespace init_user_ns = {
.owner = GLOBAL_ROOT_UID,
.group = GLOBAL_ROOT_GID,
.proc_inum = PROC_USER_INIT_INO,
+#ifdef CONFIG_AUDIT
+ .audit = {
+ .filter_list[0] =
+ LIST_HEAD_INIT(init_user_ns.audit.filter_list[0]),
+ .filter_list[1] =
+ LIST_HEAD_INIT(init_user_ns.audit.filter_list[1]),
+ .filter_list[2] =
+ LIST_HEAD_INIT(init_user_ns.audit.filter_list[2]),
+ .filter_list[3] =
+ LIST_HEAD_INIT(init_user_ns.audit.filter_list[3]),
+ .filter_list[4] =
+ LIST_HEAD_INIT(init_user_ns.audit.filter_list[4]),
+ .filter_list[5] =
+ LIST_HEAD_INIT(init_user_ns.audit.filter_list[5]),
+#if AUDIT_NR_FILTERS != 6
+#error Fix audit_filter_list of init_user_ns initialiser
+#endif
+ },
+#endif
.may_mount_sysfs = true,
.may_mount_proc = true,
};
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 29/48] Audit: make audit_krule belongs to user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (25 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 28/48] Audit: make audit filter list " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 30/48] Audit: reply audit filter list request to proper " Gao feng
` (6 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Since update_lsm_rules will update all audit_krule, we still
have to make audit_rules_list global. this patch add a field
user_ns to struct audit_krule to point out which user namespace
this audit rule belongs to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
include/linux/audit.h | 1 +
kernel/auditfilter.c | 19 +++++++++++++++----
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index f16db07..885e842 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -59,6 +59,7 @@ struct audit_krule {
struct audit_field *inode_f; /* quick access to an inode field */
struct audit_watch *watch; /* associated watch */
struct audit_tree *tree; /* associated watched tree */
+ struct user_namespace *user_ns; /* belongs to this user namespace */
struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
struct list_head list; /* for AUDIT_LIST* purposes only */
u64 prio;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index dbf05a9..cf7fe98 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -822,6 +822,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
new->buflen = old->buflen;
new->inode_f = old->inode_f;
new->field_count = old->field_count;
+ new->user_ns = old->user_ns;
/*
* note that we are OK with not refcounting here; audit_match_tree()
@@ -965,6 +966,7 @@ static inline int audit_add_rule(struct user_namespace *ns,
entry->rule.prio = --prio_low;
}
+ entry->rule.user_ns = get_user_ns(ns);
if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
list_add(&entry->rule.list,
&audit_rules_list[entry->rule.listnr]);
@@ -1026,6 +1028,7 @@ static inline int audit_del_rule(struct user_namespace *ns,
list_del_rcu(&e->list);
list_del(&e->rule.list);
+ put_user_ns(e->rule.user_ns);
call_rcu(&e->rcu, audit_free_rule_rcu);
#ifdef CONFIG_AUDITSYSCALL
@@ -1048,7 +1051,8 @@ out:
/* List rules using struct audit_rule. Exists for backward
* compatibility with userspace. */
-static void audit_list(int pid, int seq, struct sk_buff_head *q)
+static void audit_list(struct user_namespace *ns,
+ int pid, int seq, struct sk_buff_head *q)
{
struct sk_buff *skb;
struct audit_krule *r;
@@ -1060,6 +1064,9 @@ static void audit_list(int pid, int seq, struct sk_buff_head *q)
list_for_each_entry(r, &audit_rules_list[i], list) {
struct audit_rule *rule;
+ if (r->user_ns != ns)
+ continue;
+
rule = audit_krule_to_rule(r);
if (unlikely(!rule))
break;
@@ -1076,7 +1083,8 @@ static void audit_list(int pid, int seq, struct sk_buff_head *q)
}
/* List rules using struct audit_rule_data. */
-static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
+static void audit_list_rules(struct user_namespace *ns,
+ int pid, int seq, struct sk_buff_head *q)
{
struct sk_buff *skb;
struct audit_krule *r;
@@ -1088,6 +1096,9 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
list_for_each_entry(r, &audit_rules_list[i], list) {
struct audit_rule_data *data;
+ if (r->user_ns != ns)
+ continue;
+
data = audit_krule_to_data(r);
if (unlikely(!data))
break;
@@ -1172,9 +1183,9 @@ int audit_receive_filter(int type, int pid, int seq, void *data,
mutex_lock(&audit_filter_mutex);
if (type == AUDIT_LIST)
- audit_list(pid, seq, &dest->q);
+ audit_list(ns, pid, seq, &dest->q);
else
- audit_list_rules(pid, seq, &dest->q);
+ audit_list_rules(ns, pid, seq, &dest->q);
mutex_unlock(&audit_filter_mutex);
tsk = kthread_run(audit_send_list, dest, "audit_send_list");
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 30/48] Audit: reply audit filter list request to proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (26 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 29/48] Audit: make audit_krule belongs to " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 32/48] Audit: pass proper user namespace to audit_filter_inode_name Gao feng
` (5 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
We should reply the audit filter list request to the proper
user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 3 ++-
kernel/audit.h | 1 +
kernel/auditfilter.c | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 1ca1714..f723fe2 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -474,8 +474,9 @@ int audit_send_list(void *_dest)
mutex_unlock(&audit_cmd_mutex);
while ((skb = __skb_dequeue(&dest->q)) != NULL)
- netlink_unicast(init_user_ns.audit.sock, skb, pid, 0);
+ netlink_unicast(dest->user_ns->audit.sock, skb, pid, 0);
+ put_user_ns(dest->user_ns);
kfree(dest);
return 0;
diff --git a/kernel/audit.h b/kernel/audit.h
index a509796..7934598 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -85,6 +85,7 @@ extern void audit_panic(const char *message);
struct audit_netlink_list {
int pid;
struct sk_buff_head q;
+ struct user_namespace *user_ns;
};
int audit_send_list(void *);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index cf7fe98..f2afe9b 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1180,6 +1180,7 @@ int audit_receive_filter(int type, int pid, int seq, void *data,
return -ENOMEM;
dest->pid = pid;
skb_queue_head_init(&dest->q);
+ dest->user_ns = get_user_ns(ns);
mutex_lock(&audit_filter_mutex);
if (type == AUDIT_LIST)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 32/48] Audit: pass proper user namespace to audit_filter_inode_name
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (27 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 30/48] Audit: reply audit filter list request to proper " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 34/48] Log audit tree related message in proper user namespace Gao feng
` (4 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
We should use the right inode_hash list to filter the
task.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.h | 5 +++--
kernel/audit_watch.c | 3 ++-
kernel/auditsc.c | 14 ++++++++------
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index 7934598..0079cdd 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -157,11 +157,12 @@ static inline int audit_signal_info(int sig, struct task_struct *t)
return __audit_signal_info(sig, t);
return 0;
}
-extern void audit_filter_inodes(struct task_struct *, struct audit_context *);
+extern void audit_filter_inodes(struct user_namespace *ns,
+ struct task_struct *, struct audit_context *);
extern struct list_head *audit_killed_trees(void);
#else
#define audit_signal_info(s,t) AUDIT_DISABLED
-#define audit_filter_inodes(t,c) AUDIT_DISABLED
+#define audit_filter_inodes(n, t, c) AUDIT_DISABLED
#endif
extern struct mutex audit_cmd_mutex;
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 27c7a3b..6be4cbe 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -274,7 +274,8 @@ static void audit_update_watch(struct audit_parent *parent,
/* If the update involves invalidating rules, do the inode-based
* filtering now, so we don't omit records. */
if (invalidating && !audit_dummy_context())
- audit_filter_inodes(current, current->audit_context);
+ audit_filter_inodes(current_user_ns(), current,
+ current->audit_context);
/* updating ino will likely change which audit_hash_list we
* are on so we need a new watch for the new list */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 5401d21..3e3e7c7 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -900,12 +900,13 @@ static enum audit_state audit_filter_syscall(struct user_namespace *ns,
* Given an audit_name check the inode hash table to see if they match.
* Called holding the rcu read lock to protect the use of audit_inode_hash
*/
-static int audit_filter_inode_name(struct task_struct *tsk,
+static int audit_filter_inode_name(struct user_namespace *ns,
+ struct task_struct *tsk,
struct audit_names *n,
struct audit_context *ctx) {
int word, bit;
int h = audit_hash_ino((u32)n->ino);
- struct list_head *list = &init_user_ns.audit.inode_hash[h];
+ struct list_head *list = &ns->audit.inode_hash[h];
struct audit_entry *e;
enum audit_state state;
@@ -931,17 +932,18 @@ static int audit_filter_inode_name(struct task_struct *tsk,
* buckets applicable to the inode numbers in audit_names.
* Regarding audit_state, same rules apply as for audit_filter_syscall().
*/
-void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
+void audit_filter_inodes(struct user_namespace *ns,
+ struct task_struct *tsk, struct audit_context *ctx)
{
struct audit_names *n;
- if (init_user_ns.audit.pid && tsk->tgid == init_user_ns.audit.pid)
+ if (ns->audit.pid && tsk->tgid == ns->audit.pid)
return;
rcu_read_lock();
list_for_each_entry(n, &ctx->names_list, list) {
- if (audit_filter_inode_name(tsk, n, ctx))
+ if (audit_filter_inode_name(ns, tsk, n, ctx))
break;
}
rcu_read_unlock();
@@ -979,7 +981,7 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
if (context->in_syscall && !context->dummy) {
audit_filter_syscall(ns, tsk, context,
&ns->audit.filter_list[AUDIT_FILTER_EXIT]);
- audit_filter_inodes(tsk, context);
+ audit_filter_inodes(ns, tsk, context);
}
tsk->audit_context = NULL;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 34/48] Log audit tree related message in proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (28 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 32/48] Audit: pass proper user namespace to audit_filter_inode_name Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 35/48] Audit: Log task related audit message to " Gao feng
` (3 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Now, we can log audit tree related message in the right
user namespace.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.h | 4 ++--
kernel/audit_tree.c | 27 ++++++++++++++-------------
kernel/auditsc.c | 6 ++++--
3 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index 0079cdd..64ee671 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -129,7 +129,7 @@ extern void audit_trim_trees(void);
extern int audit_tag_tree(char *old, char *new);
extern const char *audit_tree_path(struct audit_tree *);
extern void audit_put_tree(struct audit_tree *);
-extern void audit_kill_trees(struct list_head *);
+extern void audit_kill_trees(struct user_namespace *ns, struct list_head *);
#else
#define audit_remove_tree_rule(rule) BUG()
#define audit_add_tree_rule(ns, rule) -EINVAL
@@ -138,7 +138,7 @@ extern void audit_kill_trees(struct list_head *);
#define audit_put_tree(tree) (void)0
#define audit_tag_tree(old, new) -EINVAL
#define audit_tree_path(rule) "" /* never called */
-#define audit_kill_trees(list) BUG()
+#define audit_kill_trees(ns, list) BUG()
#endif
extern char *audit_unpack_string(void **, size_t *, size_t);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 4531d73..521766d 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -448,11 +448,12 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
return 0;
}
-static void audit_log_remove_rule(struct audit_krule *rule)
+static void audit_log_remove_rule(struct user_namespace *ns,
+ struct audit_krule *rule)
{
struct audit_buffer *ab;
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return;
audit_log_format(ab, "op=");
@@ -461,10 +462,10 @@ static void audit_log_remove_rule(struct audit_krule *rule)
audit_log_untrustedstring(ab, rule->tree->pathname);
audit_log_key(ab, rule->filterkey);
audit_log_format(ab, " list=%d res=1", rule->listnr);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
-static void kill_rules(struct audit_tree *tree)
+static void kill_rules(struct user_namespace *ns, struct audit_tree *tree)
{
struct audit_krule *rule, *next;
struct audit_entry *entry;
@@ -475,7 +476,7 @@ static void kill_rules(struct audit_tree *tree)
list_del_init(&rule->rlist);
if (rule->tree) {
/* not a half-baked one */
- audit_log_remove_rule(rule);
+ audit_log_remove_rule(ns, rule);
rule->tree = NULL;
list_del_rcu(&entry->list);
list_del(&entry->rule.list);
@@ -503,7 +504,7 @@ static void prune_one(struct audit_tree *victim)
/* trim the uncommitted chunks from tree */
-static void trim_marked(struct audit_tree *tree)
+static void trim_marked(struct user_namespace *ns, struct audit_tree *tree)
{
struct list_head *p, *q;
spin_lock(&hash_lock);
@@ -536,7 +537,7 @@ static void trim_marked(struct audit_tree *tree)
tree->goner = 1;
spin_unlock(&hash_lock);
mutex_lock(&audit_filter_mutex);
- kill_rules(tree);
+ kill_rules(ns, tree);
list_del_init(&tree->list);
mutex_unlock(&audit_filter_mutex);
prune_one(tree);
@@ -616,7 +617,7 @@ void audit_trim_trees(void)
node->index &= ~(1U<<31);
}
spin_unlock(&hash_lock);
- trim_marked(tree);
+ trim_marked(current_user_ns(), tree);
drop_collected_mounts(root_mnt);
skip_it:
put_tree(tree);
@@ -693,7 +694,7 @@ int audit_add_tree_rule(struct user_namespace *ns, struct audit_krule *rule)
node->index &= ~(1U<<31);
spin_unlock(&hash_lock);
} else {
- trim_marked(tree);
+ trim_marked(ns, tree);
goto Err;
}
@@ -797,7 +798,7 @@ int audit_tag_tree(char *old, char *new)
node->index &= ~(1U<<31);
spin_unlock(&hash_lock);
} else {
- trim_marked(tree);
+ trim_marked(ns, tree);
}
put_tree(tree);
@@ -847,7 +848,7 @@ static void audit_schedule_prune(void)
* ... and that one is done if evict_chunk() decides to delay until the end
* of syscall. Runs synchronously.
*/
-void audit_kill_trees(struct list_head *list)
+void audit_kill_trees(struct user_namespace *ns, struct list_head *list)
{
mutex_lock(&audit_cmd_mutex);
mutex_lock(&audit_filter_mutex);
@@ -856,7 +857,7 @@ void audit_kill_trees(struct list_head *list)
struct audit_tree *victim;
victim = list_entry(list->next, struct audit_tree, list);
- kill_rules(victim);
+ kill_rules(ns, victim);
list_del_init(&victim->list);
mutex_unlock(&audit_filter_mutex);
@@ -895,7 +896,7 @@ static void evict_chunk(struct audit_chunk *chunk)
list_del_init(&owner->same_root);
spin_unlock(&hash_lock);
if (!postponed) {
- kill_rules(owner);
+ kill_rules(current_user_ns(), owner);
list_move(&owner->list, &prune_list);
need_prune = 1;
} else {
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 3e3e7c7..544eb82 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1737,7 +1737,8 @@ void __audit_free(struct task_struct *tsk)
if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
audit_log_exit(context, tsk);
if (!list_empty(&context->killed_trees))
- audit_kill_trees(&context->killed_trees);
+ audit_kill_trees(task_cred_xxx(tsk, user_ns),
+ &context->killed_trees);
audit_free_context(context);
}
@@ -1815,6 +1816,7 @@ void __audit_syscall_exit(int success, long return_code)
{
struct task_struct *tsk = current;
struct audit_context *context;
+ struct user_namespace *ns = current_user_ns();
if (success)
success = AUDITSC_SUCCESS;
@@ -1832,7 +1834,7 @@ void __audit_syscall_exit(int success, long return_code)
context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
if (!list_empty(&context->killed_trees))
- audit_kill_trees(&context->killed_trees);
+ audit_kill_trees(ns, &context->killed_trees);
audit_free_names(context);
unroll_tree_refs(context, NULL, 0);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 35/48] Audit: Log task related audit message to proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (29 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 34/48] Log audit tree related message in proper user namespace Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 36/48] Audit: Log watch " Gao feng
` (2 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Now, we can log task related audit message to the user namespace
which the task belongs to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/auditsc.c | 114 +++++++++++++++++++++++++++++++------------------------
1 file changed, 64 insertions(+), 50 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 544eb82..3c5ced9 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1185,7 +1185,8 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
EXPORT_SYMBOL(audit_log_task_info);
-static int audit_log_pid_context(struct audit_context *context, pid_t pid,
+static int audit_log_pid_context(struct user_namespace *ns,
+ struct audit_context *context, pid_t pid,
kuid_t auid, kuid_t uid, unsigned int sessionid,
u32 sid, char *comm)
{
@@ -1194,13 +1195,13 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
u32 len;
int rc = 0;
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_OBJ_PID);
if (!ab)
return rc;
audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
- from_kuid(&init_user_ns, auid),
- from_kuid(&init_user_ns, uid), sessionid);
+ from_kuid(ns, auid),
+ from_kuid(ns, uid), sessionid);
if (security_secid_to_secctx(sid, &ctx, &len)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
@@ -1210,7 +1211,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
}
audit_log_format(ab, " ocomm=");
audit_log_untrustedstring(ab, comm);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
return rc;
}
@@ -1240,6 +1241,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
size_t len, len_left, to_send;
size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
unsigned int i, has_cntl = 0, too_long = 0;
+ struct user_namespace *ns;
int ret;
/* strnlen_user includes the null we don't want to send */
@@ -1293,6 +1295,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
if (len > max_execve_audit_len)
too_long = 1;
+ ns = current_user_ns();
/* rewalk the argument actually logging the message */
for (i = 0; len_left > 0; i++) {
int room_left;
@@ -1310,8 +1313,9 @@ static int audit_log_single_execve_arg(struct audit_context *context,
room_left -= to_send;
if (room_left < 0) {
*len_sent = 0;
- audit_log_end(*ab);
- *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE);
+ audit_log_end_ns(ns, *ab);
+ *ab = audit_log_start_ns(ns, context,
+ GFP_KERNEL, AUDIT_EXECVE);
if (!*ab)
return 0;
}
@@ -1429,12 +1433,13 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver);
}
-static void show_special(struct audit_context *context, int *call_panic)
+static void show_special(struct user_namespace *ns,
+ struct audit_context *context, int *call_panic)
{
struct audit_buffer *ab;
int i;
- ab = audit_log_start(context, GFP_KERNEL, context->type);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, context->type);
if (!ab)
return;
@@ -1465,9 +1470,9 @@ static void show_special(struct audit_context *context, int *call_panic)
}
}
if (context->ipc.has_perm) {
- audit_log_end(ab);
- ab = audit_log_start(context, GFP_KERNEL,
- AUDIT_IPC_SET_PERM);
+ audit_log_end_ns(ns, ab);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL,
+ AUDIT_IPC_SET_PERM);
if (unlikely(!ab))
return;
audit_log_format(ab,
@@ -1523,14 +1528,15 @@ static void show_special(struct audit_context *context, int *call_panic)
context->mmap.flags);
break; }
}
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
-static void audit_log_name(struct audit_context *context, struct audit_names *n,
+static void audit_log_name(struct user_namespace *ns,
+ struct audit_context *context, struct audit_names *n,
int record_num, int *call_panic)
{
struct audit_buffer *ab;
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_PATH);
if (!ab)
return; /* audit_panic has been called */
@@ -1565,8 +1571,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
MAJOR(n->dev),
MINOR(n->dev),
n->mode,
- from_kuid(&init_user_ns, n->uid),
- from_kgid(&init_user_ns, n->gid),
+ from_kuid(ns, n->uid),
+ from_kgid(ns, n->gid),
MAJOR(n->rdev),
MINOR(n->rdev));
}
@@ -1585,7 +1591,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
audit_log_fcaps(ab, n);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
@@ -1594,11 +1600,12 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
struct audit_buffer *ab;
struct audit_aux_data *aux;
struct audit_names *n;
+ struct user_namespace *ns = task_cred_xxx(tsk, user_ns);
/* tsk == current */
context->personality = tsk->personality;
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_SYSCALL);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "arch=%x syscall=%d",
@@ -1620,11 +1627,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_task_info(ab, tsk);
audit_log_key(ab, context->filterkey);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
for (aux = context->aux; aux; aux = aux->next) {
- ab = audit_log_start(context, GFP_KERNEL, aux->type);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, aux->type);
if (!ab)
continue; /* audit_panic has been called */
@@ -1650,28 +1657,28 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
break; }
}
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
if (context->type)
- show_special(context, &call_panic);
+ show_special(ns, context, &call_panic);
if (context->fds[0] >= 0) {
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_FD_PAIR);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_FD_PAIR);
if (ab) {
audit_log_format(ab, "fd0=%d fd1=%d",
context->fds[0], context->fds[1]);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
}
if (context->sockaddr_len) {
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_SOCKADDR);
if (ab) {
audit_log_format(ab, "saddr=");
audit_log_n_hex(ab, (void *)context->sockaddr,
context->sockaddr_len);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
}
@@ -1679,7 +1686,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
struct audit_aux_data_pids *axs = (void *)aux;
for (i = 0; i < axs->pid_count; i++)
- if (audit_log_pid_context(context, axs->target_pid[i],
+ if (audit_log_pid_context(ns, context,
+ axs->target_pid[i],
axs->target_auid[i],
axs->target_uid[i],
axs->target_sessionid[i],
@@ -1689,28 +1697,28 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
}
if (context->target_pid &&
- audit_log_pid_context(context, context->target_pid,
+ audit_log_pid_context(ns, context, context->target_pid,
context->target_auid, context->target_uid,
context->target_sessionid,
context->target_sid, context->target_comm))
call_panic = 1;
if (context->pwd.dentry && context->pwd.mnt) {
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_CWD);
if (ab) {
audit_log_d_path(ab, " cwd=", &context->pwd);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
}
i = 0;
list_for_each_entry(n, &context->names_list, list)
- audit_log_name(context, n, i++, &call_panic);
+ audit_log_name(ns, context, n, i++, &call_panic);
/* Send end of event record to help user space know we are finished */
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
+ ab = audit_log_start_ns(ns, context, GFP_KERNEL, AUDIT_EOE);
if (ab)
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
if (call_panic)
audit_panic("error converting sid to string");
}
@@ -2327,8 +2335,9 @@ int audit_set_loginuid(kuid_t loginuid)
sessionid = atomic_inc_return(&session_id);
if (context && context->in_syscall) {
struct audit_buffer *ab;
+ struct user_namespace *ns = current_user_ns();
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
+ ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, AUDIT_LOGIN);
if (ab) {
audit_log_format(ab, "login pid=%d uid=%u "
"old auid=%u new auid=%u"
@@ -2338,7 +2347,7 @@ int audit_set_loginuid(kuid_t loginuid)
from_kuid(&init_user_ns, task->loginuid),
from_kuid(&init_user_ns, loginuid),
task->sessionid, sessionid);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
}
task->sessionid = sessionid;
@@ -2560,8 +2569,9 @@ int __audit_signal_info(int sig, struct task_struct *t)
struct task_struct *tsk = current;
struct audit_context *ctx = tsk->audit_context;
kuid_t uid = current_uid(), t_uid = task_uid(t);
+ int audit_pid = current_user_ns()->audit.pid;
- if (init_user_ns.audit.pid && t->tgid == init_user_ns.audit.pid) {
+ if (audit_pid && t->tgid == audit_pid) {
if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
audit_sig_pid = tsk->pid;
if (uid_valid(tsk->loginuid))
@@ -2683,7 +2693,8 @@ void __audit_mmap_fd(int fd, int flags)
context->type = AUDIT_MMAP;
}
-static void audit_log_task(struct audit_buffer *ab)
+static void audit_log_task(struct user_namespace *ns,
+ struct audit_buffer *ab)
{
kuid_t auid, uid;
kgid_t gid;
@@ -2694,18 +2705,19 @@ static void audit_log_task(struct audit_buffer *ab)
current_uid_gid(&uid, &gid);
audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
- from_kuid(&init_user_ns, auid),
- from_kuid(&init_user_ns, uid),
- from_kgid(&init_user_ns, gid),
+ from_kuid(ns, auid),
+ from_kuid(ns, uid),
+ from_kgid(ns, gid),
sessionid);
audit_log_task_context(ab);
audit_log_format(ab, " pid=%d comm=", current->pid);
audit_log_untrustedstring(ab, current->comm);
}
-static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
+static void audit_log_abend(struct user_namespace *ns,
+ struct audit_buffer *ab, char *reason, long signr)
{
- audit_log_task(ab);
+ audit_log_task(ns, ab);
audit_log_format(ab, " reason=");
audit_log_string(ab, reason);
audit_log_format(ab, " sig=%ld", signr);
@@ -2720,34 +2732,36 @@ static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
void audit_core_dumps(long signr)
{
struct audit_buffer *ab;
+ struct user_namespace *ns = current_user_ns();
- if (!audit_enabled)
+ if (!audit_enabled_ns(ns))
return;
if (signr == SIGQUIT) /* don't care for those */
return;
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
+ ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
if (unlikely(!ab))
return;
- audit_log_abend(ab, "memory violation", signr);
- audit_log_end(ab);
+ audit_log_abend(ns, ab, "memory violation", signr);
+ audit_log_end_ns(ns, ab);
}
void __audit_seccomp(unsigned long syscall, long signr, int code)
{
struct audit_buffer *ab;
+ struct user_namespace *ns = current_user_ns();
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP);
+ ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, AUDIT_SECCOMP);
if (unlikely(!ab))
return;
- audit_log_task(ab);
+ audit_log_task(ns, ab);
audit_log_format(ab, " sig=%ld", signr);
audit_log_format(ab, " syscall=%ld", syscall);
audit_log_format(ab, " compat=%d", is_compat_task());
audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
audit_log_format(ab, " code=0x%x", code);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
struct list_head *audit_killed_trees(void)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 36/48] Audit: Log watch related audit message to proper user namespace
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (30 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 35/48] Audit: Log task related audit message to " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:20 ` [PATCH RFC 37/48] Audit: translate audit_log_start to audit_log_start_ns Gao feng
2013-05-07 2:21 ` [PATCH RFC 40/48] Audit: ima: " Gao feng
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Now, we can log watch related audit message to the user namespace
which the task belongs to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit_watch.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 6be4cbe..1bac505 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -235,22 +235,26 @@ out:
return new;
}
-static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watch *w, char *op)
+static void audit_watch_log_rule_change(struct audit_krule *r,
+ struct audit_watch *w, char *op)
{
- if (audit_enabled) {
+ struct user_namespace *ns = current_user_ns();
+
+ if (audit_enabled_ns(ns)) {
struct audit_buffer *ab;
- ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start_ns(ns, NULL, GFP_NOFS,
+ AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return;
audit_log_format(ab, "auid=%u ses=%u op=",
- from_kuid(&init_user_ns, audit_get_loginuid(current)),
+ from_kuid(ns, audit_get_loginuid(current)),
audit_get_sessionid(current));
audit_log_string(ab, op);
audit_log_format(ab, " path=");
audit_log_untrustedstring(ab, w->path);
audit_log_key(ab, r->filterkey);
audit_log_format(ab, " list=%d res=1", r->listnr);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
}
@@ -262,6 +266,7 @@ static void audit_update_watch(struct audit_parent *parent,
struct audit_watch *owatch, *nwatch, *nextw;
struct audit_krule *r, *nextr;
struct audit_entry *oentry, *nentry;
+ struct user_namespace *ns = current_user_ns();
mutex_lock(&audit_filter_mutex);
/* Run all of the watches on this parent looking for the one that
@@ -274,7 +279,7 @@ static void audit_update_watch(struct audit_parent *parent,
/* If the update involves invalidating rules, do the inode-based
* filtering now, so we don't omit records. */
if (invalidating && !audit_dummy_context())
- audit_filter_inodes(current_user_ns(), current,
+ audit_filter_inodes(ns, current,
current->audit_context);
/* updating ino will likely change which audit_hash_list we
@@ -311,7 +316,7 @@ static void audit_update_watch(struct audit_parent *parent,
nentry->rule.watch = nwatch;
list_add(&nentry->rule.rlist, &nwatch->rules);
list_add_rcu(&nentry->list,
- &init_user_ns.audit.inode_hash[h]);
+ &ns->audit.inode_hash[h]);
list_replace(&oentry->rule.list,
&nentry->rule.list);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 37/48] Audit: translate audit_log_start to audit_log_start_ns
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (31 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 36/48] Audit: Log watch " Gao feng
@ 2013-05-07 2:20 ` Gao feng
2013-05-07 2:21 ` [PATCH RFC 40/48] Audit: ima: " Gao feng
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:20 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This patch translates the call of interface audit_log_start to
the namespace aware interface audit_log_start_ns.
After we finish translation, we can rename audit_log_start_ns
to audit_log_start.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
kernel/audit.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index f723fe2..926d59b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1489,9 +1489,10 @@ void audit_log_key(struct audit_buffer *ab, char *key)
void audit_log_link_denied(const char *operation, struct path *link)
{
struct audit_buffer *ab;
+ struct user_namespace *ns = current_user_ns();
- ab = audit_log_start(current->audit_context, GFP_KERNEL,
- AUDIT_ANOM_LINK);
+ ab = audit_log_start_ns(ns, current->audit_context, GFP_KERNEL,
+ AUDIT_ANOM_LINK);
if (!ab)
return;
audit_log_format(ab, "op=%s action=denied", operation);
@@ -1501,7 +1502,7 @@ void audit_log_link_denied(const char *operation, struct path *link)
audit_log_format(ab, " dev=");
audit_log_untrustedstring(ab, link->dentry->d_inode->i_sb->s_id);
audit_log_format(ab, " ino=%lu", link->dentry->d_inode->i_ino);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
void audit_log_end_ns(struct user_namespace *ns, struct audit_buffer *ab)
@@ -1558,12 +1559,12 @@ void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
struct audit_buffer *ab;
va_list args;
- ab = audit_log_start(ctx, gfp_mask, type);
+ ab = audit_log_start_ns(&init_user_ns, ctx, gfp_mask, type);
if (ab) {
va_start(args, fmt);
audit_log_vformat(ab, fmt, args);
va_end(args);
- audit_log_end(ab);
+ audit_log_end_ns(&init_user_ns, ab);
}
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread* [PATCH RFC 40/48] Audit: ima: translate audit_log_start to audit_log_start_ns
[not found] ` <1367893269-9308-1-git-send-email-gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
` (32 preceding siblings ...)
2013-05-07 2:20 ` [PATCH RFC 37/48] Audit: translate audit_log_start to audit_log_start_ns Gao feng
@ 2013-05-07 2:21 ` Gao feng
33 siblings, 0 replies; 53+ messages in thread
From: Gao feng @ 2013-05-07 2:21 UTC (permalink / raw)
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
eparis-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Now we can log audit message in the user namespace which current
task belongs to.
Signed-off-by: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
---
security/integrity/ima/ima_api.c | 7 ++++---
security/integrity/ima/ima_audit.c | 11 +++++++----
security/integrity/ima/ima_policy.c | 5 +++--
3 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 1c03e8f1..a94b54e 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -213,6 +213,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
{
struct audit_buffer *ab;
char hash[(IMA_DIGEST_SIZE * 2) + 1];
+ struct user_namespace *ns = current_user_ns();
int i;
if (iint->flags & IMA_AUDITED)
@@ -222,8 +223,8 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]);
hash[i * 2] = '\0';
- ab = audit_log_start(current->audit_context, GFP_KERNEL,
- AUDIT_INTEGRITY_RULE);
+ ab = audit_log_start_ns(ns, current->audit_context, GFP_KERNEL,
+ AUDIT_INTEGRITY_RULE);
if (!ab)
return;
@@ -233,7 +234,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
audit_log_untrustedstring(ab, hash);
audit_log_task_info(ab, current);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
iint->flags |= IMA_AUDITED;
}
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index c586faa..e7a205b 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -33,15 +33,18 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
const char *cause, int result, int audit_info)
{
struct audit_buffer *ab;
+ struct user_namespace *ns;
if (!ima_audit && audit_info == 1) /* Skip informational messages */
return;
- ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
+ ns = current_user_ns();
+ ab = audit_log_start_ns(ns, current->audit_context,
+ GFP_KERNEL, audit_msgno);
audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u",
current->pid,
- from_kuid(&init_user_ns, current_cred()->uid),
- from_kuid(&init_user_ns, audit_get_loginuid(current)),
+ from_kuid(ns, current_cred()->uid),
+ from_kuid(ns, audit_get_loginuid(current)),
audit_get_sessionid(current));
audit_log_task_context(ab);
audit_log_format(ab, " op=");
@@ -60,5 +63,5 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
audit_log_format(ab, " ino=%lu", inode->i_ino);
}
audit_log_format(ab, " res=%d", !result);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
}
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 399433a..c817d35 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -414,8 +414,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
struct audit_buffer *ab;
char *p;
int result = 0;
+ struct user_namespace *ns = current_user_ns();
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
+ ab = audit_log_start_ns(ns, NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
entry->uid = INVALID_UID;
entry->fowner = INVALID_UID;
@@ -633,7 +634,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
else if (entry->func == MODULE_CHECK)
ima_appraise |= IMA_APPRAISE_MODULES;
audit_log_format(ab, "res=%d", !result);
- audit_log_end(ab);
+ audit_log_end_ns(ns, ab);
return result;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 53+ messages in thread