diff options
Diffstat (limited to 'kernel/audit.c')
| -rw-r--r-- | kernel/audit.c | 624 | 
1 files changed, 463 insertions, 161 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 7b0e23a740c..3ef2e0e797e 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -41,8 +41,10 @@   * Example user-space utilities: http://people.redhat.com/sgrubb/audit/   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/init.h> -#include <asm/types.h> +#include <linux/types.h>  #include <linux/atomic.h>  #include <linux/mm.h>  #include <linux/export.h> @@ -60,10 +62,10 @@  #ifdef CONFIG_SECURITY  #include <linux/security.h>  #endif -#include <net/netlink.h>  #include <linux/freezer.h>  #include <linux/tty.h>  #include <linux/pid_namespace.h> +#include <net/netns/generic.h>  #include "audit.h" @@ -77,16 +79,16 @@ static int	audit_initialized;  #define AUDIT_OFF	0  #define AUDIT_ON	1  #define AUDIT_LOCKED	2 -int		audit_enabled; -int		audit_ever_enabled; +u32		audit_enabled; +u32		audit_ever_enabled;  EXPORT_SYMBOL_GPL(audit_enabled);  /* Default state when kernel boots without any parameters. */ -static int	audit_default; +static u32	audit_default;  /* If auditing cannot proceed, audit_failure selects what happens. */ -static int	audit_failure = AUDIT_FAIL_PRINTK; +static u32	audit_failure = AUDIT_FAIL_PRINTK;  /*   * If audit records are to be written to the netlink socket, audit_pid @@ -94,17 +96,19 @@ static int	audit_failure = AUDIT_FAIL_PRINTK;   * the portid to use to send netlink messages to that process.   */  int		audit_pid; -static int	audit_nlk_portid; +static __u32	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. */ -static int	audit_rate_limit; +static u32	audit_rate_limit; -/* Number of outstanding audit_buffers allowed. */ -static int	audit_backlog_limit = 64; -static int	audit_backlog_wait_time = 60 * HZ; -static int	audit_backlog_wait_overflow = 0; +/* Number of outstanding audit_buffers allowed. + * When set to zero, this means unlimited. */ +static u32	audit_backlog_limit = 64; +#define AUDIT_BACKLOG_WAIT_TIME (60 * HZ) +static u32	audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; +static u32	audit_backlog_wait_overflow = 0;  /* The identity of the user shutting down the audit system. */  kuid_t		audit_sig_uid = INVALID_UID; @@ -122,6 +126,7 @@ static atomic_t    audit_lost = ATOMIC_INIT(0);  /* The netlink socket. */  static struct sock *audit_sock; +int audit_net_id;  /* Hash for inode-based rules */  struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; @@ -140,6 +145,17 @@ static struct task_struct *kauditd_task;  static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);  static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); +static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION, +				   .mask = -1, +				   .features = 0, +				   .lock = 0,}; + +static char *audit_feature_names[2] = { +	"only_unset_loginuid", +	"loginuid_immutable", +}; + +  /* Serialize requests from userspace. */  DEFINE_MUTEX(audit_cmd_mutex); @@ -165,27 +181,27 @@ struct audit_buffer {  };  struct audit_reply { -	int pid; +	__u32 portid; +	struct net *net;  	struct sk_buff *skb;  }; -static void audit_set_pid(struct audit_buffer *ab, pid_t pid) +static void audit_set_portid(struct audit_buffer *ab, __u32 portid)  {  	if (ab) {  		struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); -		nlh->nlmsg_pid = pid; +		nlh->nlmsg_pid = portid;  	}  }  void audit_panic(const char *message)  { -	switch (audit_failure) -	{ +	switch (audit_failure) {  	case AUDIT_FAIL_SILENT:  		break;  	case AUDIT_FAIL_PRINTK:  		if (printk_ratelimit()) -			printk(KERN_ERR "audit: %s\n", message); +			pr_err("%s\n", message);  		break;  	case AUDIT_FAIL_PANIC:  		/* test audit_pid since printk is always losey, why bother? */ @@ -256,9 +272,7 @@ void audit_log_lost(const char *message)  	if (print) {  		if (printk_ratelimit()) -			printk(KERN_WARNING -				"audit: audit_lost=%d audit_rate_limit=%d " -				"audit_backlog_limit=%d\n", +			pr_warn("audit_lost=%u audit_rate_limit=%u audit_backlog_limit=%u\n",  				atomic_read(&audit_lost),  				audit_rate_limit,  				audit_backlog_limit); @@ -266,7 +280,7 @@ void audit_log_lost(const char *message)  	}  } -static int audit_log_config_change(char *function_name, int new, int old, +static int audit_log_config_change(char *function_name, u32 new, u32 old,  				   int allow_changes)  {  	struct audit_buffer *ab; @@ -275,7 +289,7 @@ static int audit_log_config_change(char *function_name, int new, int old,  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);  	if (unlikely(!ab))  		return rc; -	audit_log_format(ab, "%s=%d old=%d", function_name, new, old); +	audit_log_format(ab, "%s=%u old=%u", function_name, new, old);  	audit_log_session_info(ab);  	rc = audit_log_task_context(ab);  	if (rc) @@ -285,9 +299,10 @@ static int audit_log_config_change(char *function_name, int new, int old,  	return rc;  } -static int audit_do_config_change(char *function_name, int *to_change, int new) +static int audit_do_config_change(char *function_name, u32 *to_change, u32 new)  { -	int allow_changes, rc = 0, old = *to_change; +	int allow_changes, rc = 0; +	u32 old = *to_change;  	/* check if we are locked */  	if (audit_enabled == AUDIT_LOCKED) @@ -310,17 +325,23 @@ static int audit_do_config_change(char *function_name, int *to_change, int new)  	return rc;  } -static int audit_set_rate_limit(int limit) +static int audit_set_rate_limit(u32 limit)  {  	return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit);  } -static int audit_set_backlog_limit(int limit) +static int audit_set_backlog_limit(u32 limit)  {  	return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit);  } -static int audit_set_enabled(int state) +static int audit_set_backlog_wait_time(u32 timeout) +{ +	return audit_do_config_change("audit_backlog_wait_time", +				      &audit_backlog_wait_time, timeout); +} + +static int audit_set_enabled(u32 state)  {  	int rc;  	if (state < AUDIT_OFF || state > AUDIT_LOCKED) @@ -333,7 +354,7 @@ static int audit_set_enabled(int state)  	return rc;  } -static int audit_set_failure(int state) +static int audit_set_failure(u32 state)  {  	if (state != AUDIT_FAIL_SILENT  	    && state != AUDIT_FAIL_PRINTK @@ -355,7 +376,8 @@ static int audit_set_failure(int state)  static void audit_hold_skb(struct sk_buff *skb)  {  	if (audit_default && -	    skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit) +	    (!audit_backlog_limit || +	     skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit))  		skb_queue_tail(&audit_skb_hold_queue, skb);  	else  		kfree_skb(skb); @@ -372,9 +394,9 @@ static void audit_printk_skb(struct sk_buff *skb)  	if (nlh->nlmsg_type != AUDIT_EOE) {  		if (printk_ratelimit()) -			printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data); +			pr_notice("type=%d %s\n", nlh->nlmsg_type, data);  		else -			audit_log_lost("printk limit exceeded\n"); +			audit_log_lost("printk limit exceeded");  	}  	audit_hold_skb(skb); @@ -388,9 +410,12 @@ static void kauditd_send_skb(struct sk_buff *skb)  	err = netlink_unicast(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); -		audit_log_lost("auditd disappeared\n"); -		audit_pid = 0; +		if (audit_pid) { +			pr_err("*NO* daemon at audit_pid=%d\n", audit_pid); +			audit_log_lost("auditd disappeared"); +			audit_pid = 0; +			audit_sock = NULL; +		}  		/* we might get lucky and get this in the next auditd */  		audit_hold_skb(skb);  	} else @@ -399,6 +424,38 @@ static void kauditd_send_skb(struct sk_buff *skb)  }  /* + * kauditd_send_multicast_skb - send the skb to multicast userspace listeners + * + * This function doesn't consume an skb as might be expected since it has to + * copy it anyways. + */ +static void kauditd_send_multicast_skb(struct sk_buff *skb) +{ +	struct sk_buff		*copy; +	struct audit_net	*aunet = net_generic(&init_net, audit_net_id); +	struct sock		*sock = aunet->nlsk; + +	if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG)) +		return; + +	/* +	 * The seemingly wasteful skb_copy() rather than bumping the refcount +	 * using skb_get() is necessary because non-standard mods are made to +	 * the skb by the original kaudit unicast socket send routine.  The +	 * existing auditd daemon assumes this breakage.  Fixing this would +	 * require co-ordinating a change in the established protocol between +	 * the kaudit kernel subsystem and the auditd userspace code.  There is +	 * no reason for new multicast clients to continue with this +	 * non-compliance. +	 */ +	copy = skb_copy(skb, GFP_KERNEL); +	if (!copy) +		return; + +	nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL); +} + +/*   * flush_hold_queue - empty the hold queue if auditd appears   *   * If auditd just started, drain the queue of messages already @@ -447,8 +504,10 @@ static int kauditd_thread(void *dummy)  		flush_hold_queue();  		skb = skb_dequeue(&audit_skb_queue); -		wake_up(&audit_backlog_wait); +  		if (skb) { +			if (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit) +				wake_up(&audit_backlog_wait);  			if (audit_pid)  				kauditd_send_skb(skb);  			else @@ -472,22 +531,24 @@ static int kauditd_thread(void *dummy)  int audit_send_list(void *_dest)  {  	struct audit_netlink_list *dest = _dest; -	int pid = dest->pid;  	struct sk_buff *skb; +	struct net *net = dest->net; +	struct audit_net *aunet = net_generic(net, audit_net_id);  	/* wait for parent to finish and send an ACK */  	mutex_lock(&audit_cmd_mutex);  	mutex_unlock(&audit_cmd_mutex);  	while ((skb = __skb_dequeue(&dest->q)) != NULL) -		netlink_unicast(audit_sock, skb, pid, 0); +		netlink_unicast(aunet->nlsk, skb, dest->portid, 0); +	put_net(net);  	kfree(dest);  	return 0;  } -struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, +struct sk_buff *audit_make_reply(__u32 portid, int seq, int type, int done,  				 int multi, const void *payload, int size)  {  	struct sk_buff	*skb; @@ -500,7 +561,7 @@ struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,  	if (!skb)  		return NULL; -	nlh	= nlmsg_put(skb, pid, seq, t, size, flags); +	nlh	= nlmsg_put(skb, portid, seq, t, size, flags);  	if (!nlh)  		goto out_kfree_skb;  	data = nlmsg_data(nlh); @@ -515,19 +576,22 @@ out_kfree_skb:  static int audit_send_reply_thread(void *arg)  {  	struct audit_reply *reply = (struct audit_reply *)arg; +	struct net *net = reply->net; +	struct audit_net *aunet = net_generic(net, audit_net_id);  	mutex_lock(&audit_cmd_mutex);  	mutex_unlock(&audit_cmd_mutex);  	/* 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(aunet->nlsk , reply->skb, reply->portid, 0); +	put_net(net);  	kfree(reply);  	return 0;  }  /**   * audit_send_reply - send an audit reply message via netlink - * @pid: process id to send reply to + * @request_skb: skb of request we are replying to (used to target the reply)   * @seq: sequence number   * @type: audit message type   * @done: done (last) flag @@ -535,12 +599,14 @@ static int audit_send_reply_thread(void *arg)   * @payload: payload data   * @size: payload size   * - * Allocates an skb, builds the netlink message, and sends it to the pid. + * Allocates an skb, builds the netlink message, and sends it to the port id.   * No failure notifications.   */ -static void audit_send_reply(int pid, int seq, int type, int done, int multi, -			     const void *payload, int size) +static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done, +			     int multi, const void *payload, int size)  { +	u32 portid = NETLINK_CB(request_skb).portid; +	struct net *net = sock_net(NETLINK_CB(request_skb).sk);  	struct sk_buff *skb;  	struct task_struct *tsk;  	struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), @@ -549,11 +615,12 @@ static void audit_send_reply(int pid, int seq, int type, int done, int multi,  	if (!reply)  		return; -	skb = audit_make_reply(pid, seq, type, done, multi, payload, size); +	skb = audit_make_reply(portid, seq, type, done, multi, payload, size);  	if (!skb)  		goto out; -	reply->pid = pid; +	reply->net = get_net(net); +	reply->portid = portid;  	reply->skb = skb;  	tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); @@ -572,10 +639,19 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)  {  	int err = 0; -	/* Only support the initial namespaces for now. */ -	if ((current_user_ns() != &init_user_ns) || -	    (task_active_pid_ns(current) != &init_pid_ns)) -		return -EPERM; +	/* Only support initial user namespace for now. */ +	/* +	 * We return ECONNREFUSED because it tricks userspace into thinking +	 * that audit was not configured into the kernel.  Lots of users +	 * configure their PAM stack (because that's what the distro does) +	 * to reject login if unable to send messages to audit.  If we return +	 * ECONNREFUSED the PAM stack thinks the kernel does not have audit +	 * configured in and will let login proceed.  If we return EPERM +	 * userspace will reject all logins.  This should be removed when we +	 * support non init namespaces!! +	 */ +	if (current_user_ns() != &init_user_ns) +		return -ECONNREFUSED;  	switch (msg_type) {  	case AUDIT_LIST: @@ -584,6 +660,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)  		return -EOPNOTSUPP;  	case AUDIT_GET:  	case AUDIT_SET: +	case AUDIT_GET_FEATURE: +	case AUDIT_SET_FEATURE:  	case AUDIT_LIST_RULES:  	case AUDIT_ADD_RULE:  	case AUDIT_DEL_RULE: @@ -592,13 +670,18 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)  	case AUDIT_TTY_SET:  	case AUDIT_TRIM:  	case AUDIT_MAKE_EQUIV: -		if (!capable(CAP_AUDIT_CONTROL)) +		/* Only support auditd and auditctl in initial pid namespace +		 * for now. */ +		if ((task_active_pid_ns(current) != &init_pid_ns)) +			return -EPERM; + +		if (!netlink_capable(skb, CAP_AUDIT_CONTROL))  			err = -EPERM;  		break;  	case AUDIT_USER:  	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:  	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: -		if (!capable(CAP_AUDIT_WRITE)) +		if (!netlink_capable(skb, CAP_AUDIT_WRITE))  			err = -EPERM;  		break;  	default:  /* bad msg */ @@ -612,8 +695,9 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)  {  	int rc = 0;  	uid_t uid = from_kuid(&init_user_ns, current_uid()); +	pid_t pid = task_tgid_nr(current); -	if (!audit_enabled) { +	if (!audit_enabled && msg_type != AUDIT_USER_AVC) {  		*ab = NULL;  		return rc;  	} @@ -621,18 +705,108 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)  	*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);  	if (unlikely(!*ab))  		return rc; -	audit_log_format(*ab, "pid=%d uid=%u", task_tgid_vnr(current), uid); +	audit_log_format(*ab, "pid=%d uid=%u", pid, uid);  	audit_log_session_info(*ab);  	audit_log_task_context(*ab);  	return rc;  } +int is_audit_feature_set(int i) +{ +	return af.features & AUDIT_FEATURE_TO_MASK(i); +} + + +static int audit_get_feature(struct sk_buff *skb) +{ +	u32 seq; + +	seq = nlmsg_hdr(skb)->nlmsg_seq; + +	audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af)); + +	return 0; +} + +static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature, +				     u32 old_lock, u32 new_lock, int res) +{ +	struct audit_buffer *ab; + +	if (audit_enabled == AUDIT_OFF) +		return; + +	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); +	audit_log_task_info(ab, current); +	audit_log_format(ab, "feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", +			 audit_feature_names[which], !!old_feature, !!new_feature, +			 !!old_lock, !!new_lock, res); +	audit_log_end(ab); +} + +static int audit_set_feature(struct sk_buff *skb) +{ +	struct audit_features *uaf; +	int i; + +	BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > sizeof(audit_feature_names)/sizeof(audit_feature_names[0])); +	uaf = nlmsg_data(nlmsg_hdr(skb)); + +	/* if there is ever a version 2 we should handle that here */ + +	for (i = 0; i <= AUDIT_LAST_FEATURE; i++) { +		u32 feature = AUDIT_FEATURE_TO_MASK(i); +		u32 old_feature, new_feature, old_lock, new_lock; + +		/* if we are not changing this feature, move along */ +		if (!(feature & uaf->mask)) +			continue; + +		old_feature = af.features & feature; +		new_feature = uaf->features & feature; +		new_lock = (uaf->lock | af.lock) & feature; +		old_lock = af.lock & feature; + +		/* are we changing a locked feature? */ +		if (old_lock && (new_feature != old_feature)) { +			audit_log_feature_change(i, old_feature, new_feature, +						 old_lock, new_lock, 0); +			return -EPERM; +		} +	} +	/* nothing invalid, do the changes */ +	for (i = 0; i <= AUDIT_LAST_FEATURE; i++) { +		u32 feature = AUDIT_FEATURE_TO_MASK(i); +		u32 old_feature, new_feature, old_lock, new_lock; + +		/* if we are not changing this feature, move along */ +		if (!(feature & uaf->mask)) +			continue; + +		old_feature = af.features & feature; +		new_feature = uaf->features & feature; +		old_lock = af.lock & feature; +		new_lock = (uaf->lock | af.lock) & feature; + +		if (new_feature != old_feature) +			audit_log_feature_change(i, old_feature, new_feature, +						 old_lock, new_lock, 1); + +		if (new_feature) +			af.features |= feature; +		else +			af.features &= ~feature; +		af.lock |= new_lock; +	} + +	return 0; +} +  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  {  	u32			seq;  	void			*data; -	struct audit_status	*status_get, status_set;  	int			err;  	struct audit_buffer	*ab;  	u16			msg_type = nlh->nlmsg_type; @@ -658,46 +832,78 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  	data = nlmsg_data(nlh);  	switch (msg_type) { -	case AUDIT_GET: -		status_set.enabled	 = audit_enabled; -		status_set.failure	 = audit_failure; -		status_set.pid		 = audit_pid; -		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); -		audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, -				 &status_set, sizeof(status_set)); +	case AUDIT_GET: { +		struct audit_status	s; +		memset(&s, 0, sizeof(s)); +		s.enabled		= audit_enabled; +		s.failure		= audit_failure; +		s.pid			= audit_pid; +		s.rate_limit		= audit_rate_limit; +		s.backlog_limit		= audit_backlog_limit; +		s.lost			= atomic_read(&audit_lost); +		s.backlog		= skb_queue_len(&audit_skb_queue); +		s.version		= AUDIT_VERSION_LATEST; +		s.backlog_wait_time	= audit_backlog_wait_time; +		audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));  		break; -	case AUDIT_SET: -		if (nlh->nlmsg_len < sizeof(struct audit_status)) -			return -EINVAL; -		status_get   = (struct audit_status *)data; -		if (status_get->mask & AUDIT_STATUS_ENABLED) { -			err = audit_set_enabled(status_get->enabled); +	} +	case AUDIT_SET: { +		struct audit_status	s; +		memset(&s, 0, sizeof(s)); +		/* guard against past and future API changes */ +		memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); +		if (s.mask & AUDIT_STATUS_ENABLED) { +			err = audit_set_enabled(s.enabled);  			if (err < 0)  				return err;  		} -		if (status_get->mask & AUDIT_STATUS_FAILURE) { -			err = audit_set_failure(status_get->failure); +		if (s.mask & AUDIT_STATUS_FAILURE) { +			err = audit_set_failure(s.failure);  			if (err < 0)  				return err;  		} -		if (status_get->mask & AUDIT_STATUS_PID) { -			int new_pid = status_get->pid; +		if (s.mask & AUDIT_STATUS_PID) { +			int new_pid = s.pid; +			if ((!new_pid) && (task_tgid_vnr(current) != audit_pid)) +				return -EACCES;  			if (audit_enabled != AUDIT_OFF)  				audit_log_config_change("audit_pid", new_pid, audit_pid, 1);  			audit_pid = new_pid;  			audit_nlk_portid = NETLINK_CB(skb).portid; +			audit_sock = skb->sk; +		} +		if (s.mask & AUDIT_STATUS_RATE_LIMIT) { +			err = audit_set_rate_limit(s.rate_limit); +			if (err < 0) +				return err; +		} +		if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) { +			err = audit_set_backlog_limit(s.backlog_limit); +			if (err < 0) +				return err;  		} -		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) { -			err = audit_set_rate_limit(status_get->rate_limit); +		if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) { +			if (sizeof(s) > (size_t)nlh->nlmsg_len) +				return -EINVAL; +			if (s.backlog_wait_time < 0 || +			    s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME) +				return -EINVAL; +			err = audit_set_backlog_wait_time(s.backlog_wait_time);  			if (err < 0)  				return err;  		} -		if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) -			err = audit_set_backlog_limit(status_get->backlog_limit); +		break; +	} +	case AUDIT_GET_FEATURE: +		err = audit_get_feature(skb); +		if (err) +			return err; +		break; +	case AUDIT_SET_FEATURE: +		err = audit_set_feature(skb); +		if (err) +			return err;  		break;  	case AUDIT_USER:  	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: @@ -706,16 +912,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  			return 0;  		err = audit_filter_user(msg_type); -		if (err == 1) { +		if (err == 1) { /* match or error */  			err = 0;  			if (msg_type == AUDIT_USER_TTY) {  				err = tty_audit_push_current();  				if (err)  					break;  			} +			mutex_unlock(&audit_cmd_mutex);  			audit_log_common_recv_msg(&ab, msg_type);  			if (msg_type != AUDIT_USER_TTY) -				audit_log_format(ab, " msg='%.1024s'", +				audit_log_format(ab, " msg='%.*s'", +						 AUDIT_MESSAGE_TEXT_MAX,  						 (char *)data);  			else {  				int size; @@ -727,8 +935,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  					size--;  				audit_log_n_untrustedstring(ab, data, size);  			} -			audit_set_pid(ab, NETLINK_CB(skb).portid); +			audit_set_portid(ab, NETLINK_CB(skb).portid);  			audit_log_end(ab); +			mutex_lock(&audit_cmd_mutex);  		}  		break;  	case AUDIT_ADD_RULE: @@ -741,11 +950,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  			audit_log_end(ab);  			return -EPERM;  		} -		/* fallthrough */ -	case AUDIT_LIST_RULES: -		err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid, +		err = audit_rule_change(msg_type, NETLINK_CB(skb).portid,  					   seq, data, nlmsg_len(nlh));  		break; +	case AUDIT_LIST_RULES: +		err = audit_list_rules_send(skb, seq); +		break;  	case AUDIT_TRIM:  		audit_trim_trees();  		audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); @@ -809,8 +1019,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  			memcpy(sig_data->ctx, ctx, len);  			security_release_secctx(ctx, len);  		} -		audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_SIGNAL_INFO, -				0, 0, sig_data, sizeof(*sig_data) + len); +		audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, +				 sig_data, sizeof(*sig_data) + len);  		kfree(sig_data);  		break;  	case AUDIT_TTY_GET: { @@ -818,29 +1028,41 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  		struct task_struct *tsk = current;  		spin_lock(&tsk->sighand->siglock); -		s.enabled = tsk->signal->audit_tty != 0; +		s.enabled = tsk->signal->audit_tty;  		s.log_passwd = tsk->signal->audit_tty_log_passwd;  		spin_unlock(&tsk->sighand->siglock); -		audit_send_reply(NETLINK_CB(skb).portid, seq, -				 AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); +		audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s));  		break;  	}  	case AUDIT_TTY_SET: { -		struct audit_tty_status s; +		struct audit_tty_status s, old;  		struct task_struct *tsk = current; +		struct audit_buffer	*ab;  		memset(&s, 0, sizeof(s));  		/* guard against past and future API changes */ -		memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len)); +		memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); +		/* check if new data is valid */  		if ((s.enabled != 0 && s.enabled != 1) ||  		    (s.log_passwd != 0 && s.log_passwd != 1)) -			return -EINVAL; +			err = -EINVAL;  		spin_lock(&tsk->sighand->siglock); -		tsk->signal->audit_tty = s.enabled; -		tsk->signal->audit_tty_log_passwd = s.log_passwd; +		old.enabled = tsk->signal->audit_tty; +		old.log_passwd = tsk->signal->audit_tty_log_passwd; +		if (!err) { +			tsk->signal->audit_tty = s.enabled; +			tsk->signal->audit_tty_log_passwd = s.log_passwd; +		}  		spin_unlock(&tsk->sighand->siglock); + +		audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); +		audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" +				 " old-log_passwd=%d new-log_passwd=%d res=%d", +				 old.enabled, s.enabled, old.log_passwd, +				 s.log_passwd, !err); +		audit_log_end(ab);  		break;  	}  	default: @@ -886,24 +1108,67 @@ static void audit_receive(struct sk_buff  *skb)  	mutex_unlock(&audit_cmd_mutex);  } -/* Initialize audit support at boot time. */ -static int __init audit_init(void) +/* Run custom bind function on netlink socket group connect or bind requests. */ +static int audit_bind(int group) +{ +	if (!capable(CAP_AUDIT_READ)) +		return -EPERM; + +	return 0; +} + +static int __net_init audit_net_init(struct net *net)  { -	int i;  	struct netlink_kernel_cfg cfg = {  		.input	= audit_receive, +		.bind	= audit_bind, +		.flags	= NL_CFG_F_NONROOT_RECV, +		.groups	= AUDIT_NLGRP_MAX,  	}; +	struct audit_net *aunet = net_generic(net, audit_net_id); + +	aunet->nlsk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg); +	if (aunet->nlsk == NULL) { +		audit_panic("cannot initialize netlink socket in namespace"); +		return -ENOMEM; +	} +	aunet->nlsk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; +	return 0; +} + +static void __net_exit audit_net_exit(struct net *net) +{ +	struct audit_net *aunet = net_generic(net, audit_net_id); +	struct sock *sock = aunet->nlsk; +	if (sock == audit_sock) { +		audit_pid = 0; +		audit_sock = NULL; +	} + +	RCU_INIT_POINTER(aunet->nlsk, NULL); +	synchronize_net(); +	netlink_kernel_release(sock); +} + +static struct pernet_operations audit_net_ops __net_initdata = { +	.init = audit_net_init, +	.exit = audit_net_exit, +	.id = &audit_net_id, +	.size = sizeof(struct audit_net), +}; + +/* Initialize audit support at boot time. */ +static int __init audit_init(void) +{ +	int i; +  	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; +	pr_info("initializing netlink subsys (%s)\n", +		audit_default ? "enabled" : "disabled"); +	register_pernet_subsys(&audit_net_ops);  	skb_queue_head_init(&audit_skb_queue);  	skb_queue_head_init(&audit_skb_hold_queue); @@ -927,22 +1192,32 @@ static int __init audit_enable(char *str)  	if (!audit_default)  		audit_initialized = AUDIT_DISABLED; -	printk(KERN_INFO "audit: %s", audit_default ? "enabled" : "disabled"); +	pr_info("%s\n", audit_default ? +		"enabled (after initialization)" : "disabled (until reboot)"); -	if (audit_initialized == AUDIT_INITIALIZED) { -		audit_enabled = audit_default; -		audit_ever_enabled |= !!audit_default; -	} else if (audit_initialized == AUDIT_UNINITIALIZED) { -		printk(" (after initialization)"); -	} else { -		printk(" (until reboot)"); +	return 1; +} +__setup("audit=", audit_enable); + +/* Process kernel command-line parameter at boot time. + * audit_backlog_limit=<n> */ +static int __init audit_backlog_limit_set(char *str) +{ +	u32 audit_backlog_limit_arg; + +	pr_info("audit_backlog_limit: "); +	if (kstrtouint(str, 0, &audit_backlog_limit_arg)) { +		pr_cont("using default of %u, unable to parse %s\n", +			audit_backlog_limit, str); +		return 1;  	} -	printk("\n"); + +	audit_backlog_limit = audit_backlog_limit_arg; +	pr_cont("%d\n", audit_backlog_limit);  	return 1;  } - -__setup("audit=", audit_enable); +__setup("audit_backlog_limit=", audit_backlog_limit_set);  static void audit_buffer_free(struct audit_buffer *ab)  { @@ -1053,26 +1328,21 @@ 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 long wait_for_auditd(long sleep_time)  {  	DECLARE_WAITQUEUE(wait, current);  	set_current_state(TASK_UNINTERRUPTIBLE); -	add_wait_queue(&audit_backlog_wait, &wait); +	add_wait_queue_exclusive(&audit_backlog_wait, &wait);  	if (audit_backlog_limit &&  	    skb_queue_len(&audit_skb_queue) > audit_backlog_limit) -		schedule_timeout(sleep_time); +		sleep_time = schedule_timeout(sleep_time);  	__set_current_state(TASK_RUNNING);  	remove_wait_queue(&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. */ +	return sleep_time; +}  /**   * audit_log_start - obtain an audit buffer @@ -1095,7 +1365,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,  	struct audit_buffer	*ab	= NULL;  	struct timespec		t;  	unsigned int		uninitialized_var(serial); -	int reserve; +	int reserve = 5; /* Allow atomic callers to go up to five +			    entries over the normal backlog limit */  	unsigned long timeout_start = jiffies;  	if (audit_initialized != AUDIT_INITIALIZED) @@ -1104,36 +1375,37 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,  	if (unlikely(audit_filter_type(type)))  		return NULL; -	if (gfp_mask & __GFP_WAIT) -		reserve = 0; -	else -		reserve = 5; /* Allow atomic callers to go up to five -				entries over the normal backlog limit */ +	if (gfp_mask & __GFP_WAIT) { +		if (audit_pid && audit_pid == current->pid) +			gfp_mask &= ~__GFP_WAIT; +		else +			reserve = 0; +	}  	while (audit_backlog_limit  	       && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {  		if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { -			unsigned long sleep_time; +			long sleep_time; -			sleep_time = timeout_start + audit_backlog_wait_time - -					jiffies; -			if ((long)sleep_time > 0) { -				wait_for_auditd(sleep_time); -				continue; +			sleep_time = timeout_start + audit_backlog_wait_time - jiffies; +			if (sleep_time > 0) { +				sleep_time = wait_for_auditd(sleep_time); +				if (sleep_time > 0) +					continue;  			}  		}  		if (audit_rate_check() && printk_ratelimit()) -			printk(KERN_WARNING -			       "audit: audit_backlog=%d > " -			       "audit_backlog_limit=%d\n", -			       skb_queue_len(&audit_skb_queue), -			       audit_backlog_limit); +			pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n", +				skb_queue_len(&audit_skb_queue), +				audit_backlog_limit);  		audit_log_lost("backlog limit exceeded");  		audit_backlog_wait_time = audit_backlog_wait_overflow;  		wake_up(&audit_backlog_wait);  		return NULL;  	} +	audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; +  	ab = audit_buffer_alloc(ctx, gfp_mask, type);  	if (!ab) {  		audit_log_lost("out of memory in audit_log_start"); @@ -1251,7 +1523,6 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,  	int i, avail, new_len;  	unsigned char *ptr;  	struct sk_buff *skb; -	static const unsigned char *hex = "0123456789ABCDEF";  	if (!ab)  		return; @@ -1269,10 +1540,8 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,  	}  	ptr = skb_tail_pointer(skb); -	for (i=0; i<len; i++) { -		*ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */ -		*ptr++ = hex[buf[i] & 0x0F];	  /* Lower nibble */ -	} +	for (i = 0; i < len; i++) +		ptr = hex_byte_pack_upper(ptr, buf[i]);  	*ptr = 0;  	skb_put(skb, len << 1); /* new string is twice the old string */  } @@ -1386,10 +1655,10 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,  void audit_log_session_info(struct audit_buffer *ab)  { -	u32 sessionid = audit_get_sessionid(current); +	unsigned int sessionid = audit_get_sessionid(current);  	uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); -	audit_log_format(ab, " auid=%u ses=%u\n", auid, sessionid); +	audit_log_format(ab, " auid=%u ses=%u", auid, sessionid);  }  void audit_log_key(struct audit_buffer *ab, char *key) @@ -1536,6 +1805,26 @@ void audit_log_name(struct audit_context *context, struct audit_names *n,  		}  	} +	/* log the audit_names record type */ +	audit_log_format(ab, " nametype="); +	switch(n->type) { +	case AUDIT_TYPE_NORMAL: +		audit_log_format(ab, "NORMAL"); +		break; +	case AUDIT_TYPE_PARENT: +		audit_log_format(ab, "PARENT"); +		break; +	case AUDIT_TYPE_CHILD_DELETE: +		audit_log_format(ab, "DELETE"); +		break; +	case AUDIT_TYPE_CHILD_CREATE: +		audit_log_format(ab, "CREATE"); +		break; +	default: +		audit_log_format(ab, "UNKNOWN"); +		break; +	} +  	audit_log_fcaps(ab, n);  	audit_log_end(ab);  } @@ -1589,11 +1878,11 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)  	spin_unlock_irq(&tsk->sighand->siglock);  	audit_log_format(ab, -			 " ppid=%ld pid=%d auid=%u uid=%u gid=%u" +			 " ppid=%d pid=%d auid=%u uid=%u gid=%u"  			 " euid=%u suid=%u fsuid=%u" -			 " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", -			 sys_getppid(), -			 tsk->pid, +			 " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", +			 task_ppid_nr(tsk), +			 task_pid_nr(tsk),  			 from_kuid(&init_user_ns, audit_get_loginuid(tsk)),  			 from_kuid(&init_user_ns, cred->uid),  			 from_kgid(&init_user_ns, cred->gid), @@ -1603,7 +1892,7 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)  			 from_kgid(&init_user_ns, cred->egid),  			 from_kgid(&init_user_ns, cred->sgid),  			 from_kgid(&init_user_ns, cred->fsgid), -			 audit_get_sessionid(tsk), tty); +			 tty, audit_get_sessionid(tsk));  	get_task_comm(name, tsk);  	audit_log_format(ab, " comm="); @@ -1614,7 +1903,8 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)  		if (mm->exe_file)  			audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);  		up_read(&mm->mmap_sem); -	} +	} else +		audit_log_format(ab, " exe=(null)");  	audit_log_task_context(ab);  }  EXPORT_SYMBOL(audit_log_task_info); @@ -1655,10 +1945,10 @@ out:   * 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. + * netlink_unicast() cannot be called inside an irq context because it blocks + * (last arg, flags, is not set to MSG_DONTWAIT), 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)  { @@ -1668,6 +1958,18 @@ void audit_log_end(struct audit_buffer *ab)  		audit_log_lost("rate limit exceeded");  	} else {  		struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); + +		kauditd_send_multicast_skb(ab->skb); + +		/* +		 * The original kaudit unicast socket sends up messages with +		 * nlmsg_len set to the payload length rather than the entire +		 * message length.  This breaks the standard set by netlink. +		 * The existing auditd daemon assumes this breakage.  Fixing +		 * this would require co-ordinating a change in the established +		 * protocol between the kaudit kernel subsystem and the auditd +		 * userspace code. +		 */  		nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;  		if (audit_pid) {  | 
