summaryrefslogtreecommitdiff
path: root/mjit.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-25 01:06:15 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-25 01:06:15 +0000
commitd3e8d4f35aabceef90445532b10b160a5ef52fcf (patch)
tree11e721ec62e5136c7aa5e4d99cbf794c3d7a6487 /mjit.c
parent8c8247c6eb554d32fdb03f199df9c14d18bf71dc (diff)
mjit.c: avoid execvp PATH lookup in vfork-ed child
execvp(3) is not async-signal-safe and may alter libc internal states (e.g. those used by malloc). However execv(3) is async-signal-safe as of POSIX.1-2008. So perform the PATH lookup in the parent and use execv(3) in the child. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63744 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'mjit.c')
-rw-r--r--mjit.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/mjit.c b/mjit.c
index 5c6cf47cc7..2f025a66b6 100644
--- a/mjit.c
+++ b/mjit.c
@@ -95,6 +95,15 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#include "dln.h"
+
+#ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+#endif
extern void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
extern void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
@@ -349,8 +358,19 @@ start_process(const char *path, char *const *argv)
pid = spawnvp(_P_NOWAIT, path, argv);
#else
{
- /* Not calling IO functions between fork and exec for safety */
- int dev_null = rb_cloexec_open(ruby_null_device, O_WRONLY, 0);
+ /*
+ * Not calling non-async-signal-safe functions between vfork
+ * and execv for safety
+ */
+ char fbuf[MAXPATHLEN];
+ const char *abspath = dln_find_exe_r(path, 0, fbuf, sizeof(fbuf));
+ int dev_null;
+
+ if (!abspath) {
+ fprintf(stderr, "failed to find `%s' in PATH\n", path);
+ return -1;
+ }
+ dev_null = rb_cloexec_open(ruby_null_device, O_WRONLY, 0);
if ((pid = vfork()) == 0) {
umask(0077);
@@ -362,11 +382,11 @@ start_process(const char *path, char *const *argv)
dup2(dev_null, STDOUT_FILENO);
}
(void)close(dev_null);
- pid = execvp(path, argv); /* Pid will be negative on an error */
+ pid = execv(abspath, argv); /* Pid will be negative on an error */
/* Even if we successfully found CC to compile PCH we still can
fail with loading the CC in very rare cases for some reasons.
Stop the forked process in this case. */
- verbose(1, "MJIT: Error in execvp: %s\n", path);
+ verbose(1, "MJIT: Error in execv: %s\n", abspath);
_exit(1);
}
(void)close(dev_null);
@@ -1313,9 +1333,6 @@ system_default_tmpdir(void)
return tmpdir;
}
#elif defined _CS_DARWIN_USER_TEMP_DIR
- #ifndef MAXPATHLEN
- #define MAXPATHLEN 1024
- #endif
char path[MAXPATHLEN];
size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
if (len > 0) {