diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c7a66c5cd48dd..04c901710092d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -74,10 +74,7 @@ jobs: - template: azure/job.yml parameters: configurationName: DEBUG_ZTS_ASAN_UBSAN - configurationParameters: >- - --enable-debug --enable-zts - CFLAGS='-fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC' - LDFLAGS='-fsanitize=undefined,address' + configurationParameters: '--enable-debug --enable-zts --enable-sanitizer=address,undefined' runTestsParameters: --asan timeoutInMinutes: 360 - template: azure/msan_job.yml @@ -90,9 +87,8 @@ jobs: parameters: configurationName: COMMUNITY configurationParameters: >- - --enable-debug --enable-zts - CFLAGS='-fsanitize=undefined,address -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC' - LDFLAGS='-fsanitize=undefined,address' + --enable-debug --enable-zts --enable-sanitizer=address + CFLAGS='-fno-sanitize-recover' - template: azure/coverage_job.yml parameters: configurationName: COVERAGE_DEBUG_ZTS diff --git a/configure.ac b/configure.ac index 8feba49fe22c0..4d5cfbe723010 100644 --- a/configure.ac +++ b/configure.ac @@ -982,6 +982,11 @@ PHP_ARG_ENABLE([memory-sanitizer],, [Enable memory sanitizer (clang only)])], [no], [no]) +PHP_ARG_ENABLE([sanitizer],, + [AS_HELP_STRING([--enable-sanitizer], + [Enable sanitizers, like --enable-sanitizer=address,undefined for ASan and UBSan, Asan and UBSan is enabled in default."])], + [no], + [no]) dnl Extension configuration. dnl ---------------------------------------------------------------------------- @@ -1374,8 +1379,38 @@ fi dnl Enable -fsanitize=memory late, because interceptors may break linking detection. if test "$PHP_MEMORY_SANITIZER" = "yes"; then - CFLAGS="$CFLAGS -fsanitize=memory -fsanitize-memory-track-origins" - CXXFLAGS="$CXXFLAGS -fsanitize=memory -fsanitize-memory-track-origins" + AX_CHECK_COMPILE_FLAG([-fsanitize=memory -fsanitize-memory-track-origins], [ + CFLAGS="$CFLAGS -fsanitize=memory -fsanitize-memory-track-origins" + CXXFLAGS="$CXXFLAGS -fsanitize=memory -fsanitize-memory-track-origins" + ], [AC_MSG_ERROR([MemorySanitizer is not available])]) +fi + +dnl --enable-sanitizer=[[yes,]a,b,c,...] +if test "$PHP_SANITIZER" != "no"; then + sanitizers="$PHP_SANITIZER" + if test "$PHP_SANITIZER" = "yes"; then + dnl same as windows' default + sanitizers="address,undefined" + fi + sanitizer_cflags="-fsanitize=" + _IFS=$IFS + IFS=',' + for sanitizer in "$sanitizers"; do + if test x"$sanitizer" = x"yes" || test x"$sanitizer" = x"" ; then + continue + fi + if test x"$sanitizer" = x"memory" || test x"$memory-track-origins" = x"" ; then + if test "$PHP_MEMORY_SANITIZER" = "yes"; then + continue + fi + fi + sanitizer_cflags=",${sanitizer}" + done + IFS=$_IFS + AX_CHECK_COMPILE_FLAG([-fsanitize=${sanitizer}], [ + CFLAGS="$CFLAGS -fsanitize=${sanitizer}" + CXXFLAGS="$CXXFLAGS -fsanitize=${sanitizer}" + ], [AC_MSG_ERROR([Sanitizer "${sanitizer}" is not available])]) fi dnl diff --git a/win32/build/config.w32 b/win32/build/config.w32 index d8d5671b10c7a..9116b935d52f1 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -62,6 +62,8 @@ DEFINE("BASE_INCLUDES", "/I . /I main /I Zend /I TSRM /I ext "); toolset_setup_common_cflags(); +toolset_setup_sanitizer_cflags(); + if (VS_TOOLSET) { ARG_WITH('mp', 'Tell Visual Studio use up to [n,auto,disable] processes for compilation', 'auto'); var PHP_MP_DISABLED = true; diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 38a5fb75aa330..ba475e9d9dd94 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -1238,10 +1238,8 @@ function SAPI(sapiname, file_list, makefiletarget, cflags, obj_dir) manifest = "-" + CMD_MOD2 + "$(_VC_MANIFEST_EMBED_EXE)"; } - if (PHP_SANITIZER == "yes") { - if (CLANG_TOOLSET) { - add_asan_opts("CFLAGS_" + SAPI, "LIBS_" + SAPI, (is_lib ? "ARFLAGS_" : "LDFLAGS_") + SAPI); - } + if (PHP_SANITIZER != "no" && (VS_TOOLSET || CLANG_TOOLSET)) { + add_sanitizer_libs("LIBS_" + SAPI, (is_lib ? "ARFLAGS_" : "LDFLAGS_") + SAPI); } if(is_pgo_desired(sapiname) && (PHP_PGI == "yes" || PHP_PGO != "no")) { @@ -2593,10 +2591,8 @@ function generate_makefile() } } } - if (PHP_SANITIZER == "yes") { - if (CLANG_TOOLSET) { - extra_path = extra_path + ";" + get_clang_lib_dir() + "\\windows"; - } + if (PHP_SANITIZER != "no" && CLANG_TOOLSET) { + extra_path = extra_path + ";" + get_clang_lib_dir() + "\\windows"; } MF.WriteLine("set-tmp-env:"); MF.WriteLine(" " + CMD_MOD2 + "set PATH=" + extra_path + ";$(PATH)"); @@ -3305,6 +3301,43 @@ function toolset_setup_common_cflags() } } +function toolset_setup_sanitizer_cflags() +{ + if (PHP_SANITIZER == "no" || !(VS_TOOLSET || CLANG_TOOLSET)) { + return false; + } + MESSAGE("Enabling Sanitizers"); + if (VS_TOOLSET) { + if(!search_paths('vswhere.exe', null, 'PATH')){ + ERROR("Failed to find vswhere.exe"); + } + var ver = execute('vswhere.exe -nologo -requires Microsoft.VisualStudio.Component.VC.ASAN -version [16.9,) -property installationVersion -utf8'); + if(!ver.match(/\d+\.\d+\.\d+\.\d+/)){ + ERROR('Sanitizers is not supported with your VS installation (VS version is too old or ASan workload not installed)'); + } + } else { + if (!COMPILER_NAME_LONG.match(/clang version ([\d\.]+) \((.*)\)/)) { + ERROR("Failed to determine clang lib path"); + } + } + var sanitizers = PHP_SANITIZER.replace(/^yes,/,'').split(','); + var sanitizer_cflags; + if (VS_TOOLSET) { + sanitizer_cflags = "/fsanitize="; + if (PHP_SANITIZER == "yes") { + sanitizers = [ "address" ]; // MSVC not yet implemented ub at this time + } + } else { + sanitizer_cflags = "-fsanitize="; + if (PHP_SANITIZER == "yes") { + sanitizers = [ "address", "undefined" ]; + } + } + sanitizer_cflags = sanitizer_cflags + sanitizers.join(','); + ADD_FLAG("CFLAGS", sanitizer_cflags); + +} + function toolset_setup_intrinsic_cflags() { var default_enabled = "sse2"; @@ -3435,7 +3468,7 @@ function toolset_setup_build_mode() ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf"); } ADD_FLAG("CFLAGS", "/LD /MD"); - if (PHP_SANITIZER == "yes" && CLANG_TOOLSET) { + if (PHP_SANITIZER != "no" && (VS_TOOLSET || CLANG_TOOLSET)) { ADD_FLAG("CFLAGS", "/Od /D NDebug /D NDEBUG /D ZEND_WIN32_NEVER_INLINE /D ZEND_DEBUG=0"); } else { // Equivalent to Release_TSInline build -> best optimization @@ -3703,19 +3736,11 @@ function get_clang_lib_dir() return ret; } -function add_asan_opts(cflags_name, libs_name, ldflags_name) +function add_sanitizer_libs(libs_name, ldflags_name) { - - var ver = null; - - if (COMPILER_NAME_LONG.match(/clang version ([\d\.]+) \((.*)\)/)) { - ver = RegExp.$1; - } else { - ERROR("Failed to determine clang lib path"); - } - - if (!!cflags_name) { - ADD_FLAG(cflags_name, "-fsanitize=address,undefined"); + if(VS_TOOLSET){ + // VS 2019 16.9 release donot need this + return ; } if (!!libs_name) { if (X64) {