diff options
| author | Rich Felker <dalias@aerifal.cx> | 2011-09-29 00:48:04 -0400 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2011-09-29 00:48:04 -0400 | 
| commit | 4b87736998e8d8c0610c3c31b6862c77248a98df (patch) | |
| tree | 11540038b5666fc9f6e290c0c66390c364cb8a5c /src | |
| parent | 5f814682b48c59f07568d349f979eed4cf306703 (diff) | |
| download | musl-4b87736998e8d8c0610c3c31b6862c77248a98df.tar.gz | |
fix various bugs in path and error handling in execvp/fexecve
Diffstat (limited to 'src')
| -rw-r--r-- | src/process/execvp.c | 42 | ||||
| -rw-r--r-- | src/process/fexecve.c | 5 | 
2 files changed, 29 insertions, 18 deletions
| diff --git a/src/process/execvp.c b/src/process/execvp.c index d799ddae..b2da44b9 100644 --- a/src/process/execvp.c +++ b/src/process/execvp.c @@ -2,33 +2,41 @@  #include <string.h>  #include <unistd.h>  #include <errno.h> - -extern char **__environ; +#include <limits.h>  int execvp(const char *file, char *const argv[])  {  	const char *p, *z, *path = getenv("PATH"); -	int l; +	size_t l, k; + +	errno = ENOENT; +	if (!*file) return -1;  	if (strchr(file, '/')) -		return execve(file, argv, __environ); +		return execv(file, argv); -	/* FIXME: integer overflows */  	if (!path) path = "/usr/local/bin:/bin:/usr/bin"; -	l = strlen(file) + strlen(path) + 2; +	k = strnlen(file, NAME_MAX+1); +	if (k > NAME_MAX) { +		errno = ENAMETOOLONG; +		return -1; +	} +	l = strnlen(path, PATH_MAX-1)+1; -	for(p=path; p && *p; p=z) { -		char b[l]; +	for(p=path; ; p=z) { +		char b[l+k+1];  		z = strchr(p, ':'); -		if (z) { -			memcpy(b, p, z-p); -			b[z++-p] = 0; -		} else strcpy(b, p); -		strcat(b, "/"); -		strcat(b, file); -		if (!access(b, X_OK)) -			return execve(b, argv, __environ); +		if (!z) z = p+strlen(p); +		if (z-p >= l) { +			if (!*z++) break; +			continue; +		} +		memcpy(b, p, z-p); +		b[z-p] = '/'; +		memcpy(b+(z-p)+(z>p), file, k+1); +		execv(b, argv); +		if (errno != ENOENT) return -1; +		if (!*z++) break;  	} -	errno = ENOENT;  	return -1;  } diff --git a/src/process/fexecve.c b/src/process/fexecve.c index 3098645d..5939181a 100644 --- a/src/process/fexecve.c +++ b/src/process/fexecve.c @@ -1,10 +1,13 @@  #include <unistd.h>  #include <stdio.h> +#include <errno.h>  int fexecve(int fd, char *const argv[], char *const envp[])  {  	static const char proc[] = "/proc/self/fd/%d";  	char buf[sizeof proc + 3*sizeof(int)];  	snprintf(buf, sizeof buf, proc, fd); -	return execve(buf, argv, envp); +	execve(buf, argv, envp); +	if (errno == ENOENT) errno = EBADF; +	return -1;  } | 
