diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
| commit | 7731b8bc94e599c9a79e428f3359ff2c34b7576a (patch) | |
| tree | 879f18ccbe274122f2d4f095b43cbc7f953e0ada /kernel/auditsc.c | |
| parent | 48e315618dc4dc8904182cd221e3d395d5d97005 (diff) | |
| parent | 9ffc59d57228d74809700be6f7ecb1db10292f05 (diff) | |
Merge branch 'linus' into x86/urgent
Required to queue a dependent fix.
Diffstat (limited to 'kernel/auditsc.c')
| -rw-r--r-- | kernel/auditsc.c | 135 | 
1 files changed, 86 insertions, 49 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 4e0a4ac803db..ceb1c4596c51 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -374,7 +374,7 @@ static int audit_field_compare(struct task_struct *tsk,  	case AUDIT_COMPARE_EGID_TO_OBJ_GID:  		return audit_compare_gid(cred->egid, name, f, ctx);  	case AUDIT_COMPARE_AUID_TO_OBJ_UID: -		return audit_compare_uid(tsk->loginuid, name, f, ctx); +		return audit_compare_uid(audit_get_loginuid(tsk), name, f, ctx);  	case AUDIT_COMPARE_SUID_TO_OBJ_UID:  		return audit_compare_uid(cred->suid, name, f, ctx);  	case AUDIT_COMPARE_SGID_TO_OBJ_GID: @@ -385,7 +385,8 @@ static int audit_field_compare(struct task_struct *tsk,  		return audit_compare_gid(cred->fsgid, name, f, ctx);  	/* uid comparisons */  	case AUDIT_COMPARE_UID_TO_AUID: -		return audit_uid_comparator(cred->uid, f->op, tsk->loginuid); +		return audit_uid_comparator(cred->uid, f->op, +					    audit_get_loginuid(tsk));  	case AUDIT_COMPARE_UID_TO_EUID:  		return audit_uid_comparator(cred->uid, f->op, cred->euid);  	case AUDIT_COMPARE_UID_TO_SUID: @@ -394,11 +395,14 @@ static int audit_field_compare(struct task_struct *tsk,  		return audit_uid_comparator(cred->uid, f->op, cred->fsuid);  	/* auid comparisons */  	case AUDIT_COMPARE_AUID_TO_EUID: -		return audit_uid_comparator(tsk->loginuid, f->op, cred->euid); +		return audit_uid_comparator(audit_get_loginuid(tsk), f->op, +					    cred->euid);  	case AUDIT_COMPARE_AUID_TO_SUID: -		return audit_uid_comparator(tsk->loginuid, f->op, cred->suid); +		return audit_uid_comparator(audit_get_loginuid(tsk), f->op, +					    cred->suid);  	case AUDIT_COMPARE_AUID_TO_FSUID: -		return audit_uid_comparator(tsk->loginuid, f->op, cred->fsuid); +		return audit_uid_comparator(audit_get_loginuid(tsk), f->op, +					    cred->fsuid);  	/* euid comparisons */  	case AUDIT_COMPARE_EUID_TO_SUID:  		return audit_uid_comparator(cred->euid, f->op, cred->suid); @@ -471,6 +475,8 @@ static int audit_filter_rules(struct task_struct *tsk,  			break;  		case AUDIT_EXE:  			result = audit_exe_compare(tsk, rule->exe); +			if (f->op == Audit_not_equal) +				result = !result;  			break;  		case AUDIT_UID:  			result = audit_uid_comparator(cred->uid, f->op, f->uid); @@ -511,7 +517,7 @@ static int audit_filter_rules(struct task_struct *tsk,  			result = audit_gid_comparator(cred->fsgid, f->op, f->gid);  			break;  		case AUDIT_SESSIONID: -			sessionid = audit_get_sessionid(current); +			sessionid = audit_get_sessionid(tsk);  			result = audit_comparator(sessionid, f->op, f->val);  			break;  		case AUDIT_PERS: @@ -609,7 +615,8 @@ static int audit_filter_rules(struct task_struct *tsk,  				result = match_tree_refs(ctx, rule->tree);  			break;  		case AUDIT_LOGINUID: -			result = audit_uid_comparator(tsk->loginuid, f->op, f->uid); +			result = audit_uid_comparator(audit_get_loginuid(tsk), +						      f->op, f->uid);  			break;  		case AUDIT_LOGINUID_SET:  			result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val); @@ -863,7 +870,7 @@ static inline struct audit_context *audit_take_context(struct task_struct *tsk,  		audit_filter_inodes(tsk, context);  	} -	tsk->audit_context = NULL; +	audit_set_context(tsk, NULL);  	return context;  } @@ -950,7 +957,7 @@ int audit_alloc(struct task_struct *tsk)  	}  	context->filterkey = key; -	tsk->audit_context  = context; +	audit_set_context(tsk, context);  	set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);  	return 0;  } @@ -1507,8 +1514,7 @@ void __audit_free(struct task_struct *tsk)  void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,  			   unsigned long a3, unsigned long a4)  { -	struct task_struct *tsk = current; -	struct audit_context *context = tsk->audit_context; +	struct audit_context *context = audit_context();  	enum audit_state     state;  	if (!audit_enabled || !context) @@ -1523,7 +1529,7 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,  	context->dummy = !audit_n_rules;  	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {  		context->prio = 0; -		if (auditd_test_task(tsk)) +		if (auditd_test_task(current))  			return;  	} @@ -1553,7 +1559,6 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,   */  void __audit_syscall_exit(int success, long return_code)  { -	struct task_struct *tsk = current;  	struct audit_context *context;  	if (success) @@ -1561,12 +1566,12 @@ void __audit_syscall_exit(int success, long return_code)  	else  		success = AUDITSC_FAILURE; -	context = audit_take_context(tsk, success, return_code); +	context = audit_take_context(current, success, return_code);  	if (!context)  		return;  	if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT) -		audit_log_exit(context, tsk); +		audit_log_exit(context, current);  	context->in_syscall = 0;  	context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0; @@ -1588,7 +1593,7 @@ void __audit_syscall_exit(int success, long return_code)  		kfree(context->filterkey);  		context->filterkey = NULL;  	} -	tsk->audit_context = context; +	audit_set_context(current, context);  }  static inline void handle_one(const struct inode *inode) @@ -1600,7 +1605,7 @@ static inline void handle_one(const struct inode *inode)  	int count;  	if (likely(!inode->i_fsnotify_marks))  		return; -	context = current->audit_context; +	context = audit_context();  	p = context->trees;  	count = context->tree_count;  	rcu_read_lock(); @@ -1631,7 +1636,7 @@ static void handle_path(const struct dentry *dentry)  	unsigned long seq;  	int count; -	context = current->audit_context; +	context = audit_context();  	p = context->trees;  	count = context->tree_count;  retry: @@ -1713,7 +1718,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,  struct filename *  __audit_reusename(const __user char *uptr)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	struct audit_names *n;  	list_for_each_entry(n, &context->names_list, list) { @@ -1736,7 +1741,7 @@ __audit_reusename(const __user char *uptr)   */  void __audit_getname(struct filename *name)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	struct audit_names *n;  	if (!context->in_syscall) @@ -1764,7 +1769,7 @@ void __audit_getname(struct filename *name)  void __audit_inode(struct filename *name, const struct dentry *dentry,  		   unsigned int flags)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	struct inode *inode = d_backing_inode(dentry);  	struct audit_names *n;  	bool parent = flags & AUDIT_INODE_PARENT; @@ -1863,7 +1868,7 @@ void __audit_inode_child(struct inode *parent,  			 const struct dentry *dentry,  			 const unsigned char type)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	struct inode *inode = d_backing_inode(dentry);  	const char *dname = dentry->d_name.name;  	struct audit_names *n, *found_parent = NULL, *found_child = NULL; @@ -2048,7 +2053,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,  int audit_set_loginuid(kuid_t loginuid)  {  	struct task_struct *task = current; -	unsigned int oldsessionid, sessionid = (unsigned int)-1; +	unsigned int oldsessionid, sessionid = AUDIT_SID_UNSET;  	kuid_t oldloginuid;  	int rc; @@ -2062,7 +2067,7 @@ int audit_set_loginuid(kuid_t loginuid)  	/* are we setting or clearing? */  	if (uid_valid(loginuid)) {  		sessionid = (unsigned int)atomic_inc_return(&session_id); -		if (unlikely(sessionid == (unsigned int)-1)) +		if (unlikely(sessionid == AUDIT_SID_UNSET))  			sessionid = (unsigned int)atomic_inc_return(&session_id);  	} @@ -2082,7 +2087,7 @@ out:   */  void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	if (attr)  		memcpy(&context->mq_open.attr, attr, sizeof(struct mq_attr)); @@ -2106,7 +2111,7 @@ void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)  void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,  			const struct timespec64 *abs_timeout)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	struct timespec64 *p = &context->mq_sendrecv.abs_timeout;  	if (abs_timeout) @@ -2130,7 +2135,7 @@ void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,  void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	if (notification)  		context->mq_notify.sigev_signo = notification->sigev_signo; @@ -2149,7 +2154,7 @@ void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)   */  void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->mq_getsetattr.mqdes = mqdes;  	context->mq_getsetattr.mqstat = *mqstat;  	context->type = AUDIT_MQ_GETSETATTR; @@ -2162,7 +2167,7 @@ void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)   */  void __audit_ipc_obj(struct kern_ipc_perm *ipcp)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->ipc.uid = ipcp->uid;  	context->ipc.gid = ipcp->gid;  	context->ipc.mode = ipcp->mode; @@ -2182,7 +2187,7 @@ void __audit_ipc_obj(struct kern_ipc_perm *ipcp)   */  void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->ipc.qbytes = qbytes;  	context->ipc.perm_uid = uid; @@ -2193,7 +2198,7 @@ void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mo  void __audit_bprm(struct linux_binprm *bprm)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->type = AUDIT_EXECVE;  	context->execve.argc = bprm->argc; @@ -2208,7 +2213,7 @@ void __audit_bprm(struct linux_binprm *bprm)   */  int __audit_socketcall(int nargs, unsigned long *args)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)  		return -EINVAL; @@ -2226,7 +2231,7 @@ int __audit_socketcall(int nargs, unsigned long *args)   */  void __audit_fd_pair(int fd1, int fd2)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->fds[0] = fd1;  	context->fds[1] = fd2;  } @@ -2240,7 +2245,7 @@ void __audit_fd_pair(int fd1, int fd2)   */  int __audit_sockaddr(int len, void *a)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	if (!context->sockaddr) {  		void *p = kmalloc(sizeof(struct sockaddr_storage), GFP_KERNEL); @@ -2256,7 +2261,7 @@ int __audit_sockaddr(int len, void *a)  void __audit_ptrace(struct task_struct *t)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->target_pid = task_tgid_nr(t);  	context->target_auid = audit_get_loginuid(t); @@ -2277,19 +2282,19 @@ void __audit_ptrace(struct task_struct *t)  int audit_signal_info(int sig, struct task_struct *t)  {  	struct audit_aux_data_pids *axp; -	struct task_struct *tsk = current; -	struct audit_context *ctx = tsk->audit_context; -	kuid_t uid = current_uid(), t_uid = task_uid(t); +	struct audit_context *ctx = audit_context(); +	kuid_t uid = current_uid(), auid, t_uid = task_uid(t);  	if (auditd_test_task(t) &&  	    (sig == SIGTERM || sig == SIGHUP ||  	     sig == SIGUSR1 || sig == SIGUSR2)) { -		audit_sig_pid = task_tgid_nr(tsk); -		if (uid_valid(tsk->loginuid)) -			audit_sig_uid = tsk->loginuid; +		audit_sig_pid = task_tgid_nr(current); +		auid = audit_get_loginuid(current); +		if (uid_valid(auid)) +			audit_sig_uid = auid;  		else  			audit_sig_uid = uid; -		security_task_getsecid(tsk, &audit_sig_sid); +		security_task_getsecid(current, &audit_sig_sid);  	}  	if (!audit_signals || audit_dummy_context()) @@ -2345,7 +2350,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,  			   const struct cred *new, const struct cred *old)  {  	struct audit_aux_data_bprm_fcaps *ax; -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	struct cpu_vfs_cap_data vcaps;  	ax = kmalloc(sizeof(*ax), GFP_KERNEL); @@ -2385,7 +2390,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,   */  void __audit_log_capset(const struct cred *new, const struct cred *old)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->capset.pid = task_tgid_nr(current);  	context->capset.cap.effective   = new->cap_effective;  	context->capset.cap.inheritable = new->cap_effective; @@ -2396,7 +2401,7 @@ void __audit_log_capset(const struct cred *new, const struct cred *old)  void __audit_mmap_fd(int fd, int flags)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->mmap.fd = fd;  	context->mmap.flags = flags;  	context->type = AUDIT_MMAP; @@ -2404,7 +2409,7 @@ void __audit_mmap_fd(int fd, int flags)  void __audit_log_kern_module(char *name)  { -	struct audit_context *context = current->audit_context; +	struct audit_context *context = audit_context();  	context->module.name = kmalloc(strlen(name) + 1, GFP_KERNEL);  	strcpy(context->module.name, name); @@ -2413,7 +2418,7 @@ void __audit_log_kern_module(char *name)  void __audit_fanotify(unsigned int response)  { -	audit_log(current->audit_context, GFP_KERNEL, +	audit_log(audit_context(), GFP_KERNEL,  		AUDIT_FANOTIFY,	"resp=%u", response);  } @@ -2464,7 +2469,19 @@ void audit_core_dumps(long signr)  	audit_log_end(ab);  } -void __audit_seccomp(unsigned long syscall, long signr, int code) +/** + * audit_seccomp - record information about a seccomp action + * @syscall: syscall number + * @signr: signal value + * @code: the seccomp action + * + * Record the information associated with a seccomp action. Event filtering for + * seccomp actions that are not to be logged is done in seccomp_log(). + * Therefore, this function forces auditing independent of the audit_enabled + * and dummy context state because seccomp actions should be logged even when + * audit is not in use. + */ +void audit_seccomp(unsigned long syscall, long signr, int code)  {  	struct audit_buffer *ab; @@ -2478,9 +2495,29 @@ void __audit_seccomp(unsigned long syscall, long signr, int code)  	audit_log_end(ab);  } +void audit_seccomp_actions_logged(const char *names, const char *old_names, +				  int res) +{ +	struct audit_buffer *ab; + +	if (!audit_enabled) +		return; + +	ab = audit_log_start(audit_context(), GFP_KERNEL, +			     AUDIT_CONFIG_CHANGE); +	if (unlikely(!ab)) +		return; + +	audit_log_format(ab, "op=seccomp-logging"); +	audit_log_format(ab, " actions=%s", names); +	audit_log_format(ab, " old-actions=%s", old_names); +	audit_log_format(ab, " res=%d", res); +	audit_log_end(ab); +} +  struct list_head *audit_killed_trees(void)  { -	struct audit_context *ctx = current->audit_context; +	struct audit_context *ctx = audit_context();  	if (likely(!ctx || !ctx->in_syscall))  		return NULL;  	return &ctx->killed_trees;  | 
