aboutsummaryrefslogtreecommitdiffstats
path: root/mjit.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-04 12:46:50 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-04 12:46:50 +0000
commitef94a94d7d7146f51cd99814aa45ec0911794de5 (patch)
treee906eb325e423d7cc47619db0e588eb57809a79e /mjit.c
parentc111c42ba28729c5d0046799085fad2e38a5a9ef (diff)
downloadruby-ef94a94d7d7146f51cd99814aa45ec0911794de5.tar.gz
Check MJIT_BUILD_DIR strictly
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65536 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'mjit.c')
-rw-r--r--mjit.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/mjit.c b/mjit.c
index 889dee8702..2bdd53c329 100644
--- a/mjit.c
+++ b/mjit.c
@@ -380,6 +380,10 @@ init_header_filename(void)
;
const size_t libpathflag_len = sizeof(libpathflag) - 1;
#endif
+#ifndef LOAD_RELATIVE
+ static const char build_dir[] = MJIT_BUILD_DIR;
+ struct stat st;
+#endif
basedir_val = ruby_prefix_path;
basedir = StringValuePtr(basedir_val);
@@ -390,8 +394,15 @@ init_header_filename(void)
/* This path is not intended to be used on production, but using build directory's
header file here because people want to run `make test-all` without running
`make install`. Don't use $MJIT_SEARCH_BUILD_DIR except for test-all. */
- basedir = MJIT_BUILD_DIR;
- baselen = strlen(basedir);
+ if (build_dir[0] != '/' ||
+ stat(build_dir, &st) || !S_ISDIR(st.st_mode) ||
+ st.st_uid != getuid() || (st.st_mode & 022) ||
+ !rb_path_check(build_dir)) {
+ verbose(1, "Unsafe MJIT_BUILD_DIR: %s", build_dir);
+ return FALSE;
+ }
+ basedir = build_dir;
+ baselen = sizeof(build_dir) - 1;
}
#endif
@@ -410,6 +421,18 @@ init_header_filename(void)
header_file = NULL;
return FALSE;
}
+#ifndef LOAD_RELATIVE
+ if ((basedir == build_dir) &&
+ (fstat(fd, &st) ||
+ st.st_uid != getuid() ||
+ (st.st_mode & 022))) {
+ (void)close(fd);
+ verbose(1, "Unsafe header file: %s", header_file);
+ xfree(header_file);
+ header_file = NULL;
+ return FALSE;
+ }
+#endif
(void)close(fd);
}