Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 797cee98 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit

Pull audit updates from Paul Moore:
 "Six audit patches for 4.8.

  There are a couple of style and minor whitespace tweaks for the logs,
  as well as a minor fixup to catch errors on user filter rules, however
  the major improvements are a fix to the s390 syscall argument masking
  code (reviewed by the nice s390 folks), some consolidation around the
  exclude filtering (less code, always a win), and a double-fetch fix
  for recording the execve arguments"

* 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit:
  audit: fix a double fetch in audit_log_single_execve_arg()
  audit: fix whitespace in CWD record
  audit: add fields to exclude filter by reusing user filter
  s390: ensure that syscall arguments are properly masked on s390
  audit: fix some horrible switch statement style crimes
  audit: fixup: log on errors from filter user rules
parents 7a1e8b80 43761473
Loading
Loading
Loading
Loading
+8 −3
Original line number Original line Diff line number Diff line
@@ -821,6 +821,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,


asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
{
	unsigned long mask = -1UL;

	/*
	/*
	 * The sysc_tracesys code in entry.S stored the system
	 * The sysc_tracesys code in entry.S stored the system
	 * call number to gprs[2].
	 * call number to gprs[2].
@@ -846,9 +848,12 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
		trace_sys_enter(regs, regs->gprs[2]);
		trace_sys_enter(regs, regs->gprs[2]);


	audit_syscall_entry(regs->gprs[2], regs->orig_gpr2,
	if (is_compat_task())
			    regs->gprs[3], regs->gprs[4],
		mask = 0xffffffff;
			    regs->gprs[5]);

	audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask,
			    regs->gprs[3] &mask, regs->gprs[4] &mask,
			    regs->gprs[5] &mask);


	return regs->gprs[2];
	return regs->gprs[2];
}
}
+0 −2
Original line number Original line Diff line number Diff line
@@ -163,8 +163,6 @@ extern void audit_log_task_info(struct audit_buffer *ab,
extern int		    audit_update_lsm_rules(void);
extern int		    audit_update_lsm_rules(void);


				/* Private API (for audit.c only) */
				/* Private API (for audit.c only) */
extern int audit_filter_user(int type);
extern int audit_filter_type(int type);
extern int audit_rule_change(int type, __u32 portid, int seq,
extern int audit_rule_change(int type, __u32 portid, int seq,
				void *data, size_t datasz);
				void *data, size_t datasz);
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
+2 −2
Original line number Original line Diff line number Diff line
@@ -932,7 +932,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
		if (!audit_enabled && msg_type != AUDIT_USER_AVC)
		if (!audit_enabled && msg_type != AUDIT_USER_AVC)
			return 0;
			return 0;


		err = audit_filter_user(msg_type);
		err = audit_filter(msg_type, AUDIT_FILTER_USER);
		if (err == 1) { /* match or error */
		if (err == 1) { /* match or error */
			err = 0;
			err = 0;
			if (msg_type == AUDIT_USER_TTY) {
			if (msg_type == AUDIT_USER_TTY) {
@@ -1379,7 +1379,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
	if (audit_initialized != AUDIT_INITIALIZED)
	if (audit_initialized != AUDIT_INITIALIZED)
		return NULL;
		return NULL;


	if (unlikely(audit_filter_type(type)))
	if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
		return NULL;
		return NULL;


	if (gfp_mask & __GFP_DIRECT_RECLAIM) {
	if (gfp_mask & __GFP_DIRECT_RECLAIM) {
+2 −0
Original line number Original line Diff line number Diff line
@@ -331,6 +331,8 @@ extern pid_t audit_sig_pid;
extern kuid_t audit_sig_uid;
extern kuid_t audit_sig_uid;
extern u32 audit_sig_sid;
extern u32 audit_sig_sid;


extern int audit_filter(int msgtype, unsigned int listtype);

#ifdef CONFIG_AUDITSYSCALL
#ifdef CONFIG_AUDITSYSCALL
extern int __audit_signal_info(int sig, struct task_struct *t);
extern int __audit_signal_info(int sig, struct task_struct *t);
static inline int audit_signal_info(int sig, struct task_struct *t)
static inline int audit_signal_info(int sig, struct task_struct *t)
+53 −94
Original line number Original line Diff line number Diff line
@@ -1290,15 +1290,20 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen)
	return strncmp(p, dname, dlen);
	return strncmp(p, dname, dlen);
}
}


static int audit_filter_user_rules(struct audit_krule *rule, int type,
int audit_filter(int msgtype, unsigned int listtype)
				   enum audit_state *state)
{
{
	int i;
	struct audit_entry *e;
	int ret = 1; /* Audit by default */

	rcu_read_lock();
	if (list_empty(&audit_filter_list[listtype]))
		goto unlock_and_return;
	list_for_each_entry_rcu(e, &audit_filter_list[listtype], list) {
		int i, result = 0;


	for (i = 0; i < rule->field_count; i++) {
		for (i = 0; i < e->rule.field_count; i++) {
		struct audit_field *f = &rule->fields[i];
			struct audit_field *f = &e->rule.fields[i];
			pid_t pid;
			pid_t pid;
		int result = 0;
			u32 sid;
			u32 sid;


			switch (f->type) {
			switch (f->type) {
@@ -1321,7 +1326,7 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,
							  f->op, f->val);
							  f->op, f->val);
				break;
				break;
			case AUDIT_MSGTYPE:
			case AUDIT_MSGTYPE:
			result = audit_comparator(type, f->op, f->val);
				result = audit_comparator(msgtype, f->op, f->val);
				break;
				break;
			case AUDIT_SUBJ_USER:
			case AUDIT_SUBJ_USER:
			case AUDIT_SUBJ_ROLE:
			case AUDIT_SUBJ_ROLE:
@@ -1331,72 +1336,26 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,
				if (f->lsm_rule) {
				if (f->lsm_rule) {
					security_task_getsecid(current, &sid);
					security_task_getsecid(current, &sid);
					result = security_audit_rule_match(sid,
					result = security_audit_rule_match(sid,
								   f->type,
							f->type, f->op, f->lsm_rule, NULL);
								   f->op,
								   f->lsm_rule,
								   NULL);
				}
				}
				break;
				break;
			default:
				goto unlock_and_return;
			}
			}

			if (result < 0) /* error */
		if (!result)
			return 0;
	}
	switch (rule->action) {
	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
	case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
	}
	return 1;
}

int audit_filter_user(int type)
{
	enum audit_state state = AUDIT_DISABLED;
	struct audit_entry *e;
	int rc, ret;

	ret = 1; /* Audit by default */

	rcu_read_lock();
	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
		rc = audit_filter_user_rules(&e->rule, type, &state);
		if (rc) {
			if (rc > 0 && state == AUDIT_DISABLED)
				ret = 0;
			break;
		}
	}
	rcu_read_unlock();

	return ret;
}

int audit_filter_type(int type)
{
	struct audit_entry *e;
	int result = 0;

	rcu_read_lock();
	if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
				goto unlock_and_return;
				goto unlock_and_return;

	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
				list) {
		int i;
		for (i = 0; i < e->rule.field_count; i++) {
			struct audit_field *f = &e->rule.fields[i];
			if (f->type == AUDIT_MSGTYPE) {
				result = audit_comparator(type, f->op, f->val);
			if (!result)
			if (!result)
				break;
				break;
		}
		}
		if (result > 0) {
			if (e->rule.action == AUDIT_NEVER || listtype == AUDIT_FILTER_TYPE)
				ret = 0;
			break;
		}
		}
		if (result)
			goto unlock_and_return;
	}
	}
unlock_and_return:
unlock_and_return:
	rcu_read_unlock();
	rcu_read_unlock();
	return result;
	return ret;
}
}


static int update_lsm_rule(struct audit_krule *r)
static int update_lsm_rule(struct audit_krule *r)
Loading