mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	[PATCH] get rid of AVC_PATH postponed treatment
Selinux folks had been complaining about the lack of AVC_PATH
records when audit is disabled.  I must admit my stupidity - I assumed
that avc_audit() really couldn't use audit_log_d_path() because of
deadlocks (== could be called with dcache_lock or vfsmount_lock held).
Shouldn't have made that assumption - it never gets called that way.
It _is_ called under spinlocks, but not those.
        Since audit_log_d_path() uses ab->gfp_mask for allocations,
kmalloc() in there is not a problem.  IOW, the simple fix is sufficient:
let's rip AUDIT_AVC_PATH out and simply generate pathname as part of main
record.  It's trivial to do.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: James Morris <jmorris@namei.org>
			
			
This commit is contained in:
		
							parent
							
								
									74f2345b6b
								
							
						
					
					
						commit
						4259fa01a2
					
				
					 3 changed files with 8 additions and 56 deletions
				
			
		|  | @ -411,7 +411,6 @@ extern int audit_bprm(struct linux_binprm *bprm); | ||||||
| extern int audit_socketcall(int nargs, unsigned long *args); | extern int audit_socketcall(int nargs, unsigned long *args); | ||||||
| extern int audit_sockaddr(int len, void *addr); | extern int audit_sockaddr(int len, void *addr); | ||||||
| extern int __audit_fd_pair(int fd1, int fd2); | extern int __audit_fd_pair(int fd1, int fd2); | ||||||
| extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |  | ||||||
| extern int audit_set_macxattr(const char *name); | extern int audit_set_macxattr(const char *name); | ||||||
| extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); | extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); | ||||||
| extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); | extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); | ||||||
|  | @ -491,7 +490,6 @@ extern int audit_signals; | ||||||
| #define audit_socketcall(n,a) ({ 0; }) | #define audit_socketcall(n,a) ({ 0; }) | ||||||
| #define audit_fd_pair(n,a) ({ 0; }) | #define audit_fd_pair(n,a) ({ 0; }) | ||||||
| #define audit_sockaddr(len, addr) ({ 0; }) | #define audit_sockaddr(len, addr) ({ 0; }) | ||||||
| #define audit_avc_path(dentry, mnt) ({ 0; }) |  | ||||||
| #define audit_set_macxattr(n) do { ; } while (0) | #define audit_set_macxattr(n) do { ; } while (0) | ||||||
| #define audit_mq_open(o,m,a) ({ 0; }) | #define audit_mq_open(o,m,a) ({ 0; }) | ||||||
| #define audit_mq_timedsend(d,l,p,t) ({ 0; }) | #define audit_mq_timedsend(d,l,p,t) ({ 0; }) | ||||||
|  |  | ||||||
|  | @ -173,12 +173,6 @@ struct audit_aux_data_fd_pair { | ||||||
| 	int	fd[2]; | 	int	fd[2]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct audit_aux_data_path { |  | ||||||
| 	struct audit_aux_data	d; |  | ||||||
| 	struct dentry		*dentry; |  | ||||||
| 	struct vfsmount		*mnt; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct audit_aux_data_pids { | struct audit_aux_data_pids { | ||||||
| 	struct audit_aux_data	d; | 	struct audit_aux_data	d; | ||||||
| 	pid_t			target_pid[AUDIT_AUX_PIDS]; | 	pid_t			target_pid[AUDIT_AUX_PIDS]; | ||||||
|  | @ -654,12 +648,6 @@ static inline void audit_free_aux(struct audit_context *context) | ||||||
| 	struct audit_aux_data *aux; | 	struct audit_aux_data *aux; | ||||||
| 
 | 
 | ||||||
| 	while ((aux = context->aux)) { | 	while ((aux = context->aux)) { | ||||||
| 		if (aux->type == AUDIT_AVC_PATH) { |  | ||||||
| 			struct audit_aux_data_path *axi = (void *)aux; |  | ||||||
| 			dput(axi->dentry); |  | ||||||
| 			mntput(axi->mnt); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		context->aux = aux->next; | 		context->aux = aux->next; | ||||||
| 		kfree(aux); | 		kfree(aux); | ||||||
| 	} | 	} | ||||||
|  | @ -1038,11 +1026,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | ||||||
| 			audit_log_hex(ab, axs->a, axs->len); | 			audit_log_hex(ab, axs->a, axs->len); | ||||||
| 			break; } | 			break; } | ||||||
| 
 | 
 | ||||||
| 		case AUDIT_AVC_PATH: { |  | ||||||
| 			struct audit_aux_data_path *axi = (void *)aux; |  | ||||||
| 			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); |  | ||||||
| 			break; } |  | ||||||
| 
 |  | ||||||
| 		case AUDIT_FD_PAIR: { | 		case AUDIT_FD_PAIR: { | ||||||
| 			struct audit_aux_data_fd_pair *axs = (void *)aux; | 			struct audit_aux_data_fd_pair *axs = (void *)aux; | ||||||
| 			audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | 			audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | ||||||
|  | @ -1990,36 +1973,6 @@ void __audit_ptrace(struct task_struct *t) | ||||||
| 	selinux_get_task_sid(t, &context->target_sid); | 	selinux_get_task_sid(t, &context->target_sid); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * audit_avc_path - record the granting or denial of permissions |  | ||||||
|  * @dentry: dentry to record |  | ||||||
|  * @mnt: mnt to record |  | ||||||
|  * |  | ||||||
|  * Returns 0 for success or NULL context or < 0 on error. |  | ||||||
|  * |  | ||||||
|  * Called from security/selinux/avc.c::avc_audit() |  | ||||||
|  */ |  | ||||||
| int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) |  | ||||||
| { |  | ||||||
| 	struct audit_aux_data_path *ax; |  | ||||||
| 	struct audit_context *context = current->audit_context; |  | ||||||
| 
 |  | ||||||
| 	if (likely(!context)) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |  | ||||||
| 	if (!ax) |  | ||||||
| 		return -ENOMEM; |  | ||||||
| 
 |  | ||||||
| 	ax->dentry = dget(dentry); |  | ||||||
| 	ax->mnt = mntget(mnt); |  | ||||||
| 
 |  | ||||||
| 	ax->d.type = AUDIT_AVC_PATH; |  | ||||||
| 	ax->d.next = context->aux; |  | ||||||
| 	context->aux = (void *)ax; |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * audit_signal_info - record signal info for shutting down audit subsystem |  * audit_signal_info - record signal info for shutting down audit subsystem | ||||||
|  * @sig: signal value |  * @sig: signal value | ||||||
|  |  | ||||||
|  | @ -570,10 +570,12 @@ void avc_audit(u32 ssid, u32 tsid, | ||||||
| 		case AVC_AUDIT_DATA_FS: | 		case AVC_AUDIT_DATA_FS: | ||||||
| 			if (a->u.fs.dentry) { | 			if (a->u.fs.dentry) { | ||||||
| 				struct dentry *dentry = a->u.fs.dentry; | 				struct dentry *dentry = a->u.fs.dentry; | ||||||
| 				if (a->u.fs.mnt) | 				if (a->u.fs.mnt) { | ||||||
| 					audit_avc_path(dentry, a->u.fs.mnt); | 					audit_log_d_path(ab, "path=", dentry, a->u.fs.mnt); | ||||||
| 				audit_log_format(ab, " name="); | 				} else { | ||||||
| 				audit_log_untrustedstring(ab, dentry->d_name.name); | 					audit_log_format(ab, " name="); | ||||||
|  | 					audit_log_untrustedstring(ab, dentry->d_name.name); | ||||||
|  | 				} | ||||||
| 				inode = dentry->d_inode; | 				inode = dentry->d_inode; | ||||||
| 			} else if (a->u.fs.inode) { | 			} else if (a->u.fs.inode) { | ||||||
| 				struct dentry *dentry; | 				struct dentry *dentry; | ||||||
|  | @ -624,9 +626,8 @@ void avc_audit(u32 ssid, u32 tsid, | ||||||
| 				case AF_UNIX: | 				case AF_UNIX: | ||||||
| 					u = unix_sk(sk); | 					u = unix_sk(sk); | ||||||
| 					if (u->dentry) { | 					if (u->dentry) { | ||||||
| 						audit_avc_path(u->dentry, u->mnt); | 						audit_log_d_path(ab, "path=", | ||||||
| 						audit_log_format(ab, " name="); | 								 u->dentry, u->mnt); | ||||||
| 						audit_log_untrustedstring(ab, u->dentry->d_name.name); |  | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 					if (!u->addr) | 					if (!u->addr) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Al Viro
						Al Viro