From 23c73ff3998782f5e2a7f1f3755fddf8ceed0d30 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 24 Nov 2016 13:50:36 +0900 Subject: Time#initialize_copy: Check if source time is initialized. To prevent crash from nasty code like: class Time def initialize end end a = Time.new b = Time.new a.initialize_copy b --- mrbgems/mruby-time/src/time.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 19ce32832..5c23bd44a 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -611,16 +611,23 @@ static mrb_value mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) { mrb_value src; + struct mrb_time *t1, *t2; mrb_get_args(mrb, "o", &src); if (mrb_obj_equal(mrb, copy, src)) return copy; if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } - if (!DATA_PTR(copy)) { - mrb_data_init(copy, mrb_malloc(mrb, sizeof(struct mrb_time)), &mrb_time_type); + t1 = (struct mrb_time *)DATA_PTR(copy); + t2 = (struct mrb_time *)DATA_PTR(src); + if (!t2) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); } - *(struct mrb_time *)DATA_PTR(copy) = *(struct mrb_time *)DATA_PTR(src); + if (!t1) { + t1 = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); + mrb_data_init(copy, t1, &mrb_time_type); + } + *t1 = *t2; return copy; } -- cgit v1.2.3 From b7f9a58757bdf30e9d64191ac47d81144e3f6098 Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Wed, 16 Nov 2016 17:14:16 -0500 Subject: Fix null pointer dereference in mrb_time_initialize Reported by https://hackerone.com/raydot --- mrbgems/mruby-time/src/time.c | 4 ++-- mrbgems/mruby-time/test/time.rb | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 5c23bd44a..dfd4450da 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -587,14 +587,14 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self) int n; struct mrb_time *tm; + n = mrb_get_args(mrb, "|iiiiiii", + &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); tm = (struct mrb_time*)DATA_PTR(self); if (tm) { mrb_free(mrb, tm); } mrb_data_init(self, NULL, &mrb_time_type); - n = mrb_get_args(mrb, "|iiiiiii", - &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); if (n == 0) { tm = current_mrb_time(mrb); } diff --git a/mrbgems/mruby-time/test/time.rb b/mrbgems/mruby-time/test/time.rb index 759e2881d..91a646759 100644 --- a/mrbgems/mruby-time/test/time.rb +++ b/mrbgems/mruby-time/test/time.rb @@ -211,3 +211,14 @@ assert('2000 times 500us make a second') do end t.usec == 0 end + +assert("Time#initialize doens't leave uninitialized object accessible") do + assert_raise ArgumentError do + $x = Time.new + a = Object.new + def a.to_i + $x.mday + end + $x.initialize a + end +end -- cgit v1.2.3 From 3d9aa463f7ff5e813b04863c70d3aec0b0977946 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 26 Nov 2016 12:18:27 +0900 Subject: Add NULL checks for Time data retrieval --- mrbgems/mruby-time/src/time.c | 61 +++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index dfd4450da..089814890 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -368,6 +368,17 @@ mrb_time_local(mrb_state *mrb, mrb_value self) time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL)); } +static struct mrb_time* +time_get_ptr(mrb_state *mrb, mrb_value time) +{ + struct mrb_time *tm; + + tm = DATA_GET_PTR(mrb, time, &mrb_time_type, struct mrb_time); + if (!tm) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); + } + return tm; +} static mrb_value mrb_time_eq(mrb_state *mrb, mrb_value self) @@ -377,7 +388,7 @@ mrb_time_eq(mrb_state *mrb, mrb_value self) mrb_bool eq_p; mrb_get_args(mrb, "o", &other); - tm1 = DATA_CHECK_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec; @@ -391,7 +402,7 @@ mrb_time_cmp(mrb_state *mrb, mrb_value self) struct mrb_time *tm1, *tm2; mrb_get_args(mrb, "o", &other); - tm1 = DATA_CHECK_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); if (!tm1 || !tm2) return mrb_nil_value(); if (tm1->sec > tm2->sec) { @@ -417,7 +428,7 @@ mrb_time_plus(mrb_state *mrb, mrb_value self) struct mrb_time *tm; mrb_get_args(mrb, "f", &f); - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone); } @@ -429,8 +440,7 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) struct mrb_time *tm, *tm2; mrb_get_args(mrb, "o", &other); - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); - + tm = time_get_ptr(mrb, self); tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); if (tm2) { f = (mrb_float)(tm->sec - tm2->sec) @@ -450,7 +460,7 @@ mrb_time_wday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_wday); } @@ -461,7 +471,7 @@ mrb_time_yday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_yday + 1); } @@ -472,7 +482,7 @@ mrb_time_year(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_year + 1900); } @@ -483,7 +493,7 @@ mrb_time_zone(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); if (tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value(); if (tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value(); return mrb_str_new_static(mrb, @@ -501,7 +511,7 @@ mrb_time_asctime(mrb_state *mrb, mrb_value self) char buf[256]; int len; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); d = &tm->datetime; len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d", wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday, @@ -518,8 +528,7 @@ mrb_time_day(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); - if (!tm) return mrb_nil_value(); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_mday); } @@ -531,7 +540,7 @@ mrb_time_dst_p(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_bool_value(tm->datetime.tm_isdst); } @@ -543,7 +552,7 @@ mrb_time_getutc(mrb_state *mrb, mrb_value self) { struct mrb_time *tm, *tm2; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_UTC; @@ -558,7 +567,7 @@ mrb_time_getlocal(mrb_state *mrb, mrb_value self) { struct mrb_time *tm, *tm2; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_LOCAL; @@ -573,7 +582,7 @@ mrb_time_hour(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_hour); } @@ -638,7 +647,7 @@ mrb_time_localtime(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); tm->timezone = MRB_TIMEZONE_LOCAL; mrb_time_update_datetime(tm); return self; @@ -651,7 +660,7 @@ mrb_time_mday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_mday); } @@ -662,7 +671,7 @@ mrb_time_min(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_min); } @@ -673,7 +682,7 @@ mrb_time_mon(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_mon + 1); } @@ -684,7 +693,7 @@ mrb_time_sec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_fixnum_value(tm->datetime.tm_sec); } @@ -696,7 +705,7 @@ mrb_time_to_f(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); } @@ -707,7 +716,7 @@ mrb_time_to_i(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) { return mrb_float_value(mrb, (mrb_float)tm->sec); } @@ -721,7 +730,7 @@ mrb_time_usec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) { return mrb_float_value(mrb, (mrb_float)tm->usec); } @@ -735,7 +744,7 @@ mrb_time_utc(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); tm->timezone = MRB_TIMEZONE_UTC; mrb_time_update_datetime(tm); return self; @@ -748,7 +757,7 @@ mrb_time_utc_p(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm = time_get_ptr(mrb, self); return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC); } -- cgit v1.2.3 From 9a962ed2c3057be75cd77d31bfeca0ce50eb89d1 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 6 Dec 2016 10:25:07 +0900 Subject: Raise an exception in time_update_datetime(). The function used to return NULL on error, but not checked in the caller site. --- mrbgems/mruby-time/src/time.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 089814890..9ac0d2002 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -183,7 +183,7 @@ static const struct mrb_data_type mrb_time_type = { "Time", mrb_free }; /** Updates the datetime of a mrb_time based on it's timezone and seconds setting. Returns self on success, NULL of failure. */ static struct mrb_time* -mrb_time_update_datetime(struct mrb_time *self) +time_update_datetime(mrb_state *mrb, struct mrb_time *self) { struct tm *aid; @@ -193,7 +193,11 @@ mrb_time_update_datetime(struct mrb_time *self) else { aid = localtime_r(&self->sec, &self->datetime); } - if (!aid) return NULL; + if (!aid) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, self->sec)); + /* not reached */ + return NULL; + } #ifdef NO_GMTIME_R self->datetime = *aid; /* copy data */ #endif @@ -238,7 +242,7 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) tm->usec -= 1000000; } tm->timezone = timezone; - mrb_time_update_datetime(tm); + time_update_datetime(mrb, tm); return tm; } @@ -290,7 +294,7 @@ current_mrb_time(mrb_state *mrb) } #endif tm->timezone = MRB_TIMEZONE_LOCAL; - mrb_time_update_datetime(tm); + time_update_datetime(mrb, tm); return tm; } @@ -556,7 +560,7 @@ mrb_time_getutc(mrb_state *mrb, mrb_value self) tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_UTC; - mrb_time_update_datetime(tm2); + time_update_datetime(mrb, tm2); return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } @@ -571,7 +575,7 @@ mrb_time_getlocal(mrb_state *mrb, mrb_value self) tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_LOCAL; - mrb_time_update_datetime(tm2); + time_update_datetime(mrb, tm2); return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } @@ -649,7 +653,7 @@ mrb_time_localtime(mrb_state *mrb, mrb_value self) tm = time_get_ptr(mrb, self); tm->timezone = MRB_TIMEZONE_LOCAL; - mrb_time_update_datetime(tm); + time_update_datetime(mrb, tm); return self; } @@ -746,7 +750,7 @@ mrb_time_utc(mrb_state *mrb, mrb_value self) tm = time_get_ptr(mrb, self); tm->timezone = MRB_TIMEZONE_UTC; - mrb_time_update_datetime(tm); + time_update_datetime(mrb, tm); return self; } -- cgit v1.2.3 From 07167b8f5eb7e0ff7b4048ffcfefe9a38c904a75 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 1 Jan 2017 00:47:45 +0900 Subject: Initialize potentially uninitialized variable tsec. --- mrbgems/mruby-time/src/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 9ac0d2002..cf0926849 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -217,7 +217,7 @@ static struct mrb_time* time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) { struct mrb_time *tm; - time_t tsec; + time_t tsec = 0; if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) { goto out_of_range; -- cgit v1.2.3 From bc1259de3b3e1b2ba690ec5a122e95fb9a7c0d5a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 1 Jan 2017 01:19:12 +0900 Subject: add explicit casts --- mrbgems/mruby-range-ext/src/range.c | 2 +- mrbgems/mruby-time/src/time.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 8aa1379b0..3131192ff 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -156,7 +156,7 @@ mrb_range_size(mrb_state *mrb, mrb_value range) } if (isinf(n+1)) return mrb_float_value(mrb, INFINITY); - return mrb_fixnum_value(n+1); + return mrb_fixnum_value((mrb_int)n+1); } return mrb_nil_value(); } diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index cf0926849..8cadfbcff 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -194,7 +194,7 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self) aid = localtime_r(&self->sec, &self->datetime); } if (!aid) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, self->sec)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec)); /* not reached */ return NULL; } -- cgit v1.2.3 From c4491e477b40adc842ef76e524647607780c8f25 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 9 Jan 2017 10:42:11 +0900 Subject: Validate tm values before timegm(); close #3368 This issue was reported by https://hackerone.com/volc --- mrbgems/mruby-time/src/time.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'mrbgems/mruby-time/src/time.c') diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 8cadfbcff..43d87e5ff 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -332,6 +332,15 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, nowtime.tm_min = (int)amin; nowtime.tm_sec = (int)asec; nowtime.tm_isdst = -1; + + if (nowtime.tm_mon < 0 || nowtime.tm_mon > 11 + || nowtime.tm_mday < 1 || nowtime.tm_mday > 31 + || nowtime.tm_hour < 0 || nowtime.tm_hour > 24 + || (nowtime.tm_hour == 24 && (nowtime.tm_min > 0 || nowtime.tm_sec > 0)) + || nowtime.tm_min < 0 || nowtime.tm_min > 59 + || nowtime.tm_sec < 0 || nowtime.tm_sec > 60) + mrb_raise(mrb, E_RUNTIME_ERROR, "argument out of range"); + if (timezone == MRB_TIMEZONE_UTC) { nowsecs = timegm(&nowtime); } -- cgit v1.2.3