Check $HOME and home dir of $USER before getpwuid()->pw_dir
getpwnam(3) recommends to use $HOME instead of getpwuid()->pw_dir, as it allows users to point programs to a different path. Using getpwuid() also breaks namespaces-related use cases, like `unshare -r`. Patch was submitted by Dmitry Bogatov on the Debian bug tracker: https://bugs.debian.org/825397 Signed-off-by: Christoph Lohmann <20h@r-36.net>
This commit is contained in:
		
							parent
							
								
									3530d18d8e
								
							
						
					
					
						commit
						cee8f0186c
					
				
							
								
								
									
										43
									
								
								surf.c
								
								
								
								
							
							
						
						
									
										43
									
								
								surf.c
								
								
								
								
							|  | @ -350,29 +350,58 @@ buildfile(const char *path) | ||||||
| 	return fpath; | 	return fpath; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static const char* | ||||||
|  | get_user_homedir(const char *user) { | ||||||
|  | 	struct passwd *pw = getpwnam(user); | ||||||
|  | 	if (!pw) { | ||||||
|  | 		die("Can't get user `%s' home directory.\n", user); | ||||||
|  | 	} | ||||||
|  | 	return pw->pw_dir; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char* | ||||||
|  | get_current_user_homedir() { | ||||||
|  | 	const char *homedir; | ||||||
|  | 	const char *user; | ||||||
|  | 	struct passwd *pw; | ||||||
|  | 
 | ||||||
|  | 	homedir = getenv("HOME"); | ||||||
|  | 	if (homedir) { | ||||||
|  | 		return homedir; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	user = getenv("USER"); | ||||||
|  | 	if (user) { | ||||||
|  | 		return get_user_homedir(user); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pw = getpwuid(getuid()); | ||||||
|  | 	if (!pw) { | ||||||
|  | 		die("Can't get current user home directory\n"); | ||||||
|  | 	} | ||||||
|  | 	return pw->pw_dir; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| char * | char * | ||||||
| buildpath(const char *path) | buildpath(const char *path) | ||||||
| { | { | ||||||
| 	struct passwd *pw; |  | ||||||
| 	char *apath, *name, *p, *fpath; | 	char *apath, *name, *p, *fpath; | ||||||
| 
 | 
 | ||||||
| 	if (path[0] == '~') { | 	if (path[0] == '~') { | ||||||
|  | 		const char *homedir; | ||||||
| 		if (path[1] == '/' || path[1] == '\0') { | 		if (path[1] == '/' || path[1] == '\0') { | ||||||
| 			p = (char *)&path[1]; | 			p = (char *)&path[1]; | ||||||
| 			pw = getpwuid(getuid()); | 			homedir = get_current_user_homedir(); | ||||||
| 		} else { | 		} else { | ||||||
| 			if ((p = strchr(path, '/'))) | 			if ((p = strchr(path, '/'))) | ||||||
| 				name = g_strndup(&path[1], --p - path); | 				name = g_strndup(&path[1], --p - path); | ||||||
| 			else | 			else | ||||||
| 				name = g_strdup(&path[1]); | 				name = g_strdup(&path[1]); | ||||||
| 
 | 
 | ||||||
| 			if (!(pw = getpwnam(name))) { | 			homedir = get_user_homedir(name); | ||||||
| 				die("Can't get user %s home directory: %s.\n", |  | ||||||
| 				    name, path); |  | ||||||
| 			} |  | ||||||
| 			g_free(name); | 			g_free(name); | ||||||
| 		} | 		} | ||||||
| 		apath = g_build_filename(pw->pw_dir, p, NULL); | 		apath = g_build_filename(homedir, p, NULL); | ||||||
| 	} else { | 	} else { | ||||||
| 		apath = g_strdup(path); | 		apath = g_strdup(path); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue