--- rpms/php/sme8/php-5.3.3-CVE-2012-0789.patch 2012/06/29 14:45:08 1.1 +++ rpms/php/sme8/php-5.3.3-CVE-2012-0789.patch 2012/06/29 14:45:08 1.1.2.1 @@ -0,0 +1,382 @@ + +https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-0789 + +http://git.php.net/?p=php-src.git;a=commitdiff;h=5b2ce47f2e98e672873f6da0f41fff120af1e57e + - with unrelated changes reverted + +--- php-5.3.3/ext/date/lib/parse_date.c.cve0789 ++++ php-5.3.3/ext/date/lib/parse_date.c +@@ -756,7 +756,7 @@ static long timelib_lookup_zone(char **p + return value; + } + +-static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb) ++static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_wrapper) + { + timelib_tzinfo *res; + long retval = 0; +@@ -805,7 +805,7 @@ static long timelib_get_zone(char **ptr, + #endif + /* If we have a TimeZone identifier to start with, use it */ + if (strstr(tz_abbr, "/") || strcmp(tz_abbr, "UTC") == 0) { +- if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { ++ if ((res = tz_wrapper(tz_abbr, tzdb)) != NULL) { + t->tz_info = res; + t->zone_type = TIMELIB_ZONETYPE_ID; + found++; +@@ -834,7 +834,7 @@ static long timelib_get_zone(char **ptr, + } \ + } + +-static int scan(Scanner *s) ++static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) + { + uchar *cursor = s->cur; + char *str, *ptr = NULL; +@@ -1006,7 +1006,7 @@ yy4: + DEBUG_OUTPUT("tzcorrection | tz"); + TIMELIB_INIT; + TIMELIB_HAVE_TZ(); +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -4451,7 +4451,7 @@ yy223: + } + + if (*ptr != '\0') { +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -9763,7 +9763,7 @@ yy491: + } + + if (*ptr != '\0') { +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -12020,7 +12020,7 @@ yy701: + s->time->h = timelib_get_nr((char **) &ptr, 2); + s->time->i = timelib_get_nr((char **) &ptr, 2); + s->time->s = timelib_get_nr((char **) &ptr, 2); +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -13391,7 +13391,7 @@ yy843: + if (*ptr == '.') { + s->time->f = timelib_get_frac_nr((char **) &ptr, 9); + if (*ptr) { /* timezone is optional */ +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -15731,7 +15731,7 @@ yy1076: + s->time->s = timelib_get_nr((char **) &ptr, 2); + + if (*ptr != '\0') { +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -24632,7 +24632,7 @@ yy1537: + + #define YYMAXFILL 31 + +-timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb) ++timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper) + { + Scanner in; + int t; +@@ -24687,7 +24687,7 @@ timelib_time* timelib_strtotime(char *s, + in.time->zone_type = 0; + + do { +- t = scan(&in); ++ t = scan(&in, tz_get_wrapper); + #ifdef DEBUG_PARSER + printf("%d\n", t); + #endif +@@ -24714,7 +24714,7 @@ timelib_time* timelib_strtotime(char *s, + } + + +-timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb) ++timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper) + { + char *fptr = format; + char *ptr = string; +@@ -24880,7 +24880,7 @@ timelib_time *timelib_parse_from_format( + case 'O': /* timezone */ + { + int tz_not_found; +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_pbf_error(s, "The timezone could not be found in the database", string, begin); + } +--- php-5.3.3/ext/date/lib/parse_date.re.cve0789 ++++ php-5.3.3/ext/date/lib/parse_date.re +@@ -755,7 +755,7 @@ static long timelib_lookup_zone(char **p + return value; + } + +-static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb) ++static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_wrapper) + { + timelib_tzinfo *res; + long retval = 0; +@@ -804,7 +804,7 @@ static long timelib_get_zone(char **ptr, + #endif + /* If we have a TimeZone identifier to start with, use it */ + if (strstr(tz_abbr, "/") || strcmp(tz_abbr, "UTC") == 0) { +- if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { ++ if ((res = tz_wrapper(tz_abbr, tzdb)) != NULL) { + t->tz_info = res; + t->zone_type = TIMELIB_ZONETYPE_ID; + found++; +@@ -833,7 +833,7 @@ static long timelib_get_zone(char **ptr, + } \ + } + +-static int scan(Scanner *s) ++static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) + { + uchar *cursor = s->cur; + char *str, *ptr = NULL; +@@ -1166,7 +1166,7 @@ weekdayof = (reltextnumber|reltex + } + + if (*ptr != '\0') { +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -1207,7 +1207,7 @@ weekdayof = (reltextnumber|reltex + s->time->h = timelib_get_nr((char **) &ptr, 2); + s->time->i = timelib_get_nr((char **) &ptr, 2); + s->time->s = 0; +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb, tz_get_wrapper); + break; + case 1: + s->time->y = timelib_get_nr((char **) &ptr, 4); +@@ -1232,7 +1232,7 @@ weekdayof = (reltextnumber|reltex + s->time->s = timelib_get_nr((char **) &ptr, 2); + + if (*ptr != '\0') { +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -1425,7 +1425,7 @@ weekdayof = (reltextnumber|reltex + if (*ptr == '.') { + s->time->f = timelib_get_frac_nr((char **) &ptr, 9); + if (*ptr) { /* timezone is optional */ +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -1525,7 +1525,7 @@ weekdayof = (reltextnumber|reltex + s->time->h = timelib_get_nr((char **) &ptr, 2); + s->time->i = timelib_get_nr((char **) &ptr, 2); + s->time->s = timelib_get_nr((char **) &ptr, 2); +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -1638,7 +1638,7 @@ weekdayof = (reltextnumber|reltex + DEBUG_OUTPUT("tzcorrection | tz"); + TIMELIB_INIT; + TIMELIB_HAVE_TZ(); +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -1691,7 +1691,7 @@ weekdayof = (reltextnumber|reltex + } + + if (*ptr != '\0') { +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_error(s, "The timezone could not be found in the database"); + } +@@ -1737,7 +1737,7 @@ weekdayof = (reltextnumber|reltex + + /*!max:re2c */ + +-timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb) ++timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper) + { + Scanner in; + int t; +@@ -1792,7 +1792,7 @@ timelib_time* timelib_strtotime(char *s, + in.time->zone_type = 0; + + do { +- t = scan(&in); ++ t = scan(&in, tz_get_wrapper); + #ifdef DEBUG_PARSER + printf("%d\n", t); + #endif +@@ -1819,7 +1819,7 @@ timelib_time* timelib_strtotime(char *s, + } + + +-timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb) ++timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper) + { + char *fptr = format; + char *ptr = string; +@@ -1985,7 +1985,7 @@ timelib_time *timelib_parse_from_format( + case 'O': /* timezone */ + { + int tz_not_found; +- s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); ++ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); + if (tz_not_found) { + add_pbf_error(s, "The timezone could not be found in the database", string, begin); + } +--- php-5.3.3/ext/date/lib/timelib.h.cve0789 ++++ php-5.3.3/ext/date/lib/timelib.h +@@ -50,6 +50,9 @@ + #define strncasecmp strnicmp + #endif + ++/* Function pointers */ ++typedef timelib_tzinfo* (*timelib_tz_get_wrapper)(char *tzname, const timelib_tzdb *tzdb); ++ + /* From dow.c */ + timelib_sll timelib_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d); + timelib_sll timelib_iso_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d); +@@ -61,8 +64,8 @@ int timelib_valid_time(timelib_sll h, ti + int timelib_valid_date(timelib_sll y, timelib_sll m, timelib_sll d); + + /* From parse_date.re */ +-timelib_time *timelib_strtotime(char *s, int len, timelib_error_container **errors, const timelib_tzdb *tzdb); +-timelib_time *timelib_parse_from_format(char *format, char *s, int len, timelib_error_container **errors, const timelib_tzdb *tzdb); ++timelib_time *timelib_strtotime(char *s, int len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper); ++timelib_time *timelib_parse_from_format(char *format, char *s, int len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper); + void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options); + char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst); + const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void); +--- php-5.3.3/ext/date/php_date.c.cve0789 ++++ php-5.3.3/ext/date/php_date.c +@@ -833,6 +833,12 @@ static timelib_tzinfo *php_date_parse_tz + } + return tzi; + } ++ ++timelib_tzinfo *php_date_parse_tzfile_wrapper(char *formal_tzname, const timelib_tzdb *tzdb) ++{ ++ TSRMLS_FETCH(); ++ return php_date_parse_tzfile(formal_tzname, tzdb TSRMLS_CC); ++} + /* }}} */ + + /* {{{ Helper functions */ +@@ -1366,7 +1372,7 @@ PHPAPI signed long php_parse_date(char * + int error2; + signed long retval; + +- parsed_time = timelib_strtotime(string, strlen(string), &error, DATE_TIMEZONEDB); ++ parsed_time = timelib_strtotime(string, strlen(string), &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + if (error->error_count) { + timelib_error_container_dtor(error); + return -1; +@@ -1403,7 +1409,7 @@ PHP_FUNCTION(strtotime) + + initial_ts = emalloc(25); + snprintf(initial_ts, 24, "@%ld UTC", preset_ts); +- t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */ ++ t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); /* we ignore the error here, as this should never fail */ + timelib_update_ts(t, tzi); + now->tz_info = tzi; + now->zone_type = TIMELIB_ZONETYPE_ID; +@@ -1425,7 +1431,7 @@ PHP_FUNCTION(strtotime) + RETURN_FALSE; + } + +- t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB); ++ t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + error1 = error->error_count; + timelib_error_container_dtor(error); + timelib_fill_holes(t, now, TIMELIB_NO_CLONE); +@@ -2378,9 +2384,9 @@ static int date_initialize(php_date_obj + timelib_time_dtor(dateobj->time); + } + if (format) { +- dateobj->time = timelib_parse_from_format(format, time_str_len ? time_str : "", time_str_len ? time_str_len : 0, &err, DATE_TIMEZONEDB); ++ dateobj->time = timelib_parse_from_format(format, time_str_len ? time_str : "", time_str_len ? time_str_len : 0, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + } else { +- dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &err, DATE_TIMEZONEDB); ++ dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + } + + /* update last errors and warnings */ +@@ -2714,7 +2720,7 @@ PHP_FUNCTION(date_parse) + RETURN_FALSE; + } + +- parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB); ++ parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAM_PASSTHRU, parsed_time, error); + } + /* }}} */ +@@ -2733,7 +2739,7 @@ PHP_FUNCTION(date_parse_from_format) + RETURN_FALSE; + } + +- parsed_time = timelib_parse_from_format(format, date, date_len, &error, DATE_TIMEZONEDB); ++ parsed_time = timelib_parse_from_format(format, date, date_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAM_PASSTHRU, parsed_time, error); + } + /* }}} */ +@@ -2775,7 +2781,7 @@ PHP_FUNCTION(date_modify) + dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); + +- tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB); ++ tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + + /* update last errors and warnings */ + update_errors_warnings(err TSRMLS_CC); +@@ -3571,7 +3577,7 @@ PHP_FUNCTION(date_interval_create_from_d + + date_instantiate(date_ce_interval, return_value TSRMLS_CC); + +- time = timelib_strtotime(time_str, time_str_len, &err, DATE_TIMEZONEDB); ++ time = timelib_strtotime(time_str, time_str_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + diobj = (php_interval_obj *) zend_object_store_get_object(return_value TSRMLS_CC); + diobj->diff = timelib_rel_time_clone(&time->relative); + diobj->initialized = 1; +--- php-5.3.3/ext/date/tests/bug53502.phpt.cve0789 ++++ php-5.3.3/ext/date/tests/bug53502.phpt +@@ -0,0 +1,13 @@ ++--TEST-- ++Bug #53502 (strtotime with timezone memory leak) ++--INI-- ++date.timezone=UTC ++--FILE-- ++ ++--EXPECT-- ++Nothing, test only makes sense through valgrind.