aboutsummaryrefslogtreecommitdiffstats
path: root/mjit.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-07 13:26:09 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-07 13:26:09 +0000
commit0dd0971ee7b1ea66aea7ba83f08d8b9976bf625d (patch)
treeba413668fb651b82a0fa5e186608246f318b4902 /mjit.c
parenta08ab9d1d6bc9de7d0be48790e7c809c6bc0b989 (diff)
downloadruby-0dd0971ee7b1ea66aea7ba83f08d8b9976bf625d.tar.gz
mjit.c: fix buffer overflow
* mjit.c (sprint_uniq_filename): get rid of silent buffer overflow. * mjit.c (get_uniq_filename, convert_unit_to_func): allocate enough buffer before formatting. * mjit.c (convert_unit_to_func): use DLEXT instead of hard coded extension. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62281 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'mjit.c')
-rw-r--r--mjit.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/mjit.c b/mjit.c
index e51c703d5a..ac76121de4 100644
--- a/mjit.c
+++ b/mjit.c
@@ -229,10 +229,10 @@ real_ms_time(void)
/* Make and return copy of STR in the heap. */
#define get_string ruby_strdup
-static void
-sprint_uniq_filename(char *str, unsigned long id, const char *prefix, const char *suffix)
+static int
+sprint_uniq_filename(char *str, size_t size, unsigned long id, const char *prefix, const char *suffix)
{
- sprintf(str, "%s/%sp%luu%lu%s", tmp_dir, prefix, (unsigned long) getpid(), id, suffix);
+ return snprintf(str, size, "%s/%sp%luu%lu%s", tmp_dir, prefix, (unsigned long) getpid(), id, suffix);
}
/* Return an unique file name in /tmp with PREFIX and SUFFIX and
@@ -241,9 +241,18 @@ sprint_uniq_filename(char *str, unsigned long id, const char *prefix, const char
static char *
get_uniq_filename(unsigned long id, const char *prefix, const char *suffix)
{
- char str[70];
- sprint_uniq_filename(str, id, prefix, suffix);
- return get_string(str);
+ char buff[70], *str = buff;
+ int size = sprint_uniq_filename(buff, sizeof(buff), id, prefix, suffix);
+ str = 0;
+ ++size;
+ str = xmalloc(size);
+ if (size <= (int)sizeof(buff)) {
+ memcpy(str, buff, size);
+ }
+ else {
+ sprint_uniq_filename(str, size, id, prefix, suffix);
+ }
+ return str;
}
/* Print the arguments according to FORMAT to stderr only if MJIT
@@ -735,14 +744,25 @@ load_func_from_so(const char *so_file, const char *funcname, struct rb_mjit_unit
static mjit_func_t
convert_unit_to_func(struct rb_mjit_unit *unit)
{
- char c_file[70], so_file[70], funcname[35];
+ char c_file_buff[70], *c_file = c_file_buff, *so_file, funcname[35];
int success;
FILE *f;
void *func;
double start_time, end_time;
-
- sprint_uniq_filename(c_file, unit->id, MJIT_TMP_PREFIX, ".c");
- sprint_uniq_filename(so_file, unit->id, MJIT_TMP_PREFIX, ".so");
+ int c_file_len = (int)sizeof(c_file_buff);
+ static const char c_ext[] = ".c";
+ static const char so_ext[] = DLEXT;
+
+ c_file_len = sprint_uniq_filename(c_file_buff, c_file_len, unit->id, MJIT_TMP_PREFIX, c_ext);
+ if (c_file_len >= (int)sizeof(c_file_buff)) {
+ ++c_file_len;
+ c_file = alloca(c_file_len);
+ c_file_len = sprint_uniq_filename(c_file_buff, c_file_len, unit->id, MJIT_TMP_PREFIX, c_ext);
+ }
+ ++c_file_len;
+ so_file = alloca(c_file_len - sizeof(c_ext) + sizeof(so_ext));
+ memcpy(so_file, c_file, c_file_len - sizeof(c_ext));
+ memcpy(&so_file[c_file_len - sizeof(c_ext)], so_ext, sizeof(so_ext));
sprintf(funcname, "_mjit%d", unit->id);
f = fopen(c_file, "w");