mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	exec: binfmt_misc: fix race between load_misc_binary() and kill_node()
load_misc_binary() makes a local copy of fmt->interpreter under entries_lock to avoid the race with kill_node() but this is not enough; the whole Node can be freed after we drop entries_lock, not only the ->interpreter string. Add dget/dput(fmt->dentry) to ensure bm_evict_inode() can't destroy/free this Node. Link: http://lkml.kernel.org/r/20170922143650.GA17227@redhat.com Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Kees Cook <keescook@chromium.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Ben Woodard <woodard@redhat.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: Jim Foraker <foraker1@llnl.gov> Cc: Travis Gummels <tgummels@redhat.com> Cc: <tdhooge@llnl.gov> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									eb23aa0317
								
							
						
					
					
						commit
						43a4f26190
					
				
					 1 changed files with 8 additions and 4 deletions
				
			
		|  | @ -138,20 +138,23 @@ static int load_misc_binary(struct linux_binprm *bprm) | ||||||
| 
 | 
 | ||||||
| 	retval = -ENOEXEC; | 	retval = -ENOEXEC; | ||||||
| 	if (!enabled) | 	if (!enabled) | ||||||
| 		goto ret; | 		return retval; | ||||||
| 
 | 
 | ||||||
| 	/* to keep locking time low, we copy the interpreter string */ | 	/* to keep locking time low, we copy the interpreter string */ | ||||||
| 	read_lock(&entries_lock); | 	read_lock(&entries_lock); | ||||||
| 	fmt = check_file(bprm); | 	fmt = check_file(bprm); | ||||||
| 	if (fmt) | 	if (fmt) { | ||||||
|  | 		dget(fmt->dentry); | ||||||
| 		strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE); | 		strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE); | ||||||
|  | 	} | ||||||
| 	read_unlock(&entries_lock); | 	read_unlock(&entries_lock); | ||||||
| 	if (!fmt) | 	if (!fmt) | ||||||
| 		goto ret; | 		return retval; | ||||||
| 
 | 
 | ||||||
| 	/* Need to be able to load the file after exec */ | 	/* Need to be able to load the file after exec */ | ||||||
|  | 	retval = -ENOENT; | ||||||
| 	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) | 	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) | ||||||
| 		return -ENOENT; | 		goto ret; | ||||||
| 
 | 
 | ||||||
| 	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { | 	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { | ||||||
| 		retval = remove_arg_zero(bprm); | 		retval = remove_arg_zero(bprm); | ||||||
|  | @ -238,6 +241,7 @@ static int load_misc_binary(struct linux_binprm *bprm) | ||||||
| 		goto error; | 		goto error; | ||||||
| 
 | 
 | ||||||
| ret: | ret: | ||||||
|  | 	dput(fmt->dentry); | ||||||
| 	return retval; | 	return retval; | ||||||
| error: | error: | ||||||
| 	if (fd_binary > 0) | 	if (fd_binary > 0) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Oleg Nesterov
						Oleg Nesterov