-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix integer overflow UB in timelib #17060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There are edge cases where computations can cause an integer overflow, which is undefined behaviour. Lately, some fuzzers seem to be hitting these quite frequently. While this behaviour is undefined, it doesn't actually matter in practice, the worst effect is having a wrong computation result, but no sane person would do computations on e.g. the year pow(2,63). Still, undefined behaviour is bad. Make the wrapping behaviour defined by using -fwrapv when possible. The scope of this is limited to timelib and doesn't affect php_date.c. The reason for this is that this may in theory prevent some optimizations and it also seems bad to affect code that lives so close to the PHP-native edge. I tested all issues. This fixes all but 2 issues, the remaining 2 issues are in php_date.c. Fixes phpGH-13881. Fixes phpGH-14075. Fixes phpGH-15150. Fixes phpGH-16034. Fixes phpGH-16035. Fixes phpGH-16048. Fixes phpGH-16050. Fixes phpGH-16051. Fixes phpGH-16052. Fixes phpGH-16775. Fixes phpGH-16864. Fixes phpGH-16865. Fixes phpGH-16975. Fixes phpGH-17025. Fixes phpGH-17059.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know about the build system changes, but adding this compiler flags makes sense to me.
Waiting for somebody else to verify the autoconf part, but adding |
Thank you very much! A great pragmatic solution. Maybe add ext/date/config.w32 | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ext/date/config.w32 b/ext/date/config.w32
index b053e27aae..3dad8d438c 100644
--- a/ext/date/config.w32
+++ b/ext/date/config.w32
@@ -5,6 +5,9 @@ PHP_DATE = "yes";
ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");
ADD_FLAG('CFLAGS_DATE', "/wd4244");
+if (CLANG_TOOLSET) {
+ ADD_FLAG('CFLAGS_BD_EXT_DATE_LIB', "-fwrapv");
+}
var tl_config = FSO.CreateTextFile("ext/date/lib/timelib_config.h", true);
tl_config.WriteLine("#include \"config.w32.h\"");
just in case someone fuzzes on Windows with Clang (MSVC doesn't support UBSan anyway). This is a hack, though, since |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Out of interest, which are the two php_date.c
ones still failing?
ext/date/config0.m4
Outdated
PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1" | ||
PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1" | ||
PHP_TIMELIB_CFLAGS="$PHP_DATE_CFLAGS" | ||
PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure this is fine, but of course -DZEND_ENABLE_STATIC_TSRMC_CACHE=1
is meaningless in the PHP_TIMELIB_CFLAGS
definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you are right, I'll move that one too.
Furthermore, I'll apply cmb's suggestion of applying fwrapv
to Clang on Windows too.
Co-authored-by: "Christoph M. Becker" <cmbecker69@gmx.de>
There are edge cases where computations can cause an integer overflow, which is undefined behaviour. Lately, some fuzzers seem to be hitting these quite frequently. While this behaviour is undefined, it doesn't actually matter in practice, the worst effect is having a wrong computation result, but no sane person would do computations on e.g. the year pow(2,63).
Still, undefined behaviour is bad.
Make the wrapping behaviour defined by using -fwrapv when possible. The scope of this is limited to timelib and doesn't affect php_date.c.
The reason for this is that this may in theory prevent some optimizations and it also seems bad to affect code that lives so close to the PHP-native edge.
I tested all issues.
This fixes all but 2 issues, the remaining 2 issues are in php_date.c.
Fixes GH-13881.
Fixes GH-14075.
Fixes GH-15150.
Fixes GH-16034.
Fixes GH-16035.
Fixes GH-16048.
Fixes GH-16050.
Fixes GH-16051.
Fixes GH-16052.
Fixes GH-16775.
Fixes GH-16864.
Fixes GH-16865.
Fixes GH-16975.
Fixes GH-17025.
Fixes GH-17059.
cc @derickr @iluuu1994 @Girgias @petk