diff options
Diffstat (limited to 'kernel/audit.c')
| -rw-r--r-- | kernel/audit.c | 26 | 
1 files changed, 21 insertions, 5 deletions
| diff --git a/kernel/audit.c b/kernel/audit.c index 4cebadb5f30d..e4bbe2c70c26 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1444,7 +1444,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  			if (err)  				return err;  		} -		sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); +		sig_data = kmalloc(struct_size(sig_data, ctx, len), GFP_KERNEL);  		if (!sig_data) {  			if (audit_sig_sid)  				security_release_secctx(ctx, len); @@ -1457,7 +1457,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)  			security_release_secctx(ctx, len);  		}  		audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, -				 sig_data, sizeof(*sig_data) + len); +				 sig_data, struct_size(sig_data, ctx, len));  		kfree(sig_data);  		break;  	case AUDIT_TTY_GET: { @@ -1540,6 +1540,20 @@ static void audit_receive(struct sk_buff  *skb)  		nlh = nlmsg_next(nlh, &len);  	}  	audit_ctl_unlock(); + +	/* can't block with the ctrl lock, so penalize the sender now */ +	if (audit_backlog_limit && +	    (skb_queue_len(&audit_queue) > audit_backlog_limit)) { +		DECLARE_WAITQUEUE(wait, current); + +		/* wake kauditd to try and flush the queue */ +		wake_up_interruptible(&kauditd_wait); + +		add_wait_queue_exclusive(&audit_backlog_wait, &wait); +		set_current_state(TASK_UNINTERRUPTIBLE); +		schedule_timeout(audit_backlog_wait_time); +		remove_wait_queue(&audit_backlog_wait, &wait); +	}  }  /* Log information about who is connecting to the audit multicast socket */ @@ -1824,7 +1838,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,  	 *    task_tgid_vnr() since auditd_pid is set in audit_receive_msg()  	 *    using a PID anchored in the caller's namespace  	 * 2. generator holding the audit_cmd_mutex - we don't want to block -	 *    while holding the mutex */ +	 *    while holding the mutex, although we do penalize the sender +	 *    later in audit_receive() when it is safe to block +	 */  	if (!(auditd_test_task(current) || audit_ctl_owner_current())) {  		long stime = audit_backlog_wait_time; @@ -2131,7 +2147,7 @@ int audit_log_task_context(struct audit_buffer *ab)  	int error;  	u32 sid; -	security_task_getsecid_subj(current, &sid); +	security_current_getsecid_subj(&sid);  	if (!sid)  		return 0; @@ -2352,7 +2368,7 @@ int audit_signal_info(int sig, struct task_struct *t)  			audit_sig_uid = auid;  		else  			audit_sig_uid = uid; -		security_task_getsecid_subj(current, &audit_sig_sid); +		security_current_getsecid_subj(&audit_sig_sid);  	}  	return audit_signal_info_syscall(t); |