linux, darwin: don't touch environ in uv_setup_args
Don't overwrite the environment. On OS X, the entries in the environ table are not necessarily adjacent. It's arguably also safer for setuid binaries. Fixes joyent/node#4847.
This commit is contained in:
parent
c5101ae9b5
commit
a0c1d84c14
@ -30,68 +30,45 @@ static void* args_mem;
|
|||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char* str;
|
char* str;
|
||||||
int len;
|
size_t len;
|
||||||
} process_title;
|
} process_title;
|
||||||
|
|
||||||
|
|
||||||
char** uv_setup_args(int argc, char** argv) {
|
char** uv_setup_args(int argc, char** argv) {
|
||||||
char** new_argv;
|
char** new_argv;
|
||||||
char** new_env;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
int envc;
|
|
||||||
char* s;
|
char* s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
if (argc <= 0)
|
||||||
char*** _NSGetArgv(void);
|
return argv;
|
||||||
char*** _NSGetEnviron(void);
|
|
||||||
char** environ = *_NSGetEnviron();
|
|
||||||
#else
|
|
||||||
extern char** environ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (envc = 0; environ[envc]; envc++);
|
/* Calculate how much memory we need for the argv strings. */
|
||||||
|
size = 0;
|
||||||
if (envc == 0)
|
for (i = 0; i < argc; i++)
|
||||||
s = argv[argc - 1];
|
size += strlen(argv[i]) + 1;
|
||||||
else
|
|
||||||
s = environ[envc - 1];
|
|
||||||
|
|
||||||
process_title.str = argv[0];
|
process_title.str = argv[0];
|
||||||
process_title.len = s + strlen(s) + 1 - argv[0];
|
process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0];
|
||||||
|
assert(process_title.len + 1 == size); /* argv memory should be adjacent. */
|
||||||
|
|
||||||
size = process_title.len;
|
/* Add space for the argv pointers. */
|
||||||
size += (argc + 1) * sizeof(char**);
|
size += (argc + 1) * sizeof(char*);
|
||||||
size += (envc + 1) * sizeof(char**);
|
|
||||||
s = args_mem = malloc(size);
|
|
||||||
|
|
||||||
if (s == NULL) {
|
new_argv = malloc(size);
|
||||||
process_title.str = NULL;
|
if (new_argv == NULL)
|
||||||
process_title.len = 0;
|
|
||||||
return argv;
|
return argv;
|
||||||
|
args_mem = new_argv;
|
||||||
|
|
||||||
|
/* Copy over the strings and set up the pointer table. */
|
||||||
|
s = (char*) &new_argv[argc + 1];
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
size = strlen(argv[i]) + 1;
|
||||||
|
memcpy(s, argv[i], size);
|
||||||
|
new_argv[i] = s;
|
||||||
|
s += size;
|
||||||
}
|
}
|
||||||
|
new_argv[i] = NULL;
|
||||||
new_argv = (char**) s;
|
|
||||||
new_env = new_argv + argc + 1;
|
|
||||||
s = (char*) (new_env + envc + 1);
|
|
||||||
memcpy(s, process_title.str, process_title.len);
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
new_argv[i] = s + (argv[i] - argv[0]);
|
|
||||||
new_argv[argc] = NULL;
|
|
||||||
|
|
||||||
s += environ[0] - argv[0];
|
|
||||||
|
|
||||||
for (i = 0; i < envc; i++)
|
|
||||||
new_env[i] = s + (environ[i] - environ[0]);
|
|
||||||
new_env[envc] = NULL;
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
*_NSGetArgv() = new_argv;
|
|
||||||
*_NSGetEnviron() = new_env;
|
|
||||||
#else
|
|
||||||
environ = new_env;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new_argv;
|
return new_argv;
|
||||||
}
|
}
|
||||||
@ -101,8 +78,8 @@ uv_err_t uv_set_process_title(const char* title) {
|
|||||||
if (process_title.len == 0)
|
if (process_title.len == 0)
|
||||||
return uv_ok_;
|
return uv_ok_;
|
||||||
|
|
||||||
/* No need to terminate, last char is always '\0'. */
|
/* No need to terminate, byte after is always '\0'. */
|
||||||
strncpy(process_title.str, title, process_title.len - 1);
|
strncpy(process_title.str, title, process_title.len);
|
||||||
uv__set_process_title(title);
|
uv__set_process_title(title);
|
||||||
|
|
||||||
return uv_ok_;
|
return uv_ok_;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user