From b7841267dc643c88feb9f2ef55cfab3ae5a8e9ba Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Wed, 5 Feb 2020 16:16:39 +0100 Subject: [PATCH 1/4] vendor github.com/intel/safestringlib --- .gitattributes | 1 + ci/editorconfig.sh | 1 + vendor/README.md | 8 + vendor/safestringlib/.gitattributes | 17 + vendor/safestringlib/.gitignore | 220 +++++ vendor/safestringlib/CMakeLists.txt | 186 ++++ vendor/safestringlib/CODE_OF_CONDUCT.md | 46 + vendor/safestringlib/LICENSE | 47 + vendor/safestringlib/LICENSE©ING.txt | 50 + vendor/safestringlib/README.md | 86 ++ vendor/safestringlib/include/safe_lib.h | 68 ++ vendor/safestringlib/include/safe_lib_errno.h | 100 ++ .../safestringlib/include/safe_lib_errno.h.in | 91 ++ vendor/safestringlib/include/safe_mem_lib.h | 122 +++ vendor/safestringlib/include/safe_str_lib.h | 293 ++++++ vendor/safestringlib/include/safe_types.h | 68 ++ vendor/safestringlib/include/safe_types.h.in | 59 ++ vendor/safestringlib/include/snprintf_s.h | 48 + vendor/safestringlib/makefile | 69 ++ .../safestringlib/safeclib/abort_handler_s.c | 74 ++ .../safestringlib/safeclib/ignore_handler_s.c | 72 ++ .../safeclib/mem_primitives_lib.c | 853 ++++++++++++++++++ .../safeclib/mem_primitives_lib.h | 74 ++ vendor/safestringlib/safeclib/memcmp16_s.c | 173 ++++ vendor/safestringlib/safeclib/memcmp32_s.c | 167 ++++ vendor/safestringlib/safeclib/memcmp_s.c | 174 ++++ vendor/safestringlib/safeclib/memcpy16_s.c | 151 ++++ vendor/safestringlib/safeclib/memcpy32_s.c | 150 +++ vendor/safestringlib/safeclib/memcpy_s.c | 163 ++++ vendor/safestringlib/safeclib/memmove16_s.c | 151 ++++ vendor/safestringlib/safeclib/memmove32_s.c | 150 +++ vendor/safestringlib/safeclib/memmove_s.c | 149 +++ vendor/safestringlib/safeclib/memset16_s.c | 105 +++ vendor/safestringlib/safeclib/memset32_s.c | 105 +++ vendor/safestringlib/safeclib/memset_s.c | 105 +++ vendor/safestringlib/safeclib/memzero16_s.c | 107 +++ vendor/safestringlib/safeclib/memzero32_s.c | 108 +++ vendor/safestringlib/safeclib/memzero_s.c | 107 +++ .../safeclib/safe_mem_constraint.c | 142 +++ .../safeclib/safe_mem_constraint.h | 46 + .../safeclib/safe_str_constraint.c | 146 +++ .../safeclib/safe_str_constraint.h | 78 ++ .../safestringlib/safeclib/safeclib_private.h | 93 ++ .../safestringlib/safeclib/snprintf_support.c | 329 +++++++ vendor/safestringlib/safeclib/stpcpy_s.c | 234 +++++ vendor/safestringlib/safeclib/stpncpy_s.c | 282 ++++++ vendor/safestringlib/safeclib/strcasecmp_s.c | 144 +++ vendor/safestringlib/safeclib/strcasestr_s.c | 180 ++++ vendor/safestringlib/safeclib/strcat_s.c | 232 +++++ vendor/safestringlib/safeclib/strcmp_s.c | 140 +++ vendor/safestringlib/safeclib/strcmpfld_s.c | 143 +++ vendor/safestringlib/safeclib/strcpy_s.c | 198 ++++ vendor/safestringlib/safeclib/strcpyfld_s.c | 200 ++++ vendor/safestringlib/safeclib/strcpyfldin_s.c | 203 +++++ .../safestringlib/safeclib/strcpyfldout_s.c | 205 +++++ vendor/safestringlib/safeclib/strcspn_s.c | 165 ++++ .../safestringlib/safeclib/strfirstchar_s.c | 128 +++ .../safestringlib/safeclib/strfirstdiff_s.c | 143 +++ .../safestringlib/safeclib/strfirstsame_s.c | 146 +++ .../safeclib/strisalphanumeric_s.c | 120 +++ vendor/safestringlib/safeclib/strisascii_s.c | 111 +++ vendor/safestringlib/safeclib/strisdigit_s.c | 113 +++ vendor/safestringlib/safeclib/strishex_s.c | 119 +++ .../safestringlib/safeclib/strislowercase_s.c | 119 +++ .../safestringlib/safeclib/strismixedcase_s.c | 120 +++ .../safestringlib/safeclib/strispassword_s.c | 169 ++++ .../safestringlib/safeclib/strisuppercase_s.c | 118 +++ vendor/safestringlib/safeclib/strlastchar_s.c | 132 +++ vendor/safestringlib/safeclib/strlastdiff_s.c | 152 ++++ vendor/safestringlib/safeclib/strlastsame_s.c | 153 ++++ vendor/safestringlib/safeclib/strljustify_s.c | 160 ++++ vendor/safestringlib/safeclib/strncat_s.c | 265 ++++++ vendor/safestringlib/safeclib/strncpy_s.c | 238 +++++ vendor/safestringlib/safeclib/strnlen_s.c | 112 +++ .../safestringlib/safeclib/strnterminate_s.c | 113 +++ vendor/safestringlib/safeclib/strpbrk_s.c | 163 ++++ vendor/safestringlib/safeclib/strprefix_s.c | 128 +++ vendor/safestringlib/safeclib/strremovews_s.c | 164 ++++ vendor/safestringlib/safeclib/strspn_s.c | 170 ++++ vendor/safestringlib/safeclib/strstr_s.c | 179 ++++ vendor/safestringlib/safeclib/strtok_s.c | 325 +++++++ .../safestringlib/safeclib/strtolowercase_s.c | 115 +++ .../safestringlib/safeclib/strtouppercase_s.c | 115 +++ vendor/safestringlib/safeclib/strzero_s.c | 103 +++ vendor/safestringlib/safeclib/wcpcpy_s.c | 219 +++++ vendor/safestringlib/safeclib/wcscat_s.c | 226 +++++ vendor/safestringlib/safeclib/wcscpy_s.c | 207 +++++ vendor/safestringlib/safeclib/wcsncat_s.c | 269 ++++++ vendor/safestringlib/safeclib/wcsncpy_s.c | 241 +++++ vendor/safestringlib/safeclib/wcsnlen_s.c | 113 +++ vendor/safestringlib/safeclib/wmemcmp_s.c | 169 ++++ vendor/safestringlib/safeclib/wmemcpy_s.c | 158 ++++ vendor/safestringlib/safeclib/wmemmove_s.c | 150 +++ vendor/safestringlib/safeclib/wmemset_s.c | 105 +++ 94 files changed, 13928 insertions(+) create mode 100644 vendor/README.md create mode 100644 vendor/safestringlib/.gitattributes create mode 100644 vendor/safestringlib/.gitignore create mode 100644 vendor/safestringlib/CMakeLists.txt create mode 100644 vendor/safestringlib/CODE_OF_CONDUCT.md create mode 100644 vendor/safestringlib/LICENSE create mode 100644 vendor/safestringlib/LICENSE©ING.txt create mode 100644 vendor/safestringlib/README.md create mode 100644 vendor/safestringlib/include/safe_lib.h create mode 100644 vendor/safestringlib/include/safe_lib_errno.h create mode 100644 vendor/safestringlib/include/safe_lib_errno.h.in create mode 100644 vendor/safestringlib/include/safe_mem_lib.h create mode 100644 vendor/safestringlib/include/safe_str_lib.h create mode 100644 vendor/safestringlib/include/safe_types.h create mode 100644 vendor/safestringlib/include/safe_types.h.in create mode 100644 vendor/safestringlib/include/snprintf_s.h create mode 100644 vendor/safestringlib/makefile create mode 100644 vendor/safestringlib/safeclib/abort_handler_s.c create mode 100644 vendor/safestringlib/safeclib/ignore_handler_s.c create mode 100644 vendor/safestringlib/safeclib/mem_primitives_lib.c create mode 100644 vendor/safestringlib/safeclib/mem_primitives_lib.h create mode 100644 vendor/safestringlib/safeclib/memcmp16_s.c create mode 100644 vendor/safestringlib/safeclib/memcmp32_s.c create mode 100644 vendor/safestringlib/safeclib/memcmp_s.c create mode 100644 vendor/safestringlib/safeclib/memcpy16_s.c create mode 100644 vendor/safestringlib/safeclib/memcpy32_s.c create mode 100644 vendor/safestringlib/safeclib/memcpy_s.c create mode 100644 vendor/safestringlib/safeclib/memmove16_s.c create mode 100644 vendor/safestringlib/safeclib/memmove32_s.c create mode 100644 vendor/safestringlib/safeclib/memmove_s.c create mode 100644 vendor/safestringlib/safeclib/memset16_s.c create mode 100644 vendor/safestringlib/safeclib/memset32_s.c create mode 100644 vendor/safestringlib/safeclib/memset_s.c create mode 100644 vendor/safestringlib/safeclib/memzero16_s.c create mode 100644 vendor/safestringlib/safeclib/memzero32_s.c create mode 100644 vendor/safestringlib/safeclib/memzero_s.c create mode 100644 vendor/safestringlib/safeclib/safe_mem_constraint.c create mode 100644 vendor/safestringlib/safeclib/safe_mem_constraint.h create mode 100644 vendor/safestringlib/safeclib/safe_str_constraint.c create mode 100644 vendor/safestringlib/safeclib/safe_str_constraint.h create mode 100644 vendor/safestringlib/safeclib/safeclib_private.h create mode 100644 vendor/safestringlib/safeclib/snprintf_support.c create mode 100644 vendor/safestringlib/safeclib/stpcpy_s.c create mode 100644 vendor/safestringlib/safeclib/stpncpy_s.c create mode 100644 vendor/safestringlib/safeclib/strcasecmp_s.c create mode 100644 vendor/safestringlib/safeclib/strcasestr_s.c create mode 100644 vendor/safestringlib/safeclib/strcat_s.c create mode 100644 vendor/safestringlib/safeclib/strcmp_s.c create mode 100644 vendor/safestringlib/safeclib/strcmpfld_s.c create mode 100644 vendor/safestringlib/safeclib/strcpy_s.c create mode 100644 vendor/safestringlib/safeclib/strcpyfld_s.c create mode 100644 vendor/safestringlib/safeclib/strcpyfldin_s.c create mode 100644 vendor/safestringlib/safeclib/strcpyfldout_s.c create mode 100644 vendor/safestringlib/safeclib/strcspn_s.c create mode 100644 vendor/safestringlib/safeclib/strfirstchar_s.c create mode 100644 vendor/safestringlib/safeclib/strfirstdiff_s.c create mode 100644 vendor/safestringlib/safeclib/strfirstsame_s.c create mode 100644 vendor/safestringlib/safeclib/strisalphanumeric_s.c create mode 100644 vendor/safestringlib/safeclib/strisascii_s.c create mode 100644 vendor/safestringlib/safeclib/strisdigit_s.c create mode 100644 vendor/safestringlib/safeclib/strishex_s.c create mode 100644 vendor/safestringlib/safeclib/strislowercase_s.c create mode 100644 vendor/safestringlib/safeclib/strismixedcase_s.c create mode 100644 vendor/safestringlib/safeclib/strispassword_s.c create mode 100644 vendor/safestringlib/safeclib/strisuppercase_s.c create mode 100644 vendor/safestringlib/safeclib/strlastchar_s.c create mode 100644 vendor/safestringlib/safeclib/strlastdiff_s.c create mode 100644 vendor/safestringlib/safeclib/strlastsame_s.c create mode 100644 vendor/safestringlib/safeclib/strljustify_s.c create mode 100644 vendor/safestringlib/safeclib/strncat_s.c create mode 100644 vendor/safestringlib/safeclib/strncpy_s.c create mode 100644 vendor/safestringlib/safeclib/strnlen_s.c create mode 100644 vendor/safestringlib/safeclib/strnterminate_s.c create mode 100644 vendor/safestringlib/safeclib/strpbrk_s.c create mode 100644 vendor/safestringlib/safeclib/strprefix_s.c create mode 100644 vendor/safestringlib/safeclib/strremovews_s.c create mode 100644 vendor/safestringlib/safeclib/strspn_s.c create mode 100644 vendor/safestringlib/safeclib/strstr_s.c create mode 100644 vendor/safestringlib/safeclib/strtok_s.c create mode 100644 vendor/safestringlib/safeclib/strtolowercase_s.c create mode 100644 vendor/safestringlib/safeclib/strtouppercase_s.c create mode 100644 vendor/safestringlib/safeclib/strzero_s.c create mode 100644 vendor/safestringlib/safeclib/wcpcpy_s.c create mode 100644 vendor/safestringlib/safeclib/wcscat_s.c create mode 100644 vendor/safestringlib/safeclib/wcscpy_s.c create mode 100644 vendor/safestringlib/safeclib/wcsncat_s.c create mode 100644 vendor/safestringlib/safeclib/wcsncpy_s.c create mode 100644 vendor/safestringlib/safeclib/wcsnlen_s.c create mode 100644 vendor/safestringlib/safeclib/wmemcmp_s.c create mode 100644 vendor/safestringlib/safeclib/wmemcpy_s.c create mode 100644 vendor/safestringlib/safeclib/wmemmove_s.c create mode 100644 vendor/safestringlib/safeclib/wmemset_s.c diff --git a/.gitattributes b/.gitattributes index 34b1a752a..264e4fe69 100644 --- a/.gitattributes +++ b/.gitattributes @@ -30,6 +30,7 @@ src/backend/distributed/deparser/ruleutils_10.c -citus-style src/backend/distributed/deparser/ruleutils_11.c -citus-style src/backend/distributed/deparser/ruleutils_12.c -citus-style src/include/distributed/citus_nodes.h -citus-style +/vendor/** -citus-style # Hide diff on github by default for copied udfs src/backend/distributed/sql/udfs/*/[123456789]*.sql linguist-generated=true diff --git a/ci/editorconfig.sh b/ci/editorconfig.sh index 8a941ae91..661aec1a7 100755 --- a/ci/editorconfig.sh +++ b/ci/editorconfig.sh @@ -4,6 +4,7 @@ for f in $(git ls-tree -r HEAD --name-only); do if [ "$f" = "${f%.out}" ] && [ "$f" = "${f%.data}" ] && [ "$f" = "${f%.png}" ] && + [ "$(echo "$f" | cut -d / -f1)" != "vendor" ] && [ "$(dirname "$f")" != "src/test/regress/output" ] then # Trim trailing whitespace diff --git a/vendor/README.md b/vendor/README.md new file mode 100644 index 000000000..1e22d01b1 --- /dev/null +++ b/vendor/README.md @@ -0,0 +1,8 @@ +# Updating vendored dependencies + +```bash +rm -rf safestringlib +git clone https://github.com/intel/safestringlib +rm -rf safestringlib/{.git,unittests} +git add safestringlib/ +``` diff --git a/vendor/safestringlib/.gitattributes b/vendor/safestringlib/.gitattributes new file mode 100644 index 000000000..bdb0cabc8 --- /dev/null +++ b/vendor/safestringlib/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/vendor/safestringlib/.gitignore b/vendor/safestringlib/.gitignore new file mode 100644 index 000000000..60bfe41fb --- /dev/null +++ b/vendor/safestringlib/.gitignore @@ -0,0 +1,220 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + +################# +## GVIM & VI +################# +*~ + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.publishproj + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[cod] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg diff --git a/vendor/safestringlib/CMakeLists.txt b/vendor/safestringlib/CMakeLists.txt new file mode 100644 index 000000000..213d5a8f5 --- /dev/null +++ b/vendor/safestringlib/CMakeLists.txt @@ -0,0 +1,186 @@ +cmake_minimum_required(VERSION 3.1) +project(safestring) + +option(BUILD_UNITTESTS "Build also project unit-tests" OFF) + +if (NOT DEFINED BUILD_OPT_DEFAULT) + set (BUILD_OPT_DEFAULT YES CACHE PATH "Build option default") +endif (NOT DEFINED BUILD_OPT_DEFAULT) + +option(BUILD_MEMCMP "Build memcmp* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_MEMCPY "Build memcpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_MEMMOVE "Build memmove* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_MEMSET "Build memset* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_MEMZERO "Build memzero* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STPCPY "Build stpcpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STPNCPY "Build stpncpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCASECMP "Build strcasecmp* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCASESTR "Build strcasestr* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCAT "Build strcat* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCMPFLD "Build strcmpfld* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCMP "Build strcmp* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCPYFLDIN "Build strcpyfldin* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCPYFLDOUT "Build strcpyfldout* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCPYFLD "Build strcpyfld* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCPY "Build strcpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRCSPN "Build strcspn* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRFIRSTCHAR "Build strfirstchar* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRFIRSTDIFF "Build strfirstdiff* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRFIRSTSAME "Build strfirstsame* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISALPHANUMERIC "Build strisalphanumeric* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISASCII "Build strisascii* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISDIGIT "Build strisdigit* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISHEX "Build strishex* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISLOWERCASE "Build strislowercase* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISMIXEDCASE "Build strismixedcase* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISPASSWORD "Build strispassword* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRISUPPERCASE "Build strisuppercase* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRLASTCHAR "Build strlastchar* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRLASTDIFF "Build strlastdiff* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRLASTSAME "Build strlastsame* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRLJUSTIFY "Build strljustify* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRNCAT "Build strncat* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRNCPY "Build strncpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRNLEN "Build strnlen* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRNTERMINATE "Build strnterminate* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRPBRK "Build strpbrk* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRPREFIX "Build strprefix* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRREMOVEWS "Build strremovews* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRSPN "Build strspn* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRSTR "Build strstr* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRTOK "Build strtok* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRTOLOWERCASE "Build strtolowercase* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRTOUPPERCASE "Build strtouppercase* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_STRZERO "Build strzero* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WCPCPY "Build wcpcpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WCSCAT "Build wcscat* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WCSCPY "Build wcscpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WCSNCAT "Build wcsncat* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WCSNCPY "Build wcsncpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WCSNLEN "Build wcsnlen* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WMEMCMP "Build wmemcmp* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WMEMCPY "Build wmemcpy* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WMEMMOVE "Build wmemmove* functions" ${BUILD_OPT_DEFAULT}) +option(BUILD_WMEMSET "Build wmemset* functions" ${BUILD_OPT_DEFAULT}) + +set(SOURCES + safeclib/abort_handler_s.c + safeclib/ignore_handler_s.c + $<$:safeclib/memcmp16_s.c> + $<$:safeclib/memcmp32_s.c> + $<$:safeclib/memcmp_s.c> + $<$:safeclib/memcpy16_s.c> + $<$:safeclib/memcpy32_s.c> + $<$:safeclib/memcpy_s.c> + $<$:safeclib/memmove16_s.c> + $<$:safeclib/memmove32_s.c> + $<$:safeclib/memmove_s.c> + safeclib/mem_primitives_lib.c + $<$:safeclib/memset16_s.c> + $<$:safeclib/memset32_s.c> + $<$:safeclib/memset_s.c> + $<$:safeclib/memzero16_s.c> + $<$:safeclib/memzero32_s.c> + $<$:safeclib/memzero_s.c> + safeclib/safe_mem_constraint.c + safeclib/safe_str_constraint.c + safeclib/snprintf_support.c + $<$:safeclib/stpcpy_s.c> + $<$:safeclib/stpncpy_s.c> + $<$:safeclib/strcasecmp_s.c> + $<$:safeclib/strcasestr_s.c> + $<$:safeclib/strcat_s.c> + $<$:safeclib/strcmpfld_s.c> + $<$:safeclib/strcmp_s.c> + $<$:safeclib/strcpyfldin_s.c> + $<$:safeclib/strcpyfldout_s.c> + $<$:safeclib/strcpyfld_s.c> + $<$:safeclib/strcpy_s.c> + $<$:safeclib/strcspn_s.c> + $<$:safeclib/strfirstchar_s.c> + $<$:safeclib/strfirstdiff_s.c> + $<$:safeclib/strfirstsame_s.c> + $<$:safeclib/strisalphanumeric_s.c> + $<$:safeclib/strisascii_s.c> + $<$:safeclib/strisdigit_s.c> + $<$:safeclib/strishex_s.c> + $<$:safeclib/strislowercase_s.c> + $<$:safeclib/strismixedcase_s.c> + $<$:safeclib/strispassword_s.c> + $<$:safeclib/strisuppercase_s.c> + $<$:safeclib/strlastchar_s.c> + $<$:safeclib/strlastdiff_s.c> + $<$:safeclib/strlastsame_s.c> + $<$:safeclib/strljustify_s.c> + $<$:safeclib/strncat_s.c> + $<$:safeclib/strncpy_s.c> + $<$:safeclib/strnlen_s.c> + $<$:safeclib/strnterminate_s.c> + $<$:safeclib/strpbrk_s.c> + $<$:safeclib/strprefix_s.c> + $<$:safeclib/strremovews_s.c> + $<$:safeclib/strspn_s.c> + $<$:safeclib/strstr_s.c> + $<$:safeclib/strtok_s.c> + $<$:safeclib/strtolowercase_s.c> + $<$:safeclib/strtouppercase_s.c> + $<$:safeclib/strzero_s.c> + $<$:safeclib/wcpcpy_s.c> + $<$:safeclib/wcscat_s.c> + $<$:safeclib/wcscpy_s.c> + $<$:safeclib/wcsncat_s.c> + $<$:safeclib/wcsncpy_s.c> + $<$:safeclib/wcsnlen_s.c> + $<$:safeclib/wmemcmp_s.c> + $<$:safeclib/wmemcpy_s.c> + $<$:safeclib/wmemmove_s.c> + $<$:safeclib/wmemset_s.c> + ) + +include_directories(include) + +add_library(${PROJECT_NAME}_objlib OBJECT ${SOURCES}) +set_target_properties(${PROJECT_NAME}_objlib + PROPERTIES POSITION_INDEPENDENT_CODE ON) + +target_compile_definitions(${PROJECT_NAME}_objlib PRIVATE -DSTDC_HEADERS) + +target_compile_options(${PROJECT_NAME}_objlib + PRIVATE -Wno-unknown-pragmas -Wno-unused-parameter) +if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 7) + target_compile_options(${PROJECT_NAME}_objlib + PRIVATE -Wno-implicit-fallthrough) +endif() +target_compile_options(${PROJECT_NAME}_objlib + PRIVATE -Wall -Wextra -Wsign-compare -Wformat-security) +target_compile_options(${PROJECT_NAME}_objlib + PRIVATE -Wstack-protector -Winit-self) +target_compile_options(${PROJECT_NAME}_objlib + PRIVATE -D_FORTIFY_SOURCE=2 -O2) +target_compile_options(${PROJECT_NAME}_objlib + PRIVATE -fstack-protector-all) +target_compile_options(${PROJECT_NAME}_objlib + PRIVATE --param ssp-buffer-size=4 -ftrapv) +target_compile_options(${PROJECT_NAME}_objlib PRIVATE -fPIE -fPIC) + +if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 6) + target_compile_options(${PROJECT_NAME}_objlib PRIVATE -mmitigate-rop) +endif() +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack -z relro -z now") + +option(BUILD_ERROR_ON_WARNING "Fail compilation on warning" OFF) + +if(BUILD_ERROR_ON_WARNING) + target_compile_options(${PROJECT_NAME}_objlib PRIVATE -Werror) +endif() + +target_compile_options(${PROJECT_NAME}_objlib PRIVATE $<$:-s>) + +add_library(${PROJECT_NAME}_shared SHARED $) +add_library(${PROJECT_NAME}_static STATIC $) +target_include_directories(${PROJECT_NAME}_shared PUBLIC include) +target_include_directories(${PROJECT_NAME}_static PUBLIC include) + +if(BUILD_UNITTESTS) + add_subdirectory(unittests) +endif() diff --git a/vendor/safestringlib/CODE_OF_CONDUCT.md b/vendor/safestringlib/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..8368286b4 --- /dev/null +++ b/vendor/safestringlib/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at webmaster@linux.intel.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/safestringlib/LICENSE b/vendor/safestringlib/LICENSE new file mode 100644 index 000000000..fa365052e --- /dev/null +++ b/vendor/safestringlib/LICENSE @@ -0,0 +1,47 @@ +MIT License + +Copyright (c) 2014-2018 Intel Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +================================================================================ + +Copyright (C) 2012, 2013 Cisco Systems +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/safestringlib/LICENSE©ING.txt b/vendor/safestringlib/LICENSE©ING.txt new file mode 100644 index 000000000..8e8477845 --- /dev/null +++ b/vendor/safestringlib/LICENSE©ING.txt @@ -0,0 +1,50 @@ +Safe C Library + + Copyright (c) 2014-2016, Intel Corporation. All rights reserved. + + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + +================================================================================ + +Copyright (C) 2012, 2013 Cisco Systems +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/safestringlib/README.md b/vendor/safestringlib/README.md new file mode 100644 index 000000000..0b31e1c77 --- /dev/null +++ b/vendor/safestringlib/README.md @@ -0,0 +1,86 @@ +# safestringlib +The Secure Development Lifecycle (SDL) recommends banning certain C Library functions because they directly contribute +to security vulnerabilities such as buffer overflows. However routines for the manipulation of strings and memory buffers +are common in software and firmware, and are essential to accomplish certain programming tasks. Safer replacements for +these functions that avoid or prevent serious security vulnerabilities (e.g. buffer overflows, string format attacks, +conversion overflows/underflows, etc.) are available in the SafeString Library. + +This library includes routines for safe string operations (like strcpy) and memory routines (like memcpy) that are +recommended for Linux/Android operating systems, and will also work for Windows. This library is especially useful for +cross-platform situations where one library for these routines is preferred. + +The Safe String Library is based on the Safe C Library by Cisco, and includes replacement C Library functions for the SDL +banned functions, as well as a number of additional useful routines that are also susceptible to buffer overflows. This +library continues to be made available under the MIT Open Source License. + +Cisco's Safe C Library was extended by Intel's Security Center of Excellence (SeCoE) to add additional routines, and +include additional unit tests. + +LIST OF PRIMARY FUNCTIONS: +----------------------------- +* memcmp_s() +* memcpy_s() +* memmove_s() +* memset_s() +* memzero_s() + +* stpcpy_s() +* stpncpy_s() +* strcat_s() +* strcpy_s() +* strcspn_s() +* strncat_s() +* strncpy_s() +* strnlen_s() +* strpbrk_s() +* strspn_s() +* strstr_s() +* strtok_s() + +* wcpcpy_s() +* wcscat_s() +* wcscpy_s() +* wcsncat_s() +* wcsnlen_s() +* wmemcmp_s() +* wmemcpy_s() +* wmemmove_s() +* wmemset_s() + + +LIST OF ADDITIONAL STRING ROUTINES: +------------------------------------ +* strcasecmp_s() +* strcasestr_s() +* strcmp_s() +* strcmpfld_s() +* strcpyfld_s() +* strcpyfldin_s() +* strcpyfldout_s() +* strfirstchar_s() +* strfirstdiff_s() +* strfirstsmae_s() +* strisalphanumeric_s() +* strisascii_s() +* strisdigit_s() +* strishes_s() +* strislowercase_s() +* strismixedcase_s() +* strispassword_s() +* strisuppercase_s() +* strlastchar_s() +* strlastdiff_s() +* strlastsame_s() +* strljustify_s() +* strnterminate_s() +* strprefix_s() +* stremovews_s() +* strtolowercase_s() +* strtouppercase_s() +* strzero_s() + + +PLANNED ENHANCEMENTS: +---------------------- +- Add full sprintf_s() support +- Add full sscanf_s() support diff --git a/vendor/safestringlib/include/safe_lib.h b/vendor/safestringlib/include/safe_lib.h new file mode 100644 index 000000000..ba41b2847 --- /dev/null +++ b/vendor/safestringlib/include/safe_lib.h @@ -0,0 +1,68 @@ +/*------------------------------------------------------------------ + * safe_lib.h -- Safe C Library + * + * October 2008, Bo Berry + * Modified 2012, Jonathan Toppins + * + * Copyright (c) 2008-2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_LIB_H__ +#define __SAFE_LIB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "safe_types.h" +#include "safe_lib_errno.h" + +/* C11 appendix K types - specific for bounds checking */ +typedef size_t rsize_t; + +/* + * We depart from the standard and allow memory and string operations to + * have different max sizes. See the respective safe_mem_lib.h or + * safe_str_lib.h files. + */ +/* #define RSIZE_MAX (~(rsize_t)0) - leave here for completeness */ + +typedef void (*constraint_handler_t) (const char * /* msg */, + void * /* ptr */, + errno_t /* error */); + +extern void abort_handler_s(const char *msg, void *ptr, errno_t error); +extern void ignore_handler_s(const char *msg, void *ptr, errno_t error); + +#define sl_default_handler ignore_handler_s + +#include "safe_mem_lib.h" +#include "safe_str_lib.h" + +#ifdef __cplusplus +} +#endif +#endif /* __SAFE_LIB_H__ */ diff --git a/vendor/safestringlib/include/safe_lib_errno.h b/vendor/safestringlib/include/safe_lib_errno.h new file mode 100644 index 000000000..8f27111c3 --- /dev/null +++ b/vendor/safestringlib/include/safe_lib_errno.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------ + * safe_lib_errno.h -- Safe C Lib Error codes + * + * October 2008, Bo Berry + * Modified 2012, Jonathan Toppins + * + * Copyright (c) 2008-2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_LIB_ERRNO_H__ +#define __SAFE_LIB_ERRNO_H__ + +#ifdef __KERNEL__ +# include +#else +#include +#endif /* __KERNEL__ */ + +/* + * Safe Lib specific errno codes. These can be added to the errno.h file + * if desired. + */ +#ifndef ESNULLP +#define ESNULLP ( 400 ) /* null ptr */ +#endif + +#ifndef ESZEROL +#define ESZEROL ( 401 ) /* length is zero */ +#endif + +#ifndef ESLEMIN +#define ESLEMIN ( 402 ) /* length is below min */ +#endif + +#ifndef ESLEMAX +#define ESLEMAX ( 403 ) /* length exceeds max */ +#endif + +#ifndef ESOVRLP +#define ESOVRLP ( 404 ) /* overlap undefined */ +#endif + +#ifndef ESEMPTY +#define ESEMPTY ( 405 ) /* empty string */ +#endif + +#ifndef ESNOSPC +#define ESNOSPC ( 406 ) /* not enough space for s2 */ +#endif + +#ifndef ESUNTERM +#define ESUNTERM ( 407 ) /* unterminated string */ +#endif + +#ifndef ESNODIFF +#define ESNODIFF ( 408 ) /* no difference */ +#endif + +#ifndef ESNOTFND +#define ESNOTFND ( 409 ) /* not found */ +#endif + +/* Additional for safe snprintf_s interfaces */ +#ifndef ESBADFMT +#define ESBADFMT ( 410 ) /* bad format string */ +#endif + +#ifndef ESFMTTYP +#define ESFMTTYP ( 411 ) /* bad format type */ +#endif + +/* EOK may or may not be defined in errno.h */ +#ifndef EOK +#define EOK ( 0 ) +#endif + +#endif /* __SAFE_LIB_ERRNO_H__ */ diff --git a/vendor/safestringlib/include/safe_lib_errno.h.in b/vendor/safestringlib/include/safe_lib_errno.h.in new file mode 100644 index 000000000..def3420d8 --- /dev/null +++ b/vendor/safestringlib/include/safe_lib_errno.h.in @@ -0,0 +1,91 @@ +/*------------------------------------------------------------------ + * safe_lib_errno.h -- Safe C Lib Error codes + * + * October 2008, Bo Berry + * Modified 2012, Jonathan Toppins + * + * Copyright (c) 2008-2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_LIB_ERRNO_H__ +#define __SAFE_LIB_ERRNO_H__ + +#ifdef __KERNEL__ +# include +#else +@INSERT_ERRNO_H@ +#endif /* __KERNEL__ */ + +/* + * Safe Lib specific errno codes. These can be added to the errno.h file + * if desired. + */ +#ifndef ESNULLP +#define ESNULLP ( 400 ) /* null ptr */ +#endif + +#ifndef ESZEROL +#define ESZEROL ( 401 ) /* length is zero */ +#endif + +#ifndef ESLEMIN +#define ESLEMIN ( 402 ) /* length is below min */ +#endif + +#ifndef ESLEMAX +#define ESLEMAX ( 403 ) /* length exceeds max */ +#endif + +#ifndef ESOVRLP +#define ESOVRLP ( 404 ) /* overlap undefined */ +#endif + +#ifndef ESEMPTY +#define ESEMPTY ( 405 ) /* empty string */ +#endif + +#ifndef ESNOSPC +#define ESNOSPC ( 406 ) /* not enough space for s2 */ +#endif + +#ifndef ESUNTERM +#define ESUNTERM ( 407 ) /* unterminated string */ +#endif + +#ifndef ESNODIFF +#define ESNODIFF ( 408 ) /* no difference */ +#endif + +#ifndef ESNOTFND +#define ESNOTFND ( 409 ) /* not found */ +#endif + +/* EOK may or may not be defined in errno.h */ +#ifndef EOK +#define EOK ( 0 ) +#endif + +#endif /* __SAFE_LIB_ERRNO_H__ */ diff --git a/vendor/safestringlib/include/safe_mem_lib.h b/vendor/safestringlib/include/safe_mem_lib.h new file mode 100644 index 000000000..162efd2eb --- /dev/null +++ b/vendor/safestringlib/include/safe_mem_lib.h @@ -0,0 +1,122 @@ +/*------------------------------------------------------------------ + * safe_mem_lib.h -- Safe C Library Memory APIs + * + * October 2008, Bo Berry + * Modified 2012, Jonathan Toppins + * + * Copyright (c) 2008-2012 by Cisco Systems, Inc. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_MEM_LIB_H__ +#define __SAFE_MEM_LIB_H__ + +#include "safe_lib.h" +#include + +#define RSIZE_MAX_MEM ( 256UL << 20 ) /* 256MB */ +#define RSIZE_MAX_MEM16 ( RSIZE_MAX_MEM/2 ) +#define RSIZE_MAX_MEM32 ( RSIZE_MAX_MEM/4 ) + +/* set memory constraint handler */ +extern constraint_handler_t +set_mem_constraint_handler_s(constraint_handler_t handler); + + +/* compare memory */ +extern errno_t memcmp_s(const void *dest, rsize_t dmax, + const void *src, rsize_t slen, int *diff); + +/* compare uint16_t memory */ +extern errno_t memcmp16_s(const uint16_t *dest, rsize_t dmax, + const uint16_t *src, rsize_t slen, int *diff); + +/* compare uint32_t memory */ +extern errno_t memcmp32_s(const uint32_t *dest, rsize_t dmax, + const uint32_t *src, rsize_t slen, int *diff); + +/* wide compare memory */ +extern errno_t wmemcmp_s(const wchar_t *dest, rsize_t dmax, + const wchar_t *src, rsize_t smax, int *diff); + + +/* copy memory */ +extern errno_t memcpy_s(void *dest, rsize_t dmax, + const void *src, rsize_t slen); + +/* copy uint16_t memory */ +extern errno_t memcpy16_s(uint16_t *dest, rsize_t dmax, + const uint16_t *src, rsize_t slen); + +/* copy uint32_t memory */ +extern errno_t memcpy32_s(uint32_t *dest, rsize_t dmax, + const uint32_t *src, rsize_t slen); + +/* copy wchar_t memory */ +extern errno_t wmemcpy_s(wchar_t *dest, rsize_t dmax, + const wchar_t *src, rsize_t slen); + + +/* move memory, including overlapping memory */ +extern errno_t memmove_s(void *dest, rsize_t dmax, + const void *src, rsize_t slen); + +/* uint16_t move memory, including overlapping memory */ +extern errno_t memmove16_s(uint16_t *dest, rsize_t dmax, + const uint16_t *src, rsize_t slen); + +/* uint32_t move memory, including overlapping memory */ +extern errno_t memmove32_s(uint32_t *dest, rsize_t dmax, + const uint32_t *src, rsize_t slen); + +/* copy wchar_t memory, including overlapping memory */ +extern errno_t wmemmove_s(wchar_t *dest, rsize_t dmax, + const wchar_t *src, rsize_t slen); + + +/* set bytes */ +extern errno_t memset_s(void *dest, rsize_t dmax, uint8_t value); + +/* set uint16_t */ +extern errno_t memset16_s(uint16_t *dest, rsize_t dmax, uint16_t value); + +/* set uint32_t */ +extern errno_t memset32_s(uint32_t *dest, rsize_t dmax, uint32_t value); + +/* wide set bytes */ +extern errno_t wmemset_s(wchar_t *dest, wchar_t value, rsize_t len); + + +/* byte zero */ +extern errno_t memzero_s(void *dest, rsize_t dmax); + +/* uint16_t zero */ +extern errno_t memzero16_s(uint16_t *dest, rsize_t dmax); + +/* uint32_t zero */ +extern errno_t memzero32_s(uint32_t *dest, rsize_t dmax); + + +#endif /* __SAFE_MEM_LIB_H__ */ diff --git a/vendor/safestringlib/include/safe_str_lib.h b/vendor/safestringlib/include/safe_str_lib.h new file mode 100644 index 000000000..e50df36d9 --- /dev/null +++ b/vendor/safestringlib/include/safe_str_lib.h @@ -0,0 +1,293 @@ +/*------------------------------------------------------------------ + * safe_str_lib.h -- Safe C Library String APIs + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_STR_LIB_H__ +#define __SAFE_STR_LIB_H__ + +#include "safe_lib.h" +#include + +/* + * The shortest string is a null string!! + */ +#define RSIZE_MIN_STR ( 1 ) + +/* maximum sring length */ +#define RSIZE_MAX_STR ( 4UL << 10 ) /* 4KB */ + + +/* The makeup of a password */ +#define SAFE_STR_MIN_LOWERCASE ( 2 ) +#define SAFE_STR_MIN_UPPERCASE ( 2 ) +#define SAFE_STR_MIN_NUMBERS ( 1 ) +#define SAFE_STR_MIN_SPECIALS ( 1 ) + +#define SAFE_STR_PASSWORD_MIN_LENGTH ( 6 ) +#define SAFE_STR_PASSWORD_MAX_LENGTH ( 32 ) + + +/* set string constraint handler */ +extern constraint_handler_t +set_str_constraint_handler_s(constraint_handler_t handler); + + +/* string compare */ +extern errno_t +strcasecmp_s(const char *dest, rsize_t dmax, + const char *src, int *indicator); + + +/* find a substring _ case insensitive */ +extern errno_t +strcasestr_s(char *dest, rsize_t dmax, + const char *src, rsize_t slen, char **substring); + + +/* string concatenate */ +extern errno_t +strcat_s(char *dest, rsize_t dmax, const char *src); + + +/* string compare */ +extern errno_t +strcmp_s(const char *dest, rsize_t dmax, + const char *src, int *indicator); + + +/* fixed field string compare */ +extern errno_t +strcmpfld_s(const char *dest, rsize_t dmax, + const char *src, int *indicator); + + +/* string copy */ +extern errno_t +strcpy_s(char *dest, rsize_t dmax, const char *src); + +/* string copy */ +extern char * +stpcpy_s(char *dest, rsize_t dmax, const char *src, errno_t *err); + +/* string copy */ +extern char * +stpncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t smax, errno_t *err); + +/* fixed char array copy */ +extern errno_t +strcpyfld_s(char *dest, rsize_t dmax, const char *src, rsize_t slen); + + +/* copy from a null terminated string to fixed char array */ +extern errno_t +strcpyfldin_s(char *dest, rsize_t dmax, const char *src, rsize_t slen); + + +/* copy from a char array to null terminated string */ +extern errno_t +strcpyfldout_s(char *dest, rsize_t dmax, const char *src, rsize_t slen); + + +/* computes excluded prefix length */ +extern errno_t +strcspn_s(const char *dest, rsize_t dmax, + const char *src, rsize_t slen, rsize_t *count); + + +/* returns a pointer to the first occurrence of c in dest */ +extern errno_t +strfirstchar_s(char *dest, rsize_t dmax, char c, char **first); + + +/* returns index of first difference */ +extern errno_t +strfirstdiff_s(const char *dest, rsize_t dmax, + const char *src, rsize_t *index); + + +/* validate alphanumeric string */ +extern bool +strisalphanumeric_s(const char *str, rsize_t slen); + + +/* validate ascii string */ +extern bool +strisascii_s(const char *str, rsize_t slen); + + +/* validate string of digits */ +extern bool +strisdigit_s(const char *str, rsize_t slen); + + +/* validate hex string */ +extern bool +strishex_s(const char *str, rsize_t slen); + + +/* validate lower case */ +extern bool +strislowercase_s(const char *str, rsize_t slen); + + +/* validate mixed case */ +extern bool +strismixedcase_s(const char *str, rsize_t slen); + + +/* validate password */ +extern bool +strispassword_s(const char *str, rsize_t slen); + + +/* validate upper case */ +extern bool +strisuppercase_s(const char *str, rsize_t slen); + + +/* returns a pointer to the last occurrence of c in s1 */ +extern errno_t +strlastchar_s(char *str, rsize_t smax, char c, char **first); + + +/* returns index of last difference */ +extern errno_t +strlastdiff_s(const char *dest, rsize_t dmax, + const char *src, rsize_t *index); + + +/* left justify */ +extern errno_t +strljustify_s(char *dest, rsize_t dmax); + + +/* fitted string concatenate */ +extern errno_t +strncat_s(char *dest, rsize_t dmax, const char *src, rsize_t slen); + + +/* fitted string copy */ +extern errno_t +strncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t slen); + + +/* string length */ +extern rsize_t +strnlen_s (const char *s, rsize_t smax); + + +/* string terminate */ +extern rsize_t +strnterminate_s (char *s, rsize_t smax); + + +/* get pointer to first occurrence from set of char */ +extern errno_t +strpbrk_s(char *dest, rsize_t dmax, + char *src, rsize_t slen, char **first); + + +extern errno_t +strfirstsame_s(const char *dest, rsize_t dmax, + const char *src, rsize_t *index); + +extern errno_t +strlastsame_s(const char *dest, rsize_t dmax, + const char *src, rsize_t *index); + + +/* searches for a prefix */ +extern errno_t +strprefix_s(const char *dest, rsize_t dmax, const char *src); + + +/* removes leading and trailing white space */ +extern errno_t +strremovews_s(char *dest, rsize_t dmax); + + +/* computes inclusive prefix length */ +extern errno_t +strspn_s(const char *dest, rsize_t dmax, + const char *src, rsize_t slen, rsize_t *count); + + +/* find a substring */ +extern errno_t +strstr_s(char *dest, rsize_t dmax, + const char *src, rsize_t slen, char **substring); + + +/* string tokenizer */ +extern char * +strtok_s(char *s1, rsize_t *s1max, const char *src, char **ptr); + + +/* convert string to lowercase */ +extern errno_t +strtolowercase_s(char *str, rsize_t slen); + + +/* convert string to uppercase */ +extern errno_t +strtouppercase_s(char *str, rsize_t slen); + + +/* zero an entire string with nulls */ +extern errno_t +strzero_s(char *dest, rsize_t dmax); + + +/* wide string copy */ +extern wchar_t * +wcpcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, errno_t *err); + +/* wide string concatenate */ +extern errno_t +wcscat_s(wchar_t* dest, rsize_t dmax, const wchar_t* src); + +/* fitted wide string concatenate */ +extern errno_t +wcsncat_s(wchar_t *dest, rsize_t dmax, const wchar_t *src, rsize_t slen); + +/* wide string copy */ +errno_t +wcscpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src); + +/* fitted wide string copy */ +extern errno_t +wcsncpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t slen); + +/* wide string length */ +extern rsize_t +wcsnlen_s(const wchar_t *dest, rsize_t dmax); + + +#endif /* __SAFE_STR_LIB_H__ */ diff --git a/vendor/safestringlib/include/safe_types.h b/vendor/safestringlib/include/safe_types.h new file mode 100644 index 000000000..dba74740f --- /dev/null +++ b/vendor/safestringlib/include/safe_types.h @@ -0,0 +1,68 @@ +/*------------------------------------------------------------------ + * safe_types.h - C99 std types & defs or Linux kernel equivalents + * + * March 2007, Bo Berry + * Modified 2012, Jonathan Toppins + * + * Copyright (c) 2007-2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_TYPES_H__ +#define __SAFE_TYPES_H__ + +#ifdef __KERNEL__ +/* linux kernel environment */ + +#include +#include +#include + +/* errno_t isn't defined in the kernel */ +typedef int errno_t; + +#else + +#include + +/* For systems without sys/types.h, prefer to get size_t from stdlib.h */ +/* some armcc environments don't have a sys/types.h in the environment */ +#ifdef _USE_STDLIB +#include +#include +#else +#include +#endif + +#include +#include +#include + +typedef int errno_t; + +#include + +#endif /* __KERNEL__ */ +#endif /* __SAFE_TYPES_H__ */ diff --git a/vendor/safestringlib/include/safe_types.h.in b/vendor/safestringlib/include/safe_types.h.in new file mode 100644 index 000000000..7e332f800 --- /dev/null +++ b/vendor/safestringlib/include/safe_types.h.in @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------ + * safe_types.h - C99 std types & defs or Linux kernel equivalents + * + * March 2007, Bo Berry + * Modified 2012, Jonathan Toppins + * + * Copyright (c) 2007-2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_TYPES_H__ +#define __SAFE_TYPES_H__ + +#ifdef __KERNEL__ +/* linux kernel environment */ + +#include +#include +#include + +/* errno_t isn't defined in the kernel */ +typedef int errno_t; + +#else + +#include +@INSERT_SYS_TYPES_H@ +@INSERT_INTTYPES_H@ +@INSERT_STDINT_H@ +@INSERT_ERRNO_H@ + +@FALLBACK_ERRNO_T@ + +@INSERT_BOOL_SUPPORT@ + +#endif /* __KERNEL__ */ +#endif /* __SAFE_TYPES_H__ */ diff --git a/vendor/safestringlib/include/snprintf_s.h b/vendor/safestringlib/include/snprintf_s.h new file mode 100644 index 000000000..60480fe81 --- /dev/null +++ b/vendor/safestringlib/include/snprintf_s.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------ + * sprintf_s.h -- Safe Sprintf Interfaces + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ +#ifndef SPRINTF_S_H_ +#define SPRINTF_S_H_ + +#include + + +#define SNPRFNEGATE(x) (-1*(x)) + + + +int snprintf_s_i(char *dest, rsize_t dmax, const char *format, int a); +int snprintf_s_si(char *dest, rsize_t dmax, const char *format, char *s, int a); +int snprintf_s_l(char *dest, rsize_t dmax, const char *format, long a); +int snprintf_s_sl(char *dest, rsize_t dmax, const char *format, char *s, long a); + + + +#endif /* SPRINTF_S_H_ */ diff --git a/vendor/safestringlib/makefile b/vendor/safestringlib/makefile new file mode 100644 index 000000000..f7cc2680a --- /dev/null +++ b/vendor/safestringlib/makefile @@ -0,0 +1,69 @@ +IDIR = include +MKDIR_P = mkdir -p +CC=gcc +CFLAGS=-I$(IDIR) -fstack-protector-strong -fPIE -fPIC -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security +LDFLAGS=-z noexecstack -z relo -z now + +ODIR=obj +OTDIR=objtest +SRCDIR=safeclib +TESTDIR=unittests + + +_DEPS = safe_lib_errno.h safe_lib.h safe_str_lib.h safe_types.h.in safe_lib_errno.h.in safe_mem_lib.h safe_types.h + +_ODEPS = mem_primitives_lib.h safeclib_private.h safe_mem_constraint.h safe_str_constraint.h + +all: directories libsafestring.a safestringtest + + +DEPS = $(addprefix $(IDIR)/,$(_DEPS)) +ODEPS = $(addprefix $(SRCDIR)/,$(_ODEPS)) + + +_CLIB = abort_handler_s.c stpcpy_s.c strlastsame_s.c ignore_handler_s.c stpncpy_s.c strljustify_s.c memcmp16_s.c strcasecmp_s.c strncat_s.c memcmp32_s.c strcasestr_s.c strncpy_s.c memcmp_s.c strcat_s.c strnlen_s.c memcpy16_s.c strcmpfld_s.c strnterminate_s.c memcpy32_s.c strcmp_s.c strpbrk_s.c memcpy_s.c strcpyfldin_s.c strprefix_s.c memmove16_s.c strcpyfldout_s.c strremovews_s.c memmove32_s.c strcpyfld_s.c strspn_s.c memmove_s.c strcpy_s.c strstr_s.c mem_primitives_lib.c strcspn_s.c strtok_s.c strfirstchar_s.c strtolowercase_s.c memset16_s.c strfirstdiff_s.c strtouppercase_s.c memset32_s.c strfirstsame_s.c strzero_s.c memset_s.c strisalphanumeric_s.c wcpcpy_s.c memzero16_s.c strisascii_s.c wcscat_s.c memzero32_s.c strisdigit_s.c wcscpy_s.c memzero_s.c strishex_s.c wcsncat_s.c strislowercase_s.c wcsncpy_s.c safe_mem_constraint.c strismixedcase_s.c wcsnlen_s.c strispassword_s.c wmemcmp_s.c safe_str_constraint.c strisuppercase_s.c wmemcpy_s.c strlastchar_s.c wmemmove_s.c snprintf_support.c strlastdiff_s.c wmemset_s.c + +_TLIST = $(addprefix $(ODIR)/,$(_CLIB)) +OBJ = $(patsubst %.c,%.o,$(_TLIST)) +CLIB =$(addprefix $(SRCDIR)/,$(_CLIB)) + + + +$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS) $(ODEPS) + $(CC) $(LDFLAGS) -c -o $@ $< $(CFLAGS) + +libsafestring.a: $(OBJ) + ar rcs $@ $^ + + +_TESTFUNCS = Safe_String_UnitTestMain.c test_strcmp_s.c test_strnlen_s.c test_memcmp16_s.c test_strcpyfldin_s.c test_strnterminate_s.c test_memcmp32_s.c test_strcpyfldout_s.c test_strpbrk_s.c test_memcmp_s.c test_strcpyfld_s.c test_strprefix_s.c test_memcpy16_s.c test_strcpy_s.c test_strremovews_s.c test_memcpy32_s.c test_strcspn_s.c test_strspn_s.c test_memcpy_s.c test_strfirstchar_s.c test_strstr_s.c test_memmove16_s.c test_strfirstdiff_s.c test_strtok_s.c test_memmove32_s.c test_strfirstsame_s.c test_strtolowercase_s.c test_memmove_s.c test_strisalphanumeric_s.c test_strtouppercase_s.c test_memset16_s.c test_strisascii_s.c test_strzero_s.c test_memset32_s.c test_strisdigit_s.c test_wcpcpy_s.c test_memset_s.c test_strishex_s.c test_wcscat_s.c test_memzero16_s.c test_strislowercase_s.c test_wcscpy_s.c test_memzero32_s.c test_strismixed_s.c test_wcsncat_s.c test_memzero_s.c test_strispassword_s.c test_wcsncpy_s.c test_strisuppercase_s.c test_wcsnlen_s.c test_stpcpy_s.c test_strlastchar_s.c test_wmemcmp_s.c test_stpncpy_s.c test_strlastdiff_s.c test_wmemcpy_s.c test_strcasecmp_s.c test_strlastsame_s.c test_wmemmove_s.c test_strcasestr_s.c test_strljustify_s.c test_wmemset_s.c test_strcat_s.c test_strncat_s.c test_strcmpfld_s.c test_strncpy_s.c + +_TLIST2 = $(addprefix $(OTDIR)/,$(_TESTFUNCS)) +TOBJ = $(patsubst %.c,%.o,$(_TLIST2)) +TCLIB =$(addprefix $(TESTDIR)/,$(_TESTFUNCS)) + + +$(OTDIR)/%.o: $(TESTDIR)/%.c $(TESTDIR)/test_private.h + $(CC) -c -o $@ $< $(CFLAGS) + + +safestringtest: directories libsafestring.a $(TOBJ) + $(CC) $(LDFLAGS) -static -o $@ $(TOBJ) libsafestring.a + + +.PHONY: directories + +directories: ${ODIR} ${OTDIR} + +${ODIR}: + ${MKDIR_P} ${ODIR} + +${OTDIR}: + ${MKDIR_P} ${OTDIR} + +.PHONY: clean + +clean: + rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ $(OTDIR)/*.o + rm -f libsafestring.a + rm -f safestringtest diff --git a/vendor/safestringlib/safeclib/abort_handler_s.c b/vendor/safestringlib/safeclib/abort_handler_s.c new file mode 100644 index 000000000..d956bfdaa --- /dev/null +++ b/vendor/safestringlib/safeclib/abort_handler_s.c @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------ + * abort_handler_s.c + * + * 2012, Jonathan Toppins + * + * Copyright (c) 2012 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" + +/** + * NAME + * abort_handler_s + * + * SYNOPSIS + * #include "safe_lib.h" + * void abort_handler_s(const char *msg, void *ptr, errno_t error) + * + * DESCRIPTION + * This function writes a message on the standard error stream in + * an implementation-defined format. The message shall include the + * string pointed to by msg. The abort_handler_s function then calls + * the abort function. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * msg Pointer to the message describing the error + * + * ptr Pointer to aassociated data. Can be NULL. + * + * error The error code encountered. + * + * RETURN VALUE + * Does not return to caller. + * + * ALSO SEE + * ignore_handler_s() + * + */ + +void abort_handler_s(const char *msg, void *ptr, errno_t error) +{ + slprintf("ABORT CONSTRAINT HANDLER: (%u) %s\n", error, + (msg) ? msg : "Null message"); + slabort(); +} +EXPORT_SYMBOL(abort_handler_s) diff --git a/vendor/safestringlib/safeclib/ignore_handler_s.c b/vendor/safestringlib/safeclib/ignore_handler_s.c new file mode 100644 index 000000000..412e0cb71 --- /dev/null +++ b/vendor/safestringlib/safeclib/ignore_handler_s.c @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------ + * ignore_handler_s.c + * + * 2012, Jonathan Toppins + * + * Copyright (c) 2012 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" + +/** + * NAME + * ignore_handler_s + * + * SYNOPSIS + * #include "safe_lib.h" + * void ignore_handler_s(const char *msg, void *ptr, errno_t error) + * + * DESCRIPTION + * This function simply returns to the caller. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * msg Pointer to the message describing the error + * + * ptr Pointer to aassociated data. Can be NULL. + * + * error The error code encountered. + * + * RETURN VALUE + * Returns no value. + * + * ALSO SEE + * abort_handler_s() + * + */ + +void ignore_handler_s(const char *msg, void *ptr, errno_t error) +{ + + sldebug_printf("IGNORE CONSTRAINT HANDLER: (%u) %s\n", error, + (msg) ? msg : "Null message"); + return; +} +EXPORT_SYMBOL(ignore_handler_s) diff --git a/vendor/safestringlib/safeclib/mem_primitives_lib.c b/vendor/safestringlib/safeclib/mem_primitives_lib.c new file mode 100644 index 000000000..cc189e5ea --- /dev/null +++ b/vendor/safestringlib/safeclib/mem_primitives_lib.c @@ -0,0 +1,853 @@ +/*------------------------------------------------------------------ + * mem_primitives_lib.c - Unguarded Memory Copy Routines + * + * February 2005, Bo Berry + * + * Copyright (c) 2005-2009 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "mem_primitives_lib.h" + +/* + * mem_primitives_lib.c provides unguarded memory routines + * that are used by the safe_mem_library. These routines + * may also be used by an application, but the application + * is responsible for all parameter validation and alignment. + */ + +/** + * NAME + * mem_prim_set - Sets memory to value + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_set(void *dest, uint32_t len, uint8_t value) + * + * DESCRIPTION + * Sets len bytes starting at dest to the specified value + * + * INPUT PARAMETERS + * dest - pointer to memory that will be set to value + * + * len - number of bytes to be set + * + * value - byte value + * + * OUTPUT PARAMETERS + * dest - is updated + * + * RETURN VALUE + * none + * + */ +void +mem_prim_set (void *dest, uint32_t len, uint8_t value) +{ + uint8_t *dp; + uint32_t count; + uint32_t lcount; + + uint32_t *lp; + uint32_t value32; + + count = len; + + dp = dest; + + value32 = value | (value << 8) | (value << 16) | (value << 24); + + /* + * First, do the few bytes to get uint32_t aligned. + */ + for (; count && ( (uintptr_t)dp & (sizeof(uint32_t)-1) ); count--) { + *dp++ = value; + } + + /* + * Then do the uint32_ts, unrolled the loop for performance + */ + lp = (uint32_t *)dp; + lcount = count >> 2; + + while (lcount != 0) { + + switch (lcount) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32; + *lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32; + *lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32; + *lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32; + lcount -= 16; + break; + + case 15: *lp++ = value32; + case 14: *lp++ = value32; + case 13: *lp++ = value32; + case 12: *lp++ = value32; + case 11: *lp++ = value32; + case 10: *lp++ = value32; + case 9: *lp++ = value32; + case 8: *lp++ = value32; + + case 7: *lp++ = value32; + case 6: *lp++ = value32; + case 5: *lp++ = value32; + case 4: *lp++ = value32; + case 3: *lp++ = value32; + case 2: *lp++ = value32; + case 1: *lp++ = value32; + lcount = 0; + break; + } + } /* end while */ + + + dp = (uint8_t *)lp; + + /* + * compute the number of remaining bytes + */ + count &= (sizeof(uint32_t)-1); + + /* + * remaining bytes + */ + for (; count; dp++, count--) { + *dp = value; + } + + return; +} + + +/** + * NAME + * mem_prim_set16 - Sets memory to value + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_set16(uint16_t *dp, uint32_t len, uint16_t value) + * + * DESCRIPTION + * Sets len uint16_ts starting at dest to the specified value. + * Pointers must meet system alignment requirements. + * + * INPUT PARAMETERS + * dest - pointer to memory that will be set to value + * + * len - number of uint16_ts to be set + * + * value - uint16_t value + * + * OUTPUT PARAMETERS + * dest - is updated + * + * RETURN VALUE + * none + * + */ +void +mem_prim_set16 (uint16_t *dp, uint32_t len, uint16_t value) +{ + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + len -= 16; + break; + + case 15: *dp++ = value; + case 14: *dp++ = value; + case 13: *dp++ = value; + case 12: *dp++ = value; + case 11: *dp++ = value; + case 10: *dp++ = value; + case 9: *dp++ = value; + case 8: *dp++ = value; + + case 7: *dp++ = value; + case 6: *dp++ = value; + case 5: *dp++ = value; + case 4: *dp++ = value; + case 3: *dp++ = value; + case 2: *dp++ = value; + case 1: *dp++ = value; + len = 0; + break; + } + } /* end while */ + + return; +} + + +/** + * NAME + * mem_prim_set32 - Sets memory to the uint32_t value + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_set32(uint32_t *dp, uint32_t len, uint32_t value) + * + * DESCRIPTION + * Sets len uint32_ts starting at dest to the specified value + * Pointers must meet system alignment requirements. + * + * INPUT PARAMETERS + * dest - pointer to memory that will be set to value + * + * len - number of uint32_ts to be set + * + * value - uint32_t value + * + * OUTPUT PARAMETERS + * dest - is updated + * + * RETURN VALUE + * none + * + */ +void +mem_prim_set32 (uint32_t *dp, uint32_t len, uint32_t value) +{ + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + *dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value; + len -= 16; + break; + + case 15: *dp++ = value; + case 14: *dp++ = value; + case 13: *dp++ = value; + case 12: *dp++ = value; + case 11: *dp++ = value; + case 10: *dp++ = value; + case 9: *dp++ = value; + case 8: *dp++ = value; + + case 7: *dp++ = value; + case 6: *dp++ = value; + case 5: *dp++ = value; + case 4: *dp++ = value; + case 3: *dp++ = value; + case 2: *dp++ = value; + case 1: *dp++ = value; + len = 0; + break; + } + } /* end while */ + + return; +} + + +/** + * NAME + * mem_prim_move - Move (handles overlap) memory + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_move(void *dest, const void *src, uint32_t len) + * + * DESCRIPTION + * Moves at most slen bytes from src to dest, up to dmax + * bytes. Dest may overlap with src. + * + * INPUT PARAMETERS + * dest - pointer to the memory that will be replaced by src. + * + * src - pointer to the memory that will be copied + * to dest + * + * len - maximum number bytes of src that can be copied + * + * OUTPUT PARAMETERS + * dest - is updated + * + * RETURN VALUE + * none + * + */ +void +mem_prim_move (void *dest, const void *src, uint32_t len) +{ + +#define wsize sizeof(uint32_t) +#define wmask (wsize - 1) + + uint8_t *dp = dest; + const uint8_t *sp = src; + + uint32_t tsp; + + /* + * Determine if we need to copy forward or backward (overlap) + */ + if ((uintptr_t)dp < (uintptr_t)sp) { + /* + * Copy forward. + */ + + /* + * get a working copy of src for bit operations + */ + tsp = (uintptr_t)sp; + + /* + * Try to align both operands. This cannot be done + * unless the low bits match. + */ + if ((tsp | (uintptr_t)dp) & wmask) { + /* + * determine how many bytes to copy to align operands + */ + if ((tsp ^ (uintptr_t)dp) & wmask || len < wsize) { + tsp = len; + + } else { + tsp = wsize - (tsp & wmask); + } + + len -= tsp; + + /* + * make the alignment + */ + do { + *dp++ = *sp++; + } while (--tsp); + } + + /* + * Now copy, then mop up any trailing bytes. + */ + tsp = len / wsize; + + if (tsp > 0) { + + do { + *(uint32_t *)dp = *(uint32_t *)sp; + + sp += wsize; + dp += wsize; + } while (--tsp); + } + + /* + * copy over the remaining bytes and we're done + */ + tsp = len & wmask; + + if (tsp > 0) { + do { + *dp++ = *sp++; + } while (--tsp); + } + + } else { + /* + * This section is used to copy backwards, to handle any + * overlap. The alignment requires (tps&wmask) bytes to + * align. + */ + + /* + * go to end of the memory to copy + */ + sp += len; + dp += len; + + /* + * get a working copy of src for bit operations + */ + tsp = (uintptr_t)sp; + + /* + * Try to align both operands. + */ + if ((tsp | (uintptr_t)dp) & wmask) { + + if ((tsp ^ (uintptr_t)dp) & wmask || len <= wsize) { + tsp = len; + } else { + tsp &= wmask; + } + + len -= tsp; + + /* + * make the alignment + */ + do { + *--dp = *--sp; + } while (--tsp); + } + + /* + * Now copy in uint32_t units, then mop up any trailing bytes. + */ + tsp = len / wsize; + + if (tsp > 0) { + do { + sp -= wsize; + dp -= wsize; + + *(uint32_t *)dp = *(uint32_t *)sp; + } while (--tsp); + } + + /* + * copy over the remaining bytes and we're done + */ + tsp = len & wmask; + if (tsp > 0) { + tsp = len & wmask; + do { + *--dp = *--sp; + } while (--tsp); + } + } + + return; +} + + +/** + * NAME + * mem_prim_move8 - Move (handles overlap) memory + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_move8(void *dest, const void *src, uint32_t len) + * + * DESCRIPTION + * Moves at most len uint8_ts from sp to dp. + * The destination may overlap with source. + * + * INPUT PARAMETERS + * dp - pointer to the memory that will be replaced by sp. + * + * sp - pointer to the memory that will be copied + * to dp + * + * len - maximum number uint8_t of sp that can be copied + * + * OUTPUT PARAMETERS + * dp - pointer to the memory that will be replaced by sp. + * + * RETURN VALUE + * none + * + */ +void +mem_prim_move8 (uint8_t *dp, const uint8_t *sp, uint32_t len) +{ + + /* + * Determine if we need to copy forward or backward (overlap) + */ + if (dp < sp) { + /* + * Copy forward. + */ + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + len -= 16; + break; + + case 15: *dp++ = *sp++; + case 14: *dp++ = *sp++; + case 13: *dp++ = *sp++; + case 12: *dp++ = *sp++; + case 11: *dp++ = *sp++; + case 10: *dp++ = *sp++; + case 9: *dp++ = *sp++; + case 8: *dp++ = *sp++; + + case 7: *dp++ = *sp++; + case 6: *dp++ = *sp++; + case 5: *dp++ = *sp++; + case 4: *dp++ = *sp++; + case 3: *dp++ = *sp++; + case 2: *dp++ = *sp++; + case 1: *dp++ = *sp++; + len = 0; + break; + } + } /* end while */ + + } else { + /* + * This section is used to copy backwards, to handle any + * overlap. The alignment requires (tps&wmask) bytes to + * align. + */ + + + /* + * go to end of the memory to copy + */ + sp += len; + dp += len; + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + len -= 16; + break; + + case 15: *--dp = *--sp; + case 14: *--dp = *--sp; + case 13: *--dp = *--sp; + case 12: *--dp = *--sp; + case 11: *--dp = *--sp; + case 10: *--dp = *--sp; + case 9: *--dp = *--sp; + case 8: *--dp = *--sp; + + case 7: *--dp = *--sp; + case 6: *--dp = *--sp; + case 5: *--dp = *--sp; + case 4: *--dp = *--sp; + case 3: *--dp = *--sp; + case 2: *--dp = *--sp; + case 1: *--dp = *--sp; + len = 0; + break; + } + } /* end while */ + } + + return; +} + + +/** + * NAME + * mem_prim_move16 - Move (handles overlap) memory + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_move16(void *dest, const void *src, uint32_t len) + * + * DESCRIPTION + * Moves at most len uint16_ts from sp to dp. + * The destination may overlap with source. + * + * INPUT PARAMETERS + * dp - pointer to the memory that will be replaced by sp. + * + * sp - pointer to the memory that will be copied + * to dp + * + * len - maximum number uint16_t of sp that can be copied + * + * OUTPUT PARAMETERS + * dp - is updated + * + * RETURN VALUE + * none + * + */ +void +mem_prim_move16 (uint16_t *dp, const uint16_t *sp, uint32_t len) +{ + + /* + * Determine if we need to copy forward or backward (overlap) + */ + if (dp < sp) { + /* + * Copy forward. + */ + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + len -= 16; + break; + + case 15: *dp++ = *sp++; + case 14: *dp++ = *sp++; + case 13: *dp++ = *sp++; + case 12: *dp++ = *sp++; + case 11: *dp++ = *sp++; + case 10: *dp++ = *sp++; + case 9: *dp++ = *sp++; + case 8: *dp++ = *sp++; + + case 7: *dp++ = *sp++; + case 6: *dp++ = *sp++; + case 5: *dp++ = *sp++; + case 4: *dp++ = *sp++; + case 3: *dp++ = *sp++; + case 2: *dp++ = *sp++; + case 1: *dp++ = *sp++; + len = 0; + break; + } + } /* end while */ + + } else { + /* + * This section is used to copy backwards, to handle any + * overlap. The alignment requires (tps&wmask) bytes to + * align. + */ + + /* + * go to end of the memory to copy + */ + sp += len; + dp += len; + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + len -= 16; + break; + + case 15: *--dp = *--sp; + case 14: *--dp = *--sp; + case 13: *--dp = *--sp; + case 12: *--dp = *--sp; + case 11: *--dp = *--sp; + case 10: *--dp = *--sp; + case 9: *--dp = *--sp; + case 8: *--dp = *--sp; + + case 7: *--dp = *--sp; + case 6: *--dp = *--sp; + case 5: *--dp = *--sp; + case 4: *--dp = *--sp; + case 3: *--dp = *--sp; + case 2: *--dp = *--sp; + case 1: *--dp = *--sp; + len = 0; + break; + } + } /* end while */ + } + + return; +} + + +/** + * NAME + * mem_prim_move32 - Move (handles overlap) memory + * + * SYNOPSIS + * #include "mem_primitives_lib.h" + * void + * mem_prim_move32(void *dest, const void *src, uint32_t len) + * + * DESCRIPTION + * Moves at most len uint32_ts from sp to dp. + * The destination may overlap with source. + * + * INPUT PARAMETERS + * dp - pointer to the memory that will be replaced by sp. + * + * sp - pointer to the memory that will be copied + * to dp + * + * len - maximum number uint32_t of sp that can be copied + * + * OUTPUT PARAMETERS + * dp - is updated + * + * RETURN VALUE + * none + * + */ +void +mem_prim_move32 (uint32_t *dp, const uint32_t *sp, uint32_t len) +{ + + /* + * Determine if we need to copy forward or backward (overlap) + */ + if (dp < sp) { + /* + * Copy forward. + */ + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; + len -= 16; + break; + + case 15: *dp++ = *sp++; + case 14: *dp++ = *sp++; + case 13: *dp++ = *sp++; + case 12: *dp++ = *sp++; + case 11: *dp++ = *sp++; + case 10: *dp++ = *sp++; + case 9: *dp++ = *sp++; + case 8: *dp++ = *sp++; + + case 7: *dp++ = *sp++; + case 6: *dp++ = *sp++; + case 5: *dp++ = *sp++; + case 4: *dp++ = *sp++; + case 3: *dp++ = *sp++; + case 2: *dp++ = *sp++; + case 1: *dp++ = *sp++; + len = 0; + break; + } + } /* end while */ + + } else { + /* + * This section is used to copy backwards, to handle any + * overlap. + */ + + /* + * go to end of the memory to copy + */ + sp += len; + dp += len; + + while (len != 0) { + + switch (len) { + /* + * Here we do blocks of 8. Once the remaining count + * drops below 8, take the fast track to finish up. + */ + default: + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp; + len -= 16; + break; + + case 15: *--dp = *--sp; + case 14: *--dp = *--sp; + case 13: *--dp = *--sp; + case 12: *--dp = *--sp; + case 11: *--dp = *--sp; + case 10: *--dp = *--sp; + case 9: *--dp = *--sp; + case 8: *--dp = *--sp; + + case 7: *--dp = *--sp; + case 6: *--dp = *--sp; + case 5: *--dp = *--sp; + case 4: *--dp = *--sp; + case 3: *--dp = *--sp; + case 2: *--dp = *--sp; + case 1: *--dp = *--sp; + len = 0; + break; + } + } /* end while */ + } + + return; +} diff --git a/vendor/safestringlib/safeclib/mem_primitives_lib.h b/vendor/safestringlib/safeclib/mem_primitives_lib.h new file mode 100644 index 000000000..26c83d858 --- /dev/null +++ b/vendor/safestringlib/safeclib/mem_primitives_lib.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------ + * mem_primitives_lib.h - Unguarded Memory Copy Routines + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __MEM_PRIMITIVES_LIB_H__ +#define __MEM_PRIMITIVES_LIB_H__ + +#include "safeclib_private.h" + +/* + * These are prototypes for _unguarded_ memory routines. The caller must + * validate all parameters prior to invocation. Useful for diagnostics + * and system initialization processing. + */ + +/* moves (handles overlap) memory */ +extern void +mem_prim_move(void *dest, const void *src, uint32_t length); + + +/* uint8_t moves (handles overlap) memory */ +extern void +mem_prim_move8(uint8_t *dest, const uint8_t *src, uint32_t length); + +/* uint16_t moves (handles overlap) memory */ +extern void +mem_prim_move16(uint16_t *dest, const uint16_t *src, uint32_t length); + +/* uint32_t moves (handles overlap) memory */ +extern void +mem_prim_move32(uint32_t *dest, const uint32_t *src, uint32_t length); + + +/* set bytes */ +extern void +mem_prim_set(void *dest, uint32_t dmax, uint8_t value); + +/* set uint16_ts */ +extern void +mem_prim_set16(uint16_t *dest, uint32_t dmax, uint16_t value); + +/* set uint32_ts */ +extern void +mem_prim_set32(uint32_t *dest, uint32_t dmax, uint32_t value); + + +#endif /* __MEM_PRIMITIVES_LIB_H__ */ diff --git a/vendor/safestringlib/safeclib/memcmp16_s.c b/vendor/safestringlib/safeclib/memcmp16_s.c new file mode 100644 index 000000000..f19e7d24f --- /dev/null +++ b/vendor/safestringlib/safeclib/memcmp16_s.c @@ -0,0 +1,173 @@ +/*------------------------------------------------------------------ + * memcmp16_s.c - Compares memory + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "safe_mem_lib.h" + +/** + * NAME + * memcmp16_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memcmp16_s(const uint16_t *dest, rsize_t dmax, + * const uint16_t *src, rsize_t smax, int *diff) + * + * DESCRIPTION + * Compares memory until they differ, and their difference is + * returned in diff. If the block of memory is the same, diff=0. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to compare against + * + * dmax maximum length of dest, in uint16_t + * + * src pointer to the source memory to compare with dest + * + * smax maximum length of src, in uint16_t + * + * *diff pointer to the diff which is an integer greater + * than, equal to or less than zero according to + * whether the object pointed to by dest is + * greater than, equal to or less than the object + * pointed to by src. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be zero. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memcmp_s(), memcmp32_s() + * + */ +errno_t +memcmp16_s (const uint16_t *dest, rsize_t dmax, + const uint16_t *src, rsize_t smax, int *diff) +{ + + const uint16_t *dp; + const uint16_t *sp; + + dp = dest; + sp = src; + + /* + * must be able to return the diff + */ + if (diff == NULL) { + invoke_safe_mem_constraint_handler("memcmp16_s: diff is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + *diff = -1; /* default diff */ + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("memcmp16_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (sp == NULL) { + invoke_safe_mem_constraint_handler("memcmp16_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memcmp16_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM16) { + invoke_safe_mem_constraint_handler("memcmp16_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + invoke_safe_mem_constraint_handler("memcmp16_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + invoke_safe_mem_constraint_handler("memcmp16_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * no need to compare the same memory + */ + if (dp == sp) { + *diff = 0; + return (RCNEGATE(EOK)); + } + + /* + * now compare sp to dp + */ + *diff = 0; + while (dmax != 0 && smax != 0) { + if (*dp != *sp) { + *diff = *dp - *sp; + break; + } + + dmax--; + smax--; + + dp++; + sp++; + } + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memcmp16_s) diff --git a/vendor/safestringlib/safeclib/memcmp32_s.c b/vendor/safestringlib/safeclib/memcmp32_s.c new file mode 100644 index 000000000..ff355b8cb --- /dev/null +++ b/vendor/safestringlib/safeclib/memcmp32_s.c @@ -0,0 +1,167 @@ +/*------------------------------------------------------------------ + * memcmp32_s.c - Compares memory + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "safe_mem_lib.h" + +/** + * NAME + * memcmp32_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memcmp32_s(const uint32_t *dest, rsize_t dmax, + * const uint32_t *src, rsize_t smax, int *diff) + * + * DESCRIPTION + * Compares memory until they differ, and their difference is + * returned in diff. If the block of memory is the same, diff=0. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to compare against + * + * dmax maximum length of dest, in uint32_t + * + * src pointer to the source memory to compare with dest + * + * smax maximum length of src, in uint32_t + * + * *diff pointer to the diff which is an integer greater + * than, equal to or less than zero according to + * whether the object pointed to by dest is + * greater than, equal to or less than the object + * pointed to by src. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be zero. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memcmp_s(), memcmp16_s() + * + */ +errno_t +memcmp32_s (const uint32_t *dest, rsize_t dmax, + const uint32_t *src, rsize_t smax, int *diff) +{ + /* + * must be able to return the diff + */ + if (diff == NULL) { + invoke_safe_mem_constraint_handler("memcmp32_s: diff is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + *diff = -1; /* default diff */ + + + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memcmp32_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (src == NULL) { + invoke_safe_mem_constraint_handler("memcmp32_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memcmp32_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM32) { + invoke_safe_mem_constraint_handler("memcmp32_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + invoke_safe_mem_constraint_handler("memcmp32_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + invoke_safe_mem_constraint_handler("memcmp32_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * no need to compare the same memory + */ + if (dest == src) { + *diff = 0; + return (RCNEGATE(EOK)); + } + + /* + * now compare src to dest + */ + *diff = 0; + while (dmax != 0 && smax != 0) { + if (*dest != *src) { + *diff = *dest - *src; + break; + } + + dmax--; + smax--; + + dest++; + src++; + } + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memcmp32_s) diff --git a/vendor/safestringlib/safeclib/memcmp_s.c b/vendor/safestringlib/safeclib/memcmp_s.c new file mode 100644 index 000000000..b7e3f054f --- /dev/null +++ b/vendor/safestringlib/safeclib/memcmp_s.c @@ -0,0 +1,174 @@ +/*------------------------------------------------------------------ + * memcmp_s.c - Compares memory + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memcmp_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memcmp_s(const void *dest, rsize_t dmax, + * const void *src, rsize_t smax, int *diff) + * + * DESCRIPTION + * Compares memory until they differ, and their difference is + * returned in diff. If the block of memory is the same, diff=0. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to compare against + * + * dmax maximum length of dest, in bytess + * + * src pointer to the source memory to compare with dest + * + * smax length of the source memory block + * + * *diff pointer to the diff which is an integer greater + * than, equal to or less than zero according to + * whether the object pointed to by dest is + * greater than, equal to or less than the object + * pointed to by src. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be zero. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memcmp16_s(), memcmp32_s() + * + */ +errno_t +memcmp_s (const void *dest, rsize_t dmax, + const void *src, rsize_t smax, int *diff) +{ + const uint8_t *dp; + const uint8_t *sp; + + dp = dest; + sp = src; + + /* + * must be able to return the diff + */ + if (diff == NULL) { + invoke_safe_mem_constraint_handler("memcmp_s: diff is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + *diff = -1; /* default diff */ + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("memcmp_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (sp == NULL) { + invoke_safe_mem_constraint_handler("memcmp_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memcmp_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("memcmp_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + invoke_safe_mem_constraint_handler("memcmp_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + invoke_safe_mem_constraint_handler("memcmp_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * no need to compare the same memory + */ + if (dp == sp) { + *diff = 0; + return (RCNEGATE(EOK)); + } + + /* + * now compare sp to dp + */ + *diff = 0; + while (dmax > 0 && smax > 0) { + if (*dp != *sp) { + /*** *diff = *dp - *sp; ***/ + *diff = *dp < *sp ? -1 : 1; + break; + } + + dmax--; + smax--; + + dp++; + sp++; + } + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memcmp_s) diff --git a/vendor/safestringlib/safeclib/memcpy16_s.c b/vendor/safestringlib/safeclib/memcpy16_s.c new file mode 100644 index 000000000..aed0a2e8c --- /dev/null +++ b/vendor/safestringlib/safeclib/memcpy16_s.c @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------ + * memcpy16_s + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memcpy16_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memcpy16_s(uint16_t *dest, rsize_t dmax, + * const uint16_t *src, rsize_t smax) + * + * DESCRIPTION + * This function copies at most smax uint16_ts from src to dest, up to + * dmax. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be replaced by src. + * + * dmax maximum length of the resulting dest + * + * src pointer to the memory that will be copied to dest + * + * smax maximum number uint16_t of src to copy + * + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be 0. + * dmax shall not be greater than RSIZE_MAX_MEM16. + * smax shall not be greater than dmax. + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, the memcpy_s function stores + * zeros in the first dmax bytes of the object pointed to by dest + * if dest is not a null pointer and smax is valid. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP source memory overlaps destination + * + * ALSO SEE + * memcpy_s(), memcpy32_s(), memmove_s(), memmove16_s(), memmove32_s() + * + */ +errno_t +memcpy16_s (uint16_t *dest, rsize_t dmax, const uint16_t *src, rsize_t smax) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memcpy16_s: dest is NULL", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memcpy16_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM16) { + invoke_safe_mem_constraint_handler("memcpy16_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + mem_prim_set16(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy16_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + mem_prim_set16(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy16_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (src == NULL) { + mem_prim_set16(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy16_s: src is NULL", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + /* + * overlap is undefined behavior, do not allow + */ + if( ((dest > src) && (dest < (src+smax))) || + ((src > dest) && (src < (dest+dmax))) ) { + mem_prim_set16(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy16_s: overlap undefined", + NULL, ESOVRLP); + return (RCNEGATE(ESOVRLP)); + } + + /* + * now perform the copy + */ + mem_prim_move16(dest, src, smax); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memcpy16_s) diff --git a/vendor/safestringlib/safeclib/memcpy32_s.c b/vendor/safestringlib/safeclib/memcpy32_s.c new file mode 100644 index 000000000..3ad1d9a30 --- /dev/null +++ b/vendor/safestringlib/safeclib/memcpy32_s.c @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------ + * memcpy32_s + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memcpy32_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memcpy32_s(uint32_t *dest, rsize_t dmax, + * const uint32_t *src, rsize_t smax) + * + * DESCRIPTION + * This function copies at most smax uint32_ts from src to dest, up to + * dmax. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be replaced by src. + * + * dmax maximum length of the resulting dest + * + * src pointer to the memory that will be copied to dest + * + * smax maximum number uint32_t of src to copy + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be 0. + * dmax shall not be greater than RSIZE_MAX_MEM32. + * smax shall not be greater than dmax. + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, the memcpy_s function stores + * zeros in the first dmax bytes of the object pointed to by dest + * if dest is not a null pointer and smax is valid. + * + * RETURN VALUE + * EOK operation sucessful + * ESNULLP NULL pointer + * ESZEROL length was zero + * ESLEMAX length exceeds max + * ESOVRLP source memory overlaps destination + * + * ALSO SEE + * memcpy_s(), memcpy16_s(), memmove_s(), memmove16_s(), memmove32_s() + * + */ +errno_t +memcpy32_s (uint32_t *dest, rsize_t dmax, const uint32_t *src, rsize_t smax) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memcpy32_s: dest is NULL", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memcpy32_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM32) { + invoke_safe_mem_constraint_handler("memcpy32_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + mem_prim_set32(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy32_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + mem_prim_set32(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy32_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (src == NULL) { + mem_prim_set32(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy32_s: src is NULL", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + /* + * overlap is undefined behavior, do not allow + */ + if( ((dest > src) && (dest < (src+smax))) || + ((src > dest) && (src < (dest+dmax))) ) { + mem_prim_set32(dest, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy32_s: overlap undefined", + NULL, ESOVRLP); + return (RCNEGATE(ESOVRLP)); + } + + /* + * now perform the copy + */ + mem_prim_move32(dest, src, smax); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memcpy32_s) diff --git a/vendor/safestringlib/safeclib/memcpy_s.c b/vendor/safestringlib/safeclib/memcpy_s.c new file mode 100644 index 000000000..a5c77b7c6 --- /dev/null +++ b/vendor/safestringlib/safeclib/memcpy_s.c @@ -0,0 +1,163 @@ +/*------------------------------------------------------------------ + * memcpy_s + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memcpy_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memcpy_s(void *dest, rsize_t dmax, const void *src, rsize_t smax) + * + * DESCRIPTION + * This function copies at most smax bytes from src to dest, up to + * dmax. The size values are unsigned values. + * + * AR: Dave - verify ISO spec requires unsigned + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be replaced by src. + * + * dmax maximum length of the resulting dest + * + * src pointer to the memory that will be copied to dest + * + * smax maximum number bytes of src to copy + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be zero. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * Copying shall not take place between regions that overlap. + * If there is a runtime-constraint violation, the memcpy_s function + * stores zeros in the first dmax bytes of the region pointed to + * by dest if dest is not a null pointer and smax is valid. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP source memory overlaps destination + * + * ALSO SEE + * memcpy16_s(), memcpy32_s(), memmove_s(), memmove16_s(), + * memmove32_s() + * + */ +errno_t +memcpy_s (void *dest, rsize_t dmax, const void *src, rsize_t smax) +{ + uint8_t *dp; + const uint8_t *sp; + + dp = dest; + sp = src; + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("memcpy_s: dest is NULL", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memcpy_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("memcpy_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + // AR: This is not a requirement according to the ISO spec - Change? + // AR: documentation needed on use of the error handlers - + // AR: default err handler should output to stderr on DEBUG + // AR: update docs to define return RCNEGATE of the error number + if (smax == 0) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy_s: smax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (smax > dmax) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy_s: smax exceeds dmax", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (sp == NULL) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy_s: src is NULL", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + + /* + * overlap is undefined behavior, do not allow + */ + if( ((dp > sp) && (dp < (sp+smax))) || + ((sp > dp) && (sp < (dp+dmax))) ) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memcpy_s: overlap undefined", + NULL, ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + /* + * now perform the copy + */ + mem_prim_move(dp, sp, smax); + + return RCNEGATE(EOK); +} +EXPORT_SYMBOL(memcpy_s) diff --git a/vendor/safestringlib/safeclib/memmove16_s.c b/vendor/safestringlib/safeclib/memmove16_s.c new file mode 100644 index 000000000..14885e8af --- /dev/null +++ b/vendor/safestringlib/safeclib/memmove16_s.c @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------ + * memmove16_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memmove16_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memmove16_s(uint16_t *dest, rsize_t dmax, + * const uint16_t *src, rsize_t smax) + * + * DESCRIPTION + * The memmove16_s function copies smax uint16_t from the region + * pointed to by src into the region pointed to by dest. This + * copying takes place as if the smax uint16_t from the region + * pointed to by src are first copied into a temporary array of + * smax uint16_t that does not overlap the regions pointed to + * by dest or src, and then the smax uint16_t from the temporary + * array are copied into the region pointed to by dest. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to the memory that will be replaced by src. + * + * dmax maximum length of the resulting dest, in uint16_t + * + * src pointer to the memory that will be copied + * to dest + * + * smax maximum number uint16_t of src that can be copied + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be 0. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * If there is a runtime-constraint violation, the memmove_s function + * stores zeros in the first dmax characters of the regionpointed to + * by dest if dest is not a null pointer and dmax is not greater + * than RSIZE_MAX_MEM. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memmove_s(), memmove32_s(), memcpy_s(), memcpy16_s() memcpy32_s() + * + */ +errno_t +memmove16_s (uint16_t *dest, rsize_t dmax, const uint16_t *src, rsize_t smax) +{ + uint16_t *dp; + const uint16_t *sp; + + dp= dest; + sp = src; + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("memove16_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memove16_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM16) { + invoke_safe_mem_constraint_handler("memove16_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + mem_prim_set16(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memove16_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + mem_prim_set16(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memove16_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (sp == NULL) { + mem_prim_set16(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memove16_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + + /* + * now perform the copy + */ + mem_prim_move16(dp, sp, smax); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memmove16_s) diff --git a/vendor/safestringlib/safeclib/memmove32_s.c b/vendor/safestringlib/safeclib/memmove32_s.c new file mode 100644 index 000000000..18e854309 --- /dev/null +++ b/vendor/safestringlib/safeclib/memmove32_s.c @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------ + * memmove32_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memmove32_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memmove32_s(uint32_t *dest, rsize_t dmax, + * const uint32_t *src, rsize_t smax) + * + * DESCRIPTION + * The memmove32_s function copies smax uint32_ts from the region + * pointed to by src into the region pointed to by dest. This + * copying takes place as if the smax uint32_ts from the region + * pointed to by src are first copied into a temporary array of + * smax uint32_ts that does not overlap the regions pointed to + * by dest or src, and then the smax uint32_ts from the temporary + * array are copied into the region pointed to by dest. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to the memory that will be replaced by src. + * + * dmax maximum length of the resulting dest, in uint32_t + * + * src pointer to the memory that will be copied + * to dest + * + * smax maximum number uint32_t of src that can be copied + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be 0. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * If there is a runtime-constraint violation, the memmove_s function + * stores zeros in the first dmax characters of the regionpointed to + * by dest if dest is not a null pointer and dmax is not greater + * than RSIZE_MAX_MEM. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memmove_s(), memmove16_s(), memcpy_s(), memcpy16_s() memcpy32_s() + * + */ +errno_t +memmove32_s (uint32_t *dest, rsize_t dmax, const uint32_t *src, rsize_t smax) +{ + uint32_t *dp; + const uint32_t *sp; + + dp= dest; + sp = src; + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("memove32_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memove32_s: dest is zero", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM32) { + invoke_safe_mem_constraint_handler("memove32_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + mem_prim_set32(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memove32_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + mem_prim_set32(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memove32_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (sp == NULL) { + mem_prim_set32(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memove32_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + /* + * now perform the copy + */ + mem_prim_move32(dp, sp, smax); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memmove32_s) diff --git a/vendor/safestringlib/safeclib/memmove_s.c b/vendor/safestringlib/safeclib/memmove_s.c new file mode 100644 index 000000000..d040d0599 --- /dev/null +++ b/vendor/safestringlib/safeclib/memmove_s.c @@ -0,0 +1,149 @@ +/*------------------------------------------------------------------ + * memmove_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memmove_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memmove_s(void *dest, rsize_t dmax, + * const void *src, rsize_t smax) + * + * DESCRIPTION + * The memmove_s function copies smax bytes from the region pointed + * to by src into the region pointed to by dest. This copying takes place + * as if the smax bytes from the region pointed to by src are first copied + * into a temporary array of smax bytes that does not overlap the region + * pointed to by dest or src, and then the smax bytes from the temporary + * array are copied into the object region to by dest. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to the memory that will be replaced by src. + * + * dmax maximum length of the resulting dest, in bytes + * + * src pointer to the memory that will be copied + * to dest + * + * smax maximum number bytes of src that can be copied + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be 0. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * If there is a runtime-constraint violation, the memmove_s function + * stores zeros in the first dmax characters of the regionpointed to + * by dest if dest is not a null pointer and dmax is not greater + * than RSIZE_MAX_MEM. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memmove16_s(), memmove32_s(), memcpy_s(), memcpy16_s() memcpy32_s() + * + */ +errno_t +memmove_s (void *dest, rsize_t dmax, const void *src, rsize_t smax) +{ + uint8_t *dp; + const uint8_t *sp; + + dp= dest; + sp = src; + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("memmove_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("memmove_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("memmove_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memmove_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memmove_s: smax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (sp == NULL) { + mem_prim_set(dp, dmax, 0); + invoke_safe_mem_constraint_handler("memmove_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + /* + * now perform the copy + */ + mem_prim_move(dp, sp, smax); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memmove_s) diff --git a/vendor/safestringlib/safeclib/memset16_s.c b/vendor/safestringlib/safeclib/memset16_s.c new file mode 100644 index 000000000..a7372d28c --- /dev/null +++ b/vendor/safestringlib/safeclib/memset16_s.c @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------ + * memset16_s + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memset16_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memset16_s(uint16_t *dest, rsize_t len, uint16_t value) + * + * DESCRIPTION + * Sets len uint16_t starting at dest to the specified value. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be set to the value + * + * len number of uint16_t to be set + * + * value uint16_t value to be written + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM16. + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memset_s(), memset32_s() + * + */ +errno_t +memset16_s (uint16_t *dest, rsize_t len, uint16_t value) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memset16_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("memset16_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len > RSIZE_MAX_MEM16) { + invoke_safe_mem_constraint_handler("memset16_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + mem_prim_set16(dest, len, value); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memset16_s) diff --git a/vendor/safestringlib/safeclib/memset32_s.c b/vendor/safestringlib/safeclib/memset32_s.c new file mode 100644 index 000000000..0e8fb2e75 --- /dev/null +++ b/vendor/safestringlib/safeclib/memset32_s.c @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------ + * memset32_s + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memset32_s - Sets a block of memory to value + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memset32_s(uint32_t *dest, rsize_t len, uint32_t value) + * + * DESCRIPTION + * Sets len uint32_t starting at dest to the specified value. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be set to the value + * + * len number of uint32_t to be set + * + * value uint32_t value to be written + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM32. + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memset_s(), memset16_s() + * + */ +errno_t +memset32_s (uint32_t *dest, rsize_t len, uint32_t value) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memset32_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("memset32_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len > RSIZE_MAX_MEM32) { + invoke_safe_mem_constraint_handler("memset32_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + mem_prim_set32(dest, len, value); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memset32_s) diff --git a/vendor/safestringlib/safeclib/memset_s.c b/vendor/safestringlib/safeclib/memset_s.c new file mode 100644 index 000000000..f19717d03 --- /dev/null +++ b/vendor/safestringlib/safeclib/memset_s.c @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------ + * memset_s + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memset_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memset_s(void *dest, rsize_t len, uint8_t value) + * + * DESCRIPTION + * Sets len bytes starting at dest to the specified value. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be set to the value + * + * len number of bytes to be set + * + * value byte value + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM. + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memset16_s(), memset32_s() + * + */ +errno_t +memset_s (void *dest, rsize_t len, uint8_t value) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memset_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("memset_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("memset_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + mem_prim_set(dest, len, value); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memset_s) diff --git a/vendor/safestringlib/safeclib/memzero16_s.c b/vendor/safestringlib/safeclib/memzero16_s.c new file mode 100644 index 000000000..d4d827f8f --- /dev/null +++ b/vendor/safestringlib/safeclib/memzero16_s.c @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------ + * memzero16_s - zeros memory + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memzero16_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memzero16_s(uint16_t *dest, rsize_t len) + * + * DESCRIPTION + * Zeros len uint16_ts starting at dest. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to be zeroed. + * + * len number of uint16_ts to be zeroed + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM16. + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memzero_s(), memzero32_s() + * + */ +errno_t +memzero16_s (uint16_t *dest, rsize_t len) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memzero16_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("memzero16_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len > RSIZE_MAX_MEM16) { + invoke_safe_mem_constraint_handler("memzero16_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * mem_prim_set16(dest, len, 0xDEAD); + * mem_prim_set16(dest, len, 0xBEEF); + */ + mem_prim_set16(dest, len, 0); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memzero16_s) diff --git a/vendor/safestringlib/safeclib/memzero32_s.c b/vendor/safestringlib/safeclib/memzero32_s.c new file mode 100644 index 000000000..a582f35bc --- /dev/null +++ b/vendor/safestringlib/safeclib/memzero32_s.c @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------ + * memzero32_s - zeros memory + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memzero32_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memzero32_s(uint32_t *dest, rsize_t len) + * + * DESCRIPTION + * Zeros len uint32_ts starting at dest. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to be zeroed. + * + * len number of uint32_ts to be zeroed + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM32. + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memzero_s(), memzero16_s() + * + */ +errno_t +memzero32_s (uint32_t *dest, rsize_t len) +{ + + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memzero32_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("memzero32_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len > RSIZE_MAX_MEM32) { + invoke_safe_mem_constraint_handler("memzero32_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * mem_prim_set32(dest, len, 0xDEADBEEF); + * mem_prim_set32(dest, len, 0xBA5EBA11); + */ + mem_prim_set32(dest, len, 0); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memzero32_s) diff --git a/vendor/safestringlib/safeclib/memzero_s.c b/vendor/safestringlib/safeclib/memzero_s.c new file mode 100644 index 000000000..91d990b3e --- /dev/null +++ b/vendor/safestringlib/safeclib/memzero_s.c @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------ + * memzero_s - zeros memory + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * memzero_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * memzero_s(void *dest, rsize_t len) + * + * DESCRIPTION + * Zeros len bytes starting at dest. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to be zeroed. + * + * len number of bytes to be zeroed + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM. + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memzero16_s(), memzero32_s() + * + */ +errno_t +memzero_s (void *dest, rsize_t len) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("memzero_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("memzero_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("memzero_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * mem_prim_set(dest, len, 0xA5); + * mem_prim_set(dest, len, 0x5A); + */ + mem_prim_set(dest, len, 0); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(memzero_s) diff --git a/vendor/safestringlib/safeclib/safe_mem_constraint.c b/vendor/safestringlib/safeclib/safe_mem_constraint.c new file mode 100644 index 000000000..9fafe9e89 --- /dev/null +++ b/vendor/safestringlib/safeclib/safe_mem_constraint.c @@ -0,0 +1,142 @@ +/*------------------------------------------------------------------ + * safe_mem_constraint.c + * + * October 2008, Bo Berry + * 2012, Jonathan Toppins + * + * Copyright (c) 2008-2012 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "safe_mem_lib.h" + + +static constraint_handler_t mem_handler = NULL; + + +/** + * NAME + * set_mem_constraint_handler_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * constraint_handler_t + * set_mem_constraint_handler_straint_handler_t handler) + * + * DESCRIPTION + * The set_mem_constraint_handler_s function sets the runtime-constraint + * handler to be handler. The runtime-constraint handler is the function to + * be called when a library function detects a runtime-constraint + * order: + * 1. A pointer to a character string describing the + * runtime-constraint violation. + * 2. A null pointer or a pointer to an implementation defined + * object. + * 3. If the function calling the handler has a return type declared + * as errno_t, the return value of the function is passed. + * Otherwise, a positive value of type errno_t is passed. + * The implementation has a default constraint handler that is used if no + * calls to the set_constraint_handler_s function have been made. The + * behavior of the default handler is implementation-defined, and it may + * cause the program to exit or abort. If the handler argument to + * set_constraint_handler_s is a null pointer, the implementation default + * handler becomes the current constraint handler. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * *msg Pointer to the message describing the error + * + * *ptr Pointer to aassociated data. Can be NULL. + * + * error The error code encountered. + * + * OUTPUT PARAMETERS + * none + * + * RETURN VALUE + * none + * + * ALSO SEE + * set_str_constraint_handler_s() + */ +constraint_handler_t +set_mem_constraint_handler_s (constraint_handler_t handler) +{ + constraint_handler_t prev_handler = mem_handler; + if (NULL == handler) { + mem_handler = sl_default_handler; + } else { + mem_handler = handler; + } + return prev_handler; +} +EXPORT_SYMBOL(set_mem_constraint_handler_s) + + +/** + * NAME + * invoke_safe_mem_constraint_handler + * + * SYNOPSIS + * #include "safe_mem_constraint.h" + * void + * invoke_safe_mem_constraint_handler(const char *msg, + * void *ptr, + * errno_t error) + * + * DESCRIPTION + * Invokes the currently set constraint handler or the default. + * + * INPUT PARAMETERS + * *msg Pointer to the message describing the error + * + * *ptr Pointer to aassociated data. Can be NULL. + * + * error The error code encountered. + * + * OUTPUT PARAMETERS + * none + * + * RETURN VALUE + * none + * + */ +void +invoke_safe_mem_constraint_handler (const char *msg, + void *ptr, + errno_t error) +{ + if (NULL != mem_handler) { + mem_handler(msg, ptr, error); + } else { + sl_default_handler(msg, ptr, error); + } +} diff --git a/vendor/safestringlib/safeclib/safe_mem_constraint.h b/vendor/safestringlib/safeclib/safe_mem_constraint.h new file mode 100644 index 000000000..7ec898e1f --- /dev/null +++ b/vendor/safestringlib/safeclib/safe_mem_constraint.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------ + * safe_mem_constraint.h + * + * October 2008, Bo Berry + * + * Copyright (c) 2008, 2009 by Cisco Systems, Inc. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_MEM_CONSTRAINT_H__ +#define __SAFE_MEM_CONSTRAINT_H__ + +#include "safeclib_private.h" + +/* + * Function used by the libraries to invoke the registered + * runtime-constraint handler. Always needed. + */ +extern void invoke_safe_mem_constraint_handler( + const char *msg, + void *ptr, + errno_t error); + +#endif /* __SAFE_MEM_CONSTRAINT_H__ */ diff --git a/vendor/safestringlib/safeclib/safe_str_constraint.c b/vendor/safestringlib/safeclib/safe_str_constraint.c new file mode 100644 index 000000000..d57058f93 --- /dev/null +++ b/vendor/safestringlib/safeclib/safe_str_constraint.c @@ -0,0 +1,146 @@ +/*------------------------------------------------------------------ + * safe_str_constraint.c + * + * October 2008, Bo Berry + * 2012, Jonathan Toppins + * + * Copyright (c) 2008, 2009, 2012 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +static constraint_handler_t str_handler = NULL; + + +/** + * NAME + * set_str_constraint_handler_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * constraint_handler_t + * set_str_constraint_handler_s(constraint_handler_t handler) + * + * DESCRIPTION + * The set_str_constraint_handler_s function sets the runtime-constraint + * handler to be handler. The runtime-constraint handler is the function to + * be called when a library function detects a runtime-constraint + * violation. Only the most recent handler registered with + * set_str_constraint_handler_s is called when a runtime-constraint + * violation occurs. + * When the handler is called, it is passed the following arguments in + * the following order: + * 1. A pointer to a character string describing the + * runtime-constraint violation. + * 2. A null pointer or a pointer to an implementation defined + * object. + * 3. If the function calling the handler has a return type declared + * as errno_t, the return value of the function is passed. + * Otherwise, a positive value of type errno_t is passed. + * The implementation has a default constraint handler that is used if no + * calls to the set_constraint_handler_s function have been made. The + * behavior of the default handler is implementation-defined, and it may + * cause the program to exit or abort. If the handler argument to + * set_constraint_handler_s is a null pointer, the implementation default + * handler becomes the current constraint handler. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * *msg Pointer to the message describing the error + * + * *ptr Pointer to aassociated data. Can be NULL. + * + * error The error code encountered. + * + * OUTPUT PARAMETERS + * none + * + * RETURN VALUE + * none + * + * ALSO SEE + * set_str_constraint_handler_s() + */ +constraint_handler_t +set_str_constraint_handler_s (constraint_handler_t handler) +{ + constraint_handler_t prev_handler = str_handler; + if (NULL == handler) { + str_handler = sl_default_handler; + } else { + str_handler = handler; + } + return prev_handler; +} +EXPORT_SYMBOL(set_str_constraint_handler_s) + + +/** + * NAME + * invoke_safe_str_constraint_handler + * + * SYNOPSIS + * #include "safe_str_constraint.h" + * void + * invoke_safe_str_constraint_handler (const char *msg, + * void *ptr, + * errno_t error) + * + * DESCRIPTION + * Invokes the currently set constraint handler or the default. + * + * INPUT PARAMETERS + * *msg Pointer to the message describing the error + * + * *ptr Pointer to aassociated data. Can be NULL. + * + * error The error code encountered. + * + * OUTPUT PARAMETERS + * none + * + * RETURN VALUE + * none + * + */ +void +invoke_safe_str_constraint_handler (const char *msg, + void *ptr, + errno_t error) +{ + if (NULL != str_handler) { + str_handler(msg, ptr, error); + } else { + sl_default_handler(msg, ptr, error); + } +} diff --git a/vendor/safestringlib/safeclib/safe_str_constraint.h b/vendor/safestringlib/safeclib/safe_str_constraint.h new file mode 100644 index 000000000..a1fba3e7e --- /dev/null +++ b/vendor/safestringlib/safeclib/safe_str_constraint.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------ + * safe_str_constraint.h + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 Cisco Systems + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFE_STR_CONSTRAINT_H__ +#define __SAFE_STR_CONSTRAINT_H__ + +#include "safeclib_private.h" + +/* + * Function used by the libraries to invoke the registered + * runtime-constraint handler. Always needed. + */ +extern void invoke_safe_str_constraint_handler( + const char *msg, + void *ptr, + errno_t error); + + +/* + * Safe C Lib internal string routine to consolidate error handling + */ +static inline void handle_error(char *orig_dest, rsize_t orig_dmax, + char *err_msg, errno_t err_code) +{ +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to eliminate partial copy */ + while (orig_dmax) { *orig_dest = '\0'; orig_dmax--; orig_dest++; } +#else + *orig_dest = '\0'; +#endif + + invoke_safe_str_constraint_handler(err_msg, NULL, err_code); + return; +} + +static inline void handle_wc_error(wchar_t *orig_dest, rsize_t orig_dmax, + char *err_msg, errno_t err_code) +{ +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to eliminate partial copy */ + while (orig_dmax) { *orig_dest = L'\0'; orig_dmax--; orig_dest++; } +#else + *orig_dest = L'\0'; +#endif + + invoke_safe_str_constraint_handler(err_msg, NULL, err_code); + return; +} + +#endif /* __SAFE_STR_CONSTRAINT_H__ */ diff --git a/vendor/safestringlib/safeclib/safeclib_private.h b/vendor/safestringlib/safeclib/safeclib_private.h new file mode 100644 index 000000000..7280e879a --- /dev/null +++ b/vendor/safestringlib/safeclib/safeclib_private.h @@ -0,0 +1,93 @@ +/*------------------------------------------------------------------ + * safeclib_private.h - Internal library references + * + * 2012, Jonathan Toppins + * + * Copyright (c) 2012, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#ifndef __SAFECLIB_PRIVATE_H__ +#define __SAFECLIB_PRIVATE_H__ + +#ifdef __KERNEL__ +/* linux kernel environment */ + +#include +#include +#include + +#define RCNEGATE(x) ( -(x) ) + +#define slprintf(...) printk(KERN_EMERG __VA_ARGS__) +#define slabort() +#ifdef DEBUG +#define sldebug_printf(...) printk(KERN_DEBUG __VA_ARGS__) +#endif + +#else /* !__KERNEL__ */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#ifdef STDC_HEADERS +# include +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_LIMITS_H +# include +#endif + +#define EXPORT_SYMBOL(sym) +#define RCNEGATE(x) (x) + +#define slprintf(...) fprintf(stderr, __VA_ARGS__) +#define slabort() abort() +#ifdef DEBUG +#define sldebug_printf(...) printf(__VA_ARGS__) +#endif + +#endif /* __KERNEL__ */ + +#ifndef sldebug_printf +#define sldebug_printf(...) +#endif + +#include "safe_lib.h" + +#endif /* __SAFECLIB_PRIVATE_H__ */ diff --git a/vendor/safestringlib/safeclib/snprintf_support.c b/vendor/safestringlib/safeclib/snprintf_support.c new file mode 100644 index 000000000..52a0739f8 --- /dev/null +++ b/vendor/safestringlib/safeclib/snprintf_support.c @@ -0,0 +1,329 @@ +/*------------------------------------------------------------------ + * snprintf_support.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" +#include "snprintf_s.h" + +#define FMT_CHAR 'c' +#define FMT_WCHAR 'C' +#define FMT_SHORT 'h' +#define FMT_INT 'd' +#define FMT_LONG 'l' +#define FMT_STRING 's' +#define FMT_WSTRING 'S' +#define FMT_DOUBLE 'g' +#define FMT_LDOUBLE 'G' +#define FMT_VOID 'p' +#define FMT_PCHAR '1' +#define FMT_PSHORT '2' +#define FMT_PINT '3' +#define FMT_PLONG '4' + + + +#define MAX_FORMAT_ELEMENTS 16 + +#define CHK_FORMAT(X,Y) (((X)==(Y))?1:0) + + +unsigned int +parse_format(const char *format, char pformatList[], unsigned int maxFormats) +{ + unsigned int numFormats = 0; + unsigned int index = 0; + unsigned int start = 0; + char lmod = 0; + + while (index < RSIZE_MAX_STR && format[index] != '\0' && numFormats < maxFormats) + { + if (format[index] == '%') { + start = index; // remember where the format string started + // Check for flags + switch( format[++index]) { + case '\0': continue; // skip - end of format string + case '%' : continue; // skip - actually a percent character + case '#' : // convert to alternate form + case '0' : // zero pad + case '-' : // left adjust + case ' ' : // pad with spaces + case '+' : // force a sign be used + index++; // skip the flag character + break; + } + // check for and skip the optional field width + while ( format[index] != '\0' && format[index] >= '0' && format[index] <= '9') { + index++; + } + // Check for an skip the optional precision + if ( format[index] != '\0' && format[index] == '.') { + index++; // skip the period + while ( format[index] != '\0' && format[index] >= '0' && format[index] <= '9') { + index++; + } + } + // Check for and skip the optional length modifiers + lmod = ' '; + switch( format[index]) { + case 'h' : if ( format[++index] == 'h') { + ++index; //also recognize the 'hh' modifier + lmod = 'H'; // for char + } else { + lmod = 'h'; // for short + } + break; + case 'l' : if ( format[++index] == 'l') { + ++index; //also recognize the 'll' modifier + lmod = 'd'; // for long long + } else { + lmod = 'l'; // for long + } + break; + case 'L' : lmod = 'L'; break; + case 'j' : + case 'z' : + case 't' : index++; + break; + } + + // Recognize and record the actual modifier + switch( format[index]) { + case 'c' : + if ( lmod == 'l') { + pformatList[numFormats] = FMT_WCHAR; // store the format character + } else { + pformatList[numFormats] = FMT_CHAR; + } + numFormats++; + index++; // skip the format character + break; + + case 'd' : case 'i' : // signed + case 'o' : case 'u' : // unsigned + case 'x' : case 'X' : // unsigned + if ( lmod == 'H') { + pformatList[numFormats] = FMT_CHAR; // store the format character + } else if ( lmod == 'l') { + pformatList[numFormats] = FMT_LONG; // store the format character + } else if ( lmod == 'h') { + pformatList[numFormats] = FMT_SHORT; // store the format character + } else{ + pformatList[numFormats] = FMT_INT; + } + numFormats++; + index++; // skip the format character + break; + + case 'e' : case 'E' : + case 'f' : case 'F' : + case 'g' : case 'G' : + case 'a' : case 'A' : + if ( lmod == 'L') { + pformatList[numFormats] = FMT_LDOUBLE; // store the format character + } else{ + pformatList[numFormats] = FMT_DOUBLE; + } + numFormats++; + index++; // skip the format character + break; + + case 's' : + if ( lmod == 'l' || lmod == 'L') { + pformatList[numFormats] = FMT_WSTRING; // store the format character + } else { + pformatList[numFormats] = FMT_STRING; + } + numFormats++; + index++; // skip the format character + break; + + case 'p' : + pformatList[numFormats] = FMT_VOID; + numFormats++; + index++; // skip the format character + break; + + case 'n' : + if ( lmod == 'H') { + pformatList[numFormats] = FMT_PCHAR; // store the format character + } else if ( lmod == 'l') { + pformatList[numFormats] = FMT_PLONG; // store the format character + } else if ( lmod == 'h') { + pformatList[numFormats] = FMT_PSHORT; // store the format character + } else{ + pformatList[numFormats] = FMT_PINT; + } + numFormats++; + index++; // skip the format character + break; + case 'm' : + // Does not represent an argument in the call stack + index++; // skip the format character + continue; + default: + printf("failed to recognize format string ["); + for (;start RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("stpcpy_s: dmax exceeds max", + NULL, ESLEMAX); + *err = RCNEGATE(ESLEMAX); + return NULL; + } + + if (src == NULL) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + invoke_safe_str_constraint_handler("stpcpy_s: src is null", + NULL, ESNULLP); + *err = RCNEGATE(ESNULLP); + return NULL; + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest == src) { + /* look for the terminating null character, or return err if not found in dmax bytes */ + while (dmax > 0) { + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + *err = RCNEGATE(EOK); + return dest; + } + + dmax--; + dest++; + } + /* null terminator not found in src before end of dmax */ + handle_error(orig_dest, orig_dmax, "stpcpy_s: not enough space for src", + ESNOSPC); + *err = RCNEGATE(ESNOSPC); + return NULL; + } + + + if (dest < src) { + overlap_bumper = src; + + /* Check that the dest buffer does not overlap src buffer */ + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "stpcpy_s: " + "overlapping objects", + ESOVRLP); + *err = RCNEGATE(ESOVRLP); + return NULL; + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + *err = RCNEGATE(EOK); + return dest; + } + + dmax--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0) { + /* check that the src buffer does not run into the dest buffer - inifinite loop */ + if (src == overlap_bumper) { + /* NOTE (dmw) this condition guarantees that SRC has already been damaged! */ + handle_error(orig_dest, orig_dmax, "stpcpy_s: overlapping objects", + ESOVRLP); + *err = RCNEGATE(ESOVRLP); + return NULL; + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + *err = RCNEGATE(EOK); + return dest; + } + + dmax--; + dest++; + src++; + } + } + + /* + * Ran out of space in dest, and did not find the null terminator in src + */ + handle_error(orig_dest, orig_dmax, "stpcpy_s: not " + "enough space for src", + ESNOSPC); + *err = RCNEGATE(ESNOSPC); + return NULL; +} +EXPORT_SYMBOL(stpcpy_s) diff --git a/vendor/safestringlib/safeclib/stpncpy_s.c b/vendor/safestringlib/safeclib/stpncpy_s.c new file mode 100644 index 000000000..890002d46 --- /dev/null +++ b/vendor/safestringlib/safeclib/stpncpy_s.c @@ -0,0 +1,282 @@ +/*------------------------------------------------------------------ + * stpncpy_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * stpncpy_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * char * + * stpncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t smax, errno_t *err); + * + * DESCRIPTION + * The stpncpy_s function copies at most smax characters from the string + * pointed to by src, including the terminating null byte ('\0'), to the + * array pointed to by dest. Exactly smax characters are written at dest. + * If the length strlen_s(src) is smaller than smax, the remaining smax + * characters in the array pointed to by dest are filled with null bytes. + * If the length strlen_s(src) is greater than or equal to smax, the string + * pointed to by dest will contain smax characters from src plus a null + * characters (dest will be null-terminated). + * + * Therefore, dmax must be at least smax+1 in order to contain the terminator. + * + * The function returns a pointer to the end of the string in dest - + * that is to the null terminator of dest. If an error occurs, + * NULL is returned and err is set to the error encountered. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * + * dmax restricted maximum length of dest (must be at least smax+1) + * + * src pointer to the string that will be copied + * to dest + * + * smax the maximum number of characters from src to copy into dest + * + * err the error code upon error, or EOK if successful + * + * OUTPUT PARAMETERS + * dest updated + * err updated as follows: + * EOK successful operation, the characters in src were + * copied into dest and the result is null terminated, + * and dest is returned to point to the first null at end of dest. + * On error, NULL is returned and err is set to one of hte following: + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * ESNOSPC not enough space to copy src + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not be greater than RSIZE_MAX_STR. + * dmax shall not equal zero. + * dmax must be at least smax+1 to allow filling dest with smax characters plus NULL. + * If src and dest overlap, copying shall be stopped; destruction of src may have occurred. + * If there is a runtime-constraint violation, then: + * if dest is not a null pointer and dmax is greater than zero and + * not greater than RSIZE_MAX_STR, then stpncpy_s shall fill dest with nulls, + * if library was compiled with SAFECLIB_STR_NULL_SLACK. + * + * RETURN VALUE + * a char pointer to the terminating null at the end of dest + * or NULL pointer on error + * + * ALSO SEE + * stpcpy_s(), strcpy_s(), strcat_s(), strncat_s(), strncpy_s() + * + */ +char * +stpncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t smax, errno_t *err) +{ + rsize_t orig_dmax; + char *orig_dest; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("stpncpy_s: dest is null", + NULL, ESNULLP); + *err = RCNEGATE(ESNULLP); + return NULL; + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("stpncpy_s: src is null", + NULL, ESNULLP); + *err = RCNEGATE(ESNULLP); + dest[0] = '\0'; + return NULL; + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("stpncpy_s: dmax is 0", + NULL, ESZEROL); + *err = RCNEGATE(ESZEROL); + return NULL; + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("stpncpy_s: dmax exceeds max", + NULL, ESLEMAX); + *err = RCNEGATE(ESLEMAX); + return NULL; + } + + if (smax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("stpncpy_s: smax exceeds max", + NULL, ESLEMAX); + *err = RCNEGATE(ESLEMAX); + return NULL; + } + + if (dmax < (smax+1)) { + invoke_safe_str_constraint_handler("stpncpy_s: dmax too short for smax", + NULL, ESNOSPC); + *err = RCNEGATE(ESNOSPC); + dest[0] = '\0'; + return NULL; + } + + /* dmwheel1: Add check to prevent destruction of overlap into destination */ + if ((src < dest) && ((src+smax) >= dest)) { + invoke_safe_str_constraint_handler("stpncpy_s: src+smax overlaps into dest", + NULL, ESOVRLP); + *err = RCNEGATE(ESOVRLP); + dest[0] = '\0'; + return NULL; + } + + /* dmwheel1: Add check to prevent destruction of overlap into source */ + if ((dest < src) && ((dest+smax) >= src)) { + invoke_safe_str_constraint_handler("stpncpy_s: dest+smax overlaps into src", + NULL, ESOVRLP); + *err = RCNEGATE(ESOVRLP); + dest[0] = '\0'; + return NULL; + } + +#ifdef SAFECLIB_STR_NULL_SLACK + /* dmwheel1: Add check to prevent destruction of overlap into destination */ + if ((src < dest) && ((src+dmax) >= dest)) { + invoke_safe_str_constraint_handler("stpncpy_s: src+dmax overlaps into dest", + NULL, ESOVRLP); + *err = RCNEGATE(ESOVRLP); + return NULL; + } + + /* dmwheel1: Add check to prevent destruction of overlap into source */ + if ((dest < src) && ((dest+dmax) >= src)) { + invoke_safe_str_constraint_handler("stpncpy_s: dest+dmax overlaps into src", + NULL, ESOVRLP); + *err = RCNEGATE(ESOVRLP); + return NULL; + } +#endif + + + if (src == NULL) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + invoke_safe_str_constraint_handler("stpncpy_s: src is null", + NULL, ESNULLP); + *err = RCNEGATE(ESNULLP); + return NULL; + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest == src) { + /* look for the terminating null character, or return err if not found in dmax bytes */ + while (dmax > 0) { + if (*dest == '\0') { + /* add nulls to complete smax */ + char *filler = dest; /* don't change dest, because we need to return it */ + while (smax) { *filler = '\0'; dmax--; smax--; filler++; } +#ifdef SAFECLIB_STR_NULL_SLACK + /* null dmax slack to clear any data */ + while (dmax) { *filler = '\0'; dmax--; filler++; } +#endif + *err = RCNEGATE(EOK); + return dest; + } + dmax--; + dest++; + if (--smax == 0) { + /* we have copied smax characters, add null terminator */ + *dest = '\0'; + } + } + /* null terminator not found in src before end of dmax */ + handle_error(orig_dest, orig_dmax, "stpncpy_s: not enough space for src", + ESNOSPC); + *err = RCNEGATE(ESNOSPC); + return NULL; + } + + + /* All checks for buffer overlaps were made, just do the copies */ + while (dmax > 0) { + + *dest = *src; /* Copy the data into the destination */ + + /* Check for maximum copy from source */ + if (smax == 0) { + /* we have copied smax characters, add null terminator */ + *dest = '\0'; + } + + /* Check for end of copying */ + if (*dest == '\0') { + /* add nulls to complete smax, if fewer than smax characters + * were in src when the NULL was encountered */ + char *filler = dest; /* don't change dest, because we need to return it */ + while (smax) { *filler = '\0'; dmax--; smax--; filler++; } +#ifdef SAFECLIB_STR_NULL_SLACK + /* null dmax slack to clear any data */ + while (dmax) { *filler = '\0'; dmax--; filler++; } +#endif + *err = RCNEGATE(EOK); + return dest; + } + dmax--; + smax--; + dest++; + src++; + + } + /* + * Ran out of space in dest, and did not find the null terminator in src + */ + handle_error(orig_dest, orig_dmax, "stpncpy_s: not enough space for src", + ESNOSPC); + *err = RCNEGATE(ESNOSPC); + return NULL; +} +EXPORT_SYMBOL(stpncpy_s) diff --git a/vendor/safestringlib/safeclib/strcasecmp_s.c b/vendor/safestringlib/safeclib/strcasecmp_s.c new file mode 100644 index 000000000..7293cef0c --- /dev/null +++ b/vendor/safestringlib/safeclib/strcasecmp_s.c @@ -0,0 +1,144 @@ +/*------------------------------------------------------------------ + * strcasecmp_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcasecmp_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcasecmp_s(const char *dest, rsize_t dmax, + * const char *src, int *indicator) + * + * DESCRIPTION + * Case insensitive string comparison by converting + * to uppercase prior to the compare. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string dest + * + * src pointer to the string to be compared to dest + * + * indicator pointer to result indicator, greater than 0, + * equal to 0 or less than 0, if the string pointed + * to by dest is greater than, equal to or less + * than the string pointed to by src respectively. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * indicator, when the return code is OK + * >0 dest greater than src + * 0 strings the same + * <0 dest less than src + * + * EOK comparison complete + * ESNULLP pointer was null + * ESZEROL length was zero + * ESLEMAX length exceeded max + * + * ALSO SEE + * strcmp_s() + * + */ +errno_t +strcasecmp_s (const char *dest, rsize_t dmax, + const char *src, int *indicator) +{ + const unsigned char *udest = (const unsigned char *) dest; + const unsigned char *usrc = (const unsigned char *) src; + + if (indicator == NULL) { + invoke_safe_str_constraint_handler("strcasecmp_s: indicator is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + *indicator = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcasecmp_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strcasecmp_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcasecmp_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcasecmp_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + while (*udest && *usrc && dmax) { + + if (toupper(*udest) != toupper(*usrc)) { + break; + } + + udest++; + usrc++; + dmax--; + } + + *indicator = (toupper(*udest) - toupper(*usrc)); + return RCNEGATE(EOK); +} +EXPORT_SYMBOL(strcasecmp_s) diff --git a/vendor/safestringlib/safeclib/strcasestr_s.c b/vendor/safestringlib/safeclib/strcasestr_s.c new file mode 100644 index 000000000..52c9d2ac0 --- /dev/null +++ b/vendor/safestringlib/safeclib/strcasestr_s.c @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------ + * strcasestr_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcasestr_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcasestr_s(char *dest, rsize_t dmax, + * const char *src, rsize_t slen, char **substring) + * + * DESCRIPTION + * The strcasestr_s() function locates the first occurrence of + * the substring pointed to by src which would be located in + * the string pointed to by dest. The comparison is case + * insensitive. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to be searched for the substring + * + * dmax restricted maximum length of dest string + * + * src pointer to the sub string + * + * slen maximum length of src string + * + * substring returned pointer to the substring + * + * OUTPUT PARAMETERS + * substring pointer to the substring + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor slen shall equal zero. + * Neither dmax nor slen shall be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * EOK successful operation, substring found. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESNOTFND substring not found + * + * ALSO SEE + * strstr_s(), strprefix_s() + * + */ +errno_t +strcasestr_s (char *dest, rsize_t dmax, + const char *src, rsize_t slen, char **substring) +{ + rsize_t len; + rsize_t dlen; + int i; + + if (substring == NULL) { + invoke_safe_str_constraint_handler("strcasestr_s: substring is null", + NULL, ESNULLP); + return (ESNULLP); + } + *substring = NULL; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcasestr_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcasestr_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcasestr_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strcasestr_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (slen == 0) { + invoke_safe_str_constraint_handler("strcasestr_s: slen is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (slen > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcasestr_s: slen exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* + * src points to a string with zero length, or + * src equals dest, return dest + */ + if (*src == '\0' || dest == src) { + *substring = dest; + return (EOK); + } + + while (*dest && dmax) { + i = 0; + len = slen; + dlen = dmax; + + while (dest[i] && dlen) { + + /* not a match, not a substring */ + if (toupper(dest[i]) != toupper(src[i])) { + break; + } + + /* move to the next char */ + i++; + len--; + dlen--; + + if (src[i] == '\0' || !len) { + *substring = dest; + return (EOK); + } + } + dest++; + dmax--; + } + + /* + * substring was not found, return NULL + */ + *substring = NULL; + return (ESNOTFND); +} +EXPORT_SYMBOL(strcasestr_s) diff --git a/vendor/safestringlib/safeclib/strcat_s.c b/vendor/safestringlib/safeclib/strcat_s.c new file mode 100644 index 000000000..16db8a793 --- /dev/null +++ b/vendor/safestringlib/safeclib/strcat_s.c @@ -0,0 +1,232 @@ +/*------------------------------------------------------------------ + * strcat_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcat_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcat_s(char *dest, rsize_t dmax, const char *src) + * + * DESCRIPTION + * The strcat_s function appends a copy of the string pointed + * to by src (including the terminating null character) to the + * end of the string pointed to by dest. The initial character + * from src overwrites the null character at the end ofdest. + * + * All elements following the terminating null character (if + * any) written by strcat_s in the array of dmax characters + * pointed to by dest take unspecified values when strcat_s + * returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be extended by src + * if dmax allows. The string is null terminated. + * If the resulting concatenated string is less + * than dmax, the remaining slack space is nulled. + * + * dmax restricted maximum length of the resulting dest, + * including the null + * + * src pointer to the string that will be concatenaed + * to string dest + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer + * dmax shall not equal zero + * dmax shall not be greater than RSIZE_MAX_STR + * dmax shall be greater than strnlen_s(src,m). + * Copying shall not takeplace between objects that overlap + * If there is a runtime-constraint violation, then if dest is + * not a null pointer and dmax is greater than zero and not + * greater than RSIZE_MAX_STR, then strcat_s nulls dest. + * + * RETURN VALUE + * EOK successful operation, all the characters from src + * were appended to dest and the result in dest is + * null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max + * ESUNTERM dest not terminated + * + * ALSO SEE + * strncat_s(), strcpy_s(), strncpy_s() + * + */ +errno_t +strcat_s (char *dest, rsize_t dmax, const char *src) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcat_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strcat_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcat_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcat_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + /* Find the end of dest */ + while (*dest != '\0') { + + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strcat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + dest++; + dmax--; + if (dmax == 0) { + handle_error(orig_dest, orig_dmax, "strcat_s: " + "dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strcat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + /* Find the end of dest */ + while (*dest != '\0') { + + /* + * NOTE: no need to check for overlap here since src comes first + * in memory and we're not incrementing src here. + */ + dest++; + dmax--; + if (dmax == 0) { + handle_error(orig_dest, orig_dmax, "strcat_s: " + "dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strcat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + } + + /* + * the entire src was not copied, so null the string + */ + handle_error(orig_dest, orig_dmax, "strcat_s: not enough " + "space for src", + ESNOSPC); + + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(strcat_s) diff --git a/vendor/safestringlib/safeclib/strcmp_s.c b/vendor/safestringlib/safeclib/strcmp_s.c new file mode 100644 index 000000000..ae3cafc88 --- /dev/null +++ b/vendor/safestringlib/safeclib/strcmp_s.c @@ -0,0 +1,140 @@ +/*------------------------------------------------------------------ + * strcmp_s.c -- string compare + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcmp_s + * + * Synpsos + * #include "safe_str_lib.h" + * errno_t + * strcmp_s(const char *dest, rsize_t dmax, + * const char *src, int *indicator) + * + * DESCRIPTION + * Compares string src to string dest. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string dest + * + * src pointer to the string to be compared to dest + * + * indicator pointer to result indicator, greater than, + * equal to or less than 0, if the string pointed + * to by dest is greater than, equal to or less + * than the string pointed to by src respectively. + * + * OUTPUT PARAMETERS + * indicator updated result indicator + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * indicator, when the return code is OK + * >0 dest greater than src + * 0 strings the same + * <0 dest less than src + * + * EOK + * ESNULLP pointer was null + * ESZEROL length was zero + * ESLEMAX length exceeded max + * + * ALSO SEE + * strcasecmp_s() + * + */ +errno_t +strcmp_s (const char *dest, rsize_t dmax, + const char *src, int *indicator) +{ + if (indicator == NULL) { + invoke_safe_str_constraint_handler("strcmp_s: indicator is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + *indicator = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcmp_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strcmp_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcmp_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcmp_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + while (*dest && *src && dmax) { + + if (*dest != *src) { + break; + } + + dest++; + src++; + dmax--; + } + + *indicator = *dest - *src; + return RCNEGATE(EOK); +} +EXPORT_SYMBOL(strcmp_s) diff --git a/vendor/safestringlib/safeclib/strcmpfld_s.c b/vendor/safestringlib/safeclib/strcmpfld_s.c new file mode 100644 index 000000000..e7a841d75 --- /dev/null +++ b/vendor/safestringlib/safeclib/strcmpfld_s.c @@ -0,0 +1,143 @@ +/*------------------------------------------------------------------ + * strcmpfld_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcmpfld_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcmpfld_s(const char *dest, rsize_t dmax, + * const char *src, int *indicator) + * + * DESCRIPTION + * Compares the character array pointed to by src to the character array + * pointed to by dest for dmax characters. The null terminator does not + * stop the comparison. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to character array to compare against + * + * dmax restricted maximum length of dest. The length is + * used for the comparison of src against dest. + * + * src pointer to the character array to be compared to dest + * + * indicator pointer to result indicator, greater than, equal + * to or less than 0, if the character array pointed + * to by dest is greater than, equal to or less + * than the character array pointed to by src. + * OUTPUT + * indicator updated result indicator + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * indicator, when the return code is OK + * >0 dest greater than src + * 0 strings the same + * <0 dest less than src + * + * EOK + * ESNULLP pointer was null + * ESZEROL length was zero + * ESLEMAX length exceeded max + * + * ALSO SEE + * strcpyfld_s(), strcpyfldin_s(), strcpyfldout_s() + * + */ +errno_t +strcmpfld_s (const char *dest, rsize_t dmax, + const char *src, int *indicator) +{ + if (indicator == NULL) { + invoke_safe_str_constraint_handler("strcmpfld_s: indicator is null", + NULL, ESNULLP); + return (ESNULLP); + } + *indicator = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcmpfld_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strcmpfld_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcmpfld_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcmpfld_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* compare for dmax charactrers, not the null! */ + while (dmax) { + + if (*dest != *src) { + break; + } + + dest++; + src++; + dmax--; + } + + *indicator = *dest - *src; + return (EOK); +} +EXPORT_SYMBOL(strcmpfld_s) diff --git a/vendor/safestringlib/safeclib/strcpy_s.c b/vendor/safestringlib/safeclib/strcpy_s.c new file mode 100644 index 000000000..67f6f0370 --- /dev/null +++ b/vendor/safestringlib/safeclib/strcpy_s.c @@ -0,0 +1,198 @@ +/*------------------------------------------------------------------ + * strcpy_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcpy_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcpy_s(char *dest, rsize_t dmax, const char *src) + * + * DESCRIPTION + * The strcpy_s function copies the string pointed to by src + * (including the terminating null character) into the array + * pointed to by dest. All elements following the terminating + * null character (if any) written by strcpy_s in the array + * of dmax characters pointed to by dest are nulled when + * strcpy_s returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * + * dmax restricted maximum length of dest + * + * src pointer to the string that will be copied + * to dest + * + * OUTPUT PARAMETERS + * dest updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not be greater than RSIZE_MAX_STR. + * dmax shall not equal zero. + * dmax shall be greater than strnlen_s(src, dmax). + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and destmax is greater than zero and + * not greater than RSIZE_MAX_STR, then strcpy_s nulls dest. + * + * RETURN VALUE + * EOK successful operation, the characters in src were + * copied into dest and the result is null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * ESNOSPC not enough space to copy src + * + * ALSO SEE + * strcat_s(), strncat_s(), strncpy_s() + * + */ +errno_t +strcpy_s (char *dest, rsize_t dmax, const char *src) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcpy_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcpy_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcpy_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (src == NULL) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + invoke_safe_str_constraint_handler("strcpy_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dest == src) { + return RCNEGATE(EOK); + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strcpy_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strcpy_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + } + + /* + * the entire src must have been copied, if not reset dest + * to null the string. + */ + handle_error(orig_dest, orig_dmax, "strcpy_s: not " + "enough space for src", + ESNOSPC); + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(strcpy_s) diff --git a/vendor/safestringlib/safeclib/strcpyfld_s.c b/vendor/safestringlib/safeclib/strcpyfld_s.c new file mode 100644 index 000000000..88463f1aa --- /dev/null +++ b/vendor/safestringlib/safeclib/strcpyfld_s.c @@ -0,0 +1,200 @@ +/*------------------------------------------------------------------ + * strcpyfld_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcpyfld_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcpyfld_s(char *dest, rsize_t dmax, const char *src, rsize_t slen) + * + * DESCRIPTION + * The strcpyfld_s function copies slen characters from the character + * array pointed to by src into the character array pointed to by dest. + * The copy operation does not stop on the null character as the + * function copies slen characters. + * + * EXTENSION TO + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to character array that will be replaced by src. + * + * dmax restricted maximum length of dest + * + * src pointer to the character array that will be copied + * to dest + * + * slen maximum length of src + * + * OUTPUT PARAMETERS + * dest updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * slen shall not equal zero. + * slen shall not exceed dmax + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and destmax is greater than zero and + * not greater than RSIZE_MAX_STR, then strcpyfld_s nulls dest. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * + * ALSO SEE + * strcpyfldin_s(), strcpyfldout_s() + * + */ +errno_t +strcpyfld_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcpyfld_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcpyfld_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcpyfld_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + if (src == NULL) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfld_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (slen == 0) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfld_s: slen is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (slen > dmax) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfld_s: src exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + while (slen > 0) { + + if (dest == overlap_bumper) { + dmax = orig_dmax; + dest = orig_dest; + + /* null string to eliminate partial copy */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler( + "strcpyfld_s: overlapping objects", + NULL, ESOVRLP); + return (ESOVRLP); + } + + *dest++ = *src++; + slen--; + dmax--; + } + + } else { + overlap_bumper = dest; + + while (slen > 0) { + + if (src == overlap_bumper) { + dmax = orig_dmax; + dest = orig_dest; + + /* null string to eliminate partial copy */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler( + "strcpyfld_s: overlapping objects", + NULL, ESOVRLP); + return (ESOVRLP); + } + + *dest++ = *src++; + slen--; + dmax--; + } + } + + /* null slack space in the field */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + return (EOK); +} +EXPORT_SYMBOL(strcpyfld_s) diff --git a/vendor/safestringlib/safeclib/strcpyfldin_s.c b/vendor/safestringlib/safeclib/strcpyfldin_s.c new file mode 100644 index 000000000..cb2ca569e --- /dev/null +++ b/vendor/safestringlib/safeclib/strcpyfldin_s.c @@ -0,0 +1,203 @@ +/*------------------------------------------------------------------ + * strcpyfldin_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcpyfldin_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcpyfldin_s(char *dest, rsize_t dmax, + * const char *src, rsize_t slen) + * + * DESCRIPTION + * The strcpyfldin_s function copies at most slen characters from the + * null terminated string pointed to by src into the fixed character + * array pointed to by dest. The copy operation stops on the null + * character if encountered and then continues to fill the field + * with nulls up to dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to character array that will be replaced by src. + * + * dmax restricted maximum length of dest + * + * src pointer to the null terminated string that will be copied + * into the character array pointed to by dest + * + * slen length of source + * + * OUTPUT PARAMETERS + * dest updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * slen shall not equal zero. + * slen shall not exceed dmax + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and dmax is greater than zero and + * not greater than RSIZE_MAX_STR, then strcpyfldin_s nulls dest. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * + * ALSO SEE + * strcpyfld_s(), strcpyfldout_s(), + * + */ +errno_t +strcpyfldin_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcpyfldin_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcpyfldin_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcpyfldin_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + if (src == NULL) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfldin_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (slen == 0) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfldin_s: slen is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (slen > dmax) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfldin_s: slen exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0 && *src) { + + if (dest == overlap_bumper) { + dmax = orig_dmax; + dest = orig_dest; + + /* null string to eliminate partial copy */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler( + "strcpyfldin_s: overlapping objects", + NULL, ESOVRLP); + return (ESOVRLP); + } + + dmax--; + *dest++ = *src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0 && *src) { + + if (src == overlap_bumper) { + dmax = orig_dmax; + dest = orig_dest; + + /* null string to eliminate partial copy */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler( + "strcpyfldin_s: overlapping objects", + NULL, ESOVRLP); + return (ESOVRLP); + } + + dmax--; + *dest++ = *src++; + } + } + + /* + * finish filling in the field with nulls if there is slack space + */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + return (EOK); +} +EXPORT_SYMBOL(strcpyfldin_s) diff --git a/vendor/safestringlib/safeclib/strcpyfldout_s.c b/vendor/safestringlib/safeclib/strcpyfldout_s.c new file mode 100644 index 000000000..740d37bb6 --- /dev/null +++ b/vendor/safestringlib/safeclib/strcpyfldout_s.c @@ -0,0 +1,205 @@ +/*------------------------------------------------------------------ + * strcpyfldout_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcpyfldout_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcpyfldout_s(char *dest, rsize_t dmax, + * const char *src, rsize_t slen) + * + * DESCRIPTION + * The strcpyfldout_s function copies slen characters from + * the character array pointed to by src into the string + * pointed to by dest. A null is included to properly + * termiante the dest string. The copy operation does not + * stop on the null character as function copies dmax + * characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * + * dmax restricted maximum length of dest + * + * src pointer to the character array to be copied + * to dest and null terminated. + * + * slen the maximum number of characters that will be + * copied from the src field into the dest string. + * + * OUTPUT PARAMETERS + * dest updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * slen shall not equal zero. + * slen shall not exceed dmax + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and dmax is greater than zero and + * not greater than RSIZE_MAX_STR, then strcpyfldout_s nulls dest. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * + * ALSO SEE + * strcpyfld_s(), strcpyfldin_s() + * + */ +errno_t +strcpyfldout_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcpyfldout_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strcpyfldout_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcpyfldout_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + if (src == NULL) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfldout_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (slen == 0) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfldout_s: slen is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (slen > dmax) { + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler("strcpyfldout_s: slen exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 1 && slen) { + + if (dest == overlap_bumper) { + dmax = orig_dmax; + dest = orig_dest; + + /* null string to eliminate partial copy */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler( + "strcpyfldout_s: overlapping objects", + NULL, ESOVRLP); + return (ESOVRLP); + } + + dmax--; + slen--; + *dest++ = *src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 1 && slen) { + + if (src == overlap_bumper) { + dmax = orig_dmax; + dest = orig_dest; + + /* null string to eliminate partial copy */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + invoke_safe_str_constraint_handler( + "strcpyfldout_s: overlapping objects", + NULL, ESOVRLP); + return (ESOVRLP); + } + + dmax--; + slen--; + *dest++ = *src++; + } + } + + /* null slack space */ + while (dmax) { *dest = '\0'; dmax--; dest++; } + + return (EOK); +} +EXPORT_SYMBOL(strcpyfldout_s) diff --git a/vendor/safestringlib/safeclib/strcspn_s.c b/vendor/safestringlib/safeclib/strcspn_s.c new file mode 100644 index 000000000..b3e09a36c --- /dev/null +++ b/vendor/safestringlib/safeclib/strcspn_s.c @@ -0,0 +1,165 @@ +/*------------------------------------------------------------------ + * strcspn_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strcspn_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strcspn_s(const char *dest, rsize_t dmax, + * const char *src, rsize_t slen, rsize_t *count) + * + * DESCRIPTION + * This function computes the prefix length of the string pointed + * to by dest which consists entirely of characters that are + * excluded from the string pointed to by src. The scanning stops + * at the first null in dest or after dmax characters. The + * exclusion string is checked to the null or after slen + * characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to determine the prefix + * + * dmax restricted maximum length of string dest + * + * src pointer to exclusion string + * + * slen restricted maximum length of string src + * + * count pointer to a count variable that will be updated + * with the dest substring length + * + * OUTPUT PARAMETERS + * count updated count variable + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * count shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * EOK count + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strspn_s(), strpbrk_s(), strstr_s() + * + */ +errno_t +strcspn_s (const char *dest, rsize_t dmax, + const char *src, rsize_t slen, rsize_t *count) +{ + const char *scan2; + rsize_t smax; + + if (count== NULL) { + invoke_safe_str_constraint_handler("strcspn_s: count is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + *count = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strcspn_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strcspn_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strcspn_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcspn_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (slen == 0 ) { + invoke_safe_str_constraint_handler("strcspn_s: slen is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (slen > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strcspn_s: slen exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + while (*dest && dmax) { + + /* + * Scanning for exclusions, so if there is a match, + * we're done! + */ + smax = slen; + scan2 = src; + while (*scan2 && smax) { + + if (*dest == *scan2) { + return RCNEGATE(EOK); + } + scan2++; + smax--; + } + + (*count)++; + dest++; + dmax--; + } + + return RCNEGATE(EOK); +} +EXPORT_SYMBOL(strcspn_s) diff --git a/vendor/safestringlib/safeclib/strfirstchar_s.c b/vendor/safestringlib/safeclib/strfirstchar_s.c new file mode 100644 index 000000000..41a1c677b --- /dev/null +++ b/vendor/safestringlib/safeclib/strfirstchar_s.c @@ -0,0 +1,128 @@ +/*------------------------------------------------------------------ + * strfirstchar_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strfirstchar_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strfirstchar_s(char *dest, rsize_t dmax, char c, char **first) + * + * DESCRIPTION + * This function returns a pointer to the first occurrence + * of character c in dest. The scanning stops at the first null + * or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string + * + * c character to locate + * + * first returned pointer to first occurrence of c + * + * OUTPUT PARAMETERS + * first updated pointer to first occurrence of c + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * first shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * pointer to first occurence of c, NULL if not found + * + * EOK pointer to first occurrence is returned + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strlastchar_s(), strfirstdiff_s(), strfirstsame_s(), + * strlastdiff_s(), strlastsame_s(), + * + */ +errno_t +strfirstchar_s (char *dest, rsize_t dmax, char c, char **first) +{ + + if (first == NULL) { + invoke_safe_str_constraint_handler("strfirstchar_s: index is null", + NULL, ESNULLP); + return (ESNULLP); + } + *first = NULL; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strfirstchar_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strfirstchar_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strfirstchar_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + while (*dest && dmax) { + + if (*dest == c) { + *first = dest; + return (EOK); + } + dest++; + dmax--; + } + + return (ESNOTFND); +} +EXPORT_SYMBOL(strfirstchar_s) diff --git a/vendor/safestringlib/safeclib/strfirstdiff_s.c b/vendor/safestringlib/safeclib/strfirstdiff_s.c new file mode 100644 index 000000000..3d1665b95 --- /dev/null +++ b/vendor/safestringlib/safeclib/strfirstdiff_s.c @@ -0,0 +1,143 @@ +/*------------------------------------------------------------------ + * strfirstdiff_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strfirstdiff_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strfirstdiff_s(const char *dest, rsize_t dmax, + * const char *src, rsize_t *index) + * + * DESCRIPTION + * Returns the index of the first character that is different + * between dest and src. Index is valid only for OK. + * The scanning stops at the first null in dest or src, or + * after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string dest + * + * src pointer to the string to be compared to dest + * + * index pointer to returned index to first difference + * + * OUTPUT PARAMETERS + * index returned index to first difference + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * index to first difference, when the return code is OK + * + * EOK index to first diff is returned + * ESNODIFF no difference + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strfirstchar_s(), strfirstsame_s(), strlastchar_s(), + * strlastdiff_s(), strlastsame_s() + * + */ + errno_t + strfirstdiff_s (const char *dest, rsize_t dmax, + const char *src, rsize_t *index) +{ + const char *rp; + + if (index == NULL) { + invoke_safe_str_constraint_handler("strfirstdiff_s: index is null", + NULL, ESNULLP); + return (ESNULLP); + } + *index = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strfirstdiff_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strfirstdiff_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strfirstdiff_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strfirstdiff_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* hold reference point */ + rp = dest; + + while (*dest && *src && dmax) { + + if (*dest != *src) { + *index = dest - rp; + return (EOK); + } + dmax--; + dest++; + src++; + } + + return (ESNODIFF); +} +EXPORT_SYMBOL(strfirstdiff_s) diff --git a/vendor/safestringlib/safeclib/strfirstsame_s.c b/vendor/safestringlib/safeclib/strfirstsame_s.c new file mode 100644 index 000000000..38dde7e3b --- /dev/null +++ b/vendor/safestringlib/safeclib/strfirstsame_s.c @@ -0,0 +1,146 @@ +/*------------------------------------------------------------------ + * strfirstsame_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strfirstsame_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strfirstsame_s(const char *dest, rsize_t dmax, + * const char *src, rsize_t *index) + * + * DESCRIPTION + * Returns the index of the first character that is the + * same between dest and src. The scanning stops at the + * fisrt null in dest or src, or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string dest + * + * src pointer to the string to be compared to dest + * + * index pointer to returned index + * + * OUTPUT PARAMETERS + * index updated index + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * index to first same char, when the return code is OK + * + * EOK index to first same char is returned + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESNOTFND not found + * + * ALSO SEE + * strfirstchar_s(), strfirstdiff_s(), strlastchar_s(), + * strlastdiff_s(), strlastsame_s() + * + */ +errno_t +strfirstsame_s (const char *dest, rsize_t dmax, + const char *src, rsize_t *index) +{ + const char *rp = 0; + + if (index == NULL) { + invoke_safe_str_constraint_handler("strfirstsame_s: index is null", + NULL, ESNULLP); + return (ESNULLP); + } + *index = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strfirstsame_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strfirstsame_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strfirstsame_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strfirstsame_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* hold reference point */ + rp = dest; + + /* + * find the offset + */ + while (*dest && *src && dmax) { + + if (*dest == *src) { + *index = (uint32_t)(dest - rp); + return (EOK); + } + + dest++; + src++; + dmax--; + } + + return (ESNOTFND); +} +EXPORT_SYMBOL(strfirstsame_s) diff --git a/vendor/safestringlib/safeclib/strisalphanumeric_s.c b/vendor/safestringlib/safeclib/strisalphanumeric_s.c new file mode 100644 index 000000000..73a371f53 --- /dev/null +++ b/vendor/safestringlib/safeclib/strisalphanumeric_s.c @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------ + * strisalphanumeric_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strisalphanumeric_s + * + * SYNOPSIS + * #include "safe_dest_lib.h" + * bool + * strisalphanumeric_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks if the entire string contains + * alphanumerics. The scanning stops at the first null + * or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * Runtime-condestaints + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true dest is alphanumeric + * false dest is not alphanumeric or an error occurred + * + * ALSO SEE + * strisascii_s(), strisdigit_s(), strishex_s(), strislowercase_s(), + * strismixedcase_s(), strisuppercase_s() + * + */ +bool +strisalphanumeric_s (const char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strisalphanumeric_s: " + "dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strisalphanumeric_s: " + "dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strisalphanumeric_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + while (*dest && dmax) { + + if (( (*dest >= '0') && (*dest <= '9') ) || + ( (*dest >= 'a') && (*dest <= 'z') ) || + ( (*dest >= 'A') && (*dest <= 'Z') )) { + dest++; + dmax--; + } else { + return (false); + } + } + + return (true); +} +EXPORT_SYMBOL(strisalphanumeric_s) diff --git a/vendor/safestringlib/safeclib/strisascii_s.c b/vendor/safestringlib/safeclib/strisascii_s.c new file mode 100644 index 000000000..982a11aec --- /dev/null +++ b/vendor/safestringlib/safeclib/strisascii_s.c @@ -0,0 +1,111 @@ +/*------------------------------------------------------------------ + * strisascii_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/* + *- + * NAME + * strisascii_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * bool + * strisascii_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks if the entire string contains ascii + * characters. The scanning stops at the first null or + * at most dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true, string is ascii + * false, string contains one or more non-ascii or an error occurred + * + * ALSO SEE + * strisalphanumeric_s(), strisdigit_s(), strishex_s(), + * strislowercase_s(), strismixedcase_s(), strisuppercase_s() + *- + */ +bool +strisascii_s (const char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strisascii_s: dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strisascii_s: dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strisascii_s: dmax " + "exceeds max", + NULL, ESLEMAX); + return (false); + } + + while (*dest && dmax) { + if ((unsigned char)*dest > 127) { + return (false); + } + dest++; + dmax--; + } + + return (true); +} +EXPORT_SYMBOL(strisascii_s) diff --git a/vendor/safestringlib/safeclib/strisdigit_s.c b/vendor/safestringlib/safeclib/strisdigit_s.c new file mode 100644 index 000000000..515c21d6b --- /dev/null +++ b/vendor/safestringlib/safeclib/strisdigit_s.c @@ -0,0 +1,113 @@ +/*------------------------------------------------------------------ + * strisdigit_s + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strisdigit_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * bool + * strisdigit_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks that the entire string contains digits. + * The scanning stops at the first null or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true string is digit + * false string is not digit or an error occurred + * + * ALSO SEE + * strisalphanumeric_s(), strisascii_s(), strishex_s(), + * strislowercase_s(), strismixedcase_s(), strisuppercase_s() + * + */ +bool +strisdigit_s (const char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strisdigit_s: dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strisdigit_s: dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strisdigit_s: dmax exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + while (*dest) { + + if ((*dest < '0') || (*dest > '9')) { + return (false); + } + dest++; + dmax--; + } + + return (true); +} +EXPORT_SYMBOL(strisdigit_s) diff --git a/vendor/safestringlib/safeclib/strishex_s.c b/vendor/safestringlib/safeclib/strishex_s.c new file mode 100644 index 000000000..63d27f045 --- /dev/null +++ b/vendor/safestringlib/safeclib/strishex_s.c @@ -0,0 +1,119 @@ +/*------------------------------------------------------------------ + * strishex_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strishex_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * bool + * strishex_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks that the entire string contains + * hex characters. The scanning stops at the first null + * or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true string is hex + * false string is not hex or an error occurred + * + * ALSO SEE + * strisalphanumeric_s(), strisascii_s(), strisdigit_s(), + * strislowercase_s(), strismixedcase_s(), + * strisuppercase_s() + * + */ +bool +strishex_s (const char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strishex_s: dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strishex_s: dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strishex_s: dmax exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + while (*dest && dmax) { + + if (((*dest >= '0') && (*dest <= '9')) || + ((*dest >= 'a') && (*dest <= 'f')) || + ((*dest >= 'A') && (*dest <= 'F'))) { + dest++; + dmax--; + + } else { + return (false); + } + } + + return (true); +} +EXPORT_SYMBOL(strishex_s) diff --git a/vendor/safestringlib/safeclib/strislowercase_s.c b/vendor/safestringlib/safeclib/strislowercase_s.c new file mode 100644 index 000000000..3e3fbdad6 --- /dev/null +++ b/vendor/safestringlib/safeclib/strislowercase_s.c @@ -0,0 +1,119 @@ +/*------------------------------------------------------------------ + * strislowercase_s.c + * + * February 2005, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strislowercase_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * bool + * strislowercase_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks if entire string is lowercase. + * The scanning stops at the first null or after dmax + * characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dest shal be null terminated. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true string is lowercase + * false string is not lowercase or an error occurred + * + * ALSO SEE + * strisalphanumeric_s(), strisascii_s(), strisdigit_s(), + * strishex_s(), strismixedcase_s(), + * strisuppercase_s() + * + */ +bool +strislowercase_s (const char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strislowercase_s: " + "dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strislowercase_s: " + "dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strislowercase_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + while (*dest && dmax) { + + if ((*dest < 'a') || (*dest > 'z')) { + return (false); + } + dest++; + dmax--; + } + + return (true); +} +EXPORT_SYMBOL(strislowercase_s) diff --git a/vendor/safestringlib/safeclib/strismixedcase_s.c b/vendor/safestringlib/safeclib/strismixedcase_s.c new file mode 100644 index 000000000..b6ef0f93c --- /dev/null +++ b/vendor/safestringlib/safeclib/strismixedcase_s.c @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------ + * strismixedcase_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strismixedcase_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * bool + * strismixedcase_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks that the entire string is mixed + * case. The scanning stops at the first null or after + * dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true string is mixed case + * false string is not mixed case or error + * + * ALSO SEE + * strisalphanumeric_s(), strisascii_s(), strisdigit_s(), + * strishex_s(), strislowercase_s(), + * strisuppercase_s() + * + */ +bool +strismixedcase_s (const char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strismixedcase_s: " + "dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strismixedcase_s: " + "dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strismixedcase_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + while (*dest) { + + if (((*dest >= 'a') && (*dest <= 'z')) || + ((*dest >= 'A') && (*dest <= 'Z'))) { + dest++; + dmax--; + } else { + return (false); + } + } + + return (true); +} +EXPORT_SYMBOL(strismixedcase_s) diff --git a/vendor/safestringlib/safeclib/strispassword_s.c b/vendor/safestringlib/safeclib/strispassword_s.c new file mode 100644 index 000000000..3a3a5d22f --- /dev/null +++ b/vendor/safestringlib/safeclib/strispassword_s.c @@ -0,0 +1,169 @@ +/*------------------------------------------------------------------ + * strispassword_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strispassword_s + * + * SYNOPSIS + * #include "strlib.h" + * bool + * strispassword_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function validates the make-up of a password string. + * -SAFE_STR_PASSWORD_MIN_LENGTH character minimum + * -SAFE_STR_PASSWORD_MAX_LENGTH character maximum + * -at least SAFE_STR_MIN_LOWERCASE lower case characters + * -at least SAFE_STR_MIN_UPPERCASE upper case characters + * -at least SAFE_STR_MIN_NUMBERS number + * -at least SAFE_STR_MIN_SPECIALS special + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax length of password string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * length > SAFE_STR_PASSWORD_MIN_LENGTH + * length < SAFE_STR_PASSWORD_MAX_LENGTH + * dest shall not be unterminated + * + * RETURN VALUE + * true, string has valid password makeup + * false, string does not meet requirements or an error occurred + * + * ALSO SEE + * strzero_s() + * + */ +bool +strispassword_s (const char *dest, rsize_t dmax) +{ + uint32_t cnt_all; + uint32_t cnt_lowercase; + uint32_t cnt_uppercase; + uint32_t cnt_numbers; + uint32_t cnt_specials; + + if (!dest) { + invoke_safe_str_constraint_handler("strispassword_s: " + "dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax < SAFE_STR_PASSWORD_MIN_LENGTH) { + invoke_safe_str_constraint_handler("strispassword_s: " + "dest is too short", + NULL, ESLEMIN); + return (false); + } + + if (dmax > SAFE_STR_PASSWORD_MAX_LENGTH) { + invoke_safe_str_constraint_handler("strispassword_s: " + "dest exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + cnt_all = cnt_lowercase = cnt_uppercase = 0; + cnt_numbers = cnt_specials = 0; + + while (*dest) { + + if (dmax == 0) { + invoke_safe_str_constraint_handler( + "strispassword_s: dest is unterminated", + NULL, ESUNTERM); + return (false); + } + dmax--; + + cnt_all++; + + if ((*dest >= '0') && (*dest <= '9')) { + cnt_numbers++; + + } else if ((*dest >= 'a') && (*dest <= 'z')) { + cnt_lowercase++; + + } else if ((*dest >= 'A') && (*dest <= 'Z')) { + cnt_uppercase++; + + /* allow all specials */ + } else if ((*dest >= 33) && (*dest <= 47)) { + cnt_specials++; + } else if ((*dest >= 58) && (*dest <= 64)) { + cnt_specials++; + } else if ((*dest >= 91) && (*dest <= 94)) { + cnt_specials++; + } else if ((*dest >= 95) && (*dest <= 96)) { + cnt_specials++; + } else if ((*dest >= 123) && (*dest <= 126)) { + cnt_specials++; + + } else { + /* illegal char in password string */ + return (false); + } + dest++; + } + + if (cnt_all < SAFE_STR_PASSWORD_MAX_LENGTH && + cnt_numbers >= SAFE_STR_MIN_NUMBERS && + cnt_lowercase >= SAFE_STR_MIN_LOWERCASE && + cnt_uppercase >= SAFE_STR_MIN_UPPERCASE && + cnt_specials >= SAFE_STR_MIN_SPECIALS ) { + return (true); + } else { + return (false); + } +} +EXPORT_SYMBOL(strispassword_s) diff --git a/vendor/safestringlib/safeclib/strisuppercase_s.c b/vendor/safestringlib/safeclib/strisuppercase_s.c new file mode 100644 index 000000000..d0b249709 --- /dev/null +++ b/vendor/safestringlib/safeclib/strisuppercase_s.c @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------ + * strisuppercase_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strisuppercase_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * bool + * strisuppercase_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * This function checks if entire string is uppercase + * The scanning stops at the first null or after dmax + * characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * true string is uppercase + * false string is not uppercase or an error occurred + * + * ALSO SEE + * strisalphanumeric_s(), strisascii_s(), strisdigit_s(), + * strishex_s(), strislowercase_s(), strismixedcase_s(), + * + */ +bool +strisuppercase_s (const char *dest, rsize_t dmax) +{ + + if (!dest) { + invoke_safe_str_constraint_handler("strisuppercase_s: " + "dest is null", + NULL, ESNULLP); + return (false); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strisuppercase_s: " + "dmax is 0", + NULL, ESZEROL); + return (false); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strisuppercase_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (false); + } + + if (*dest == '\0') { + return (false); + } + + while (*dest) { + + if ((*dest < 'A') || (*dest > 'Z')) { + return (false); + } + dest++; + dmax--; + } + + return (true); +} +EXPORT_SYMBOL(strisuppercase_s) diff --git a/vendor/safestringlib/safeclib/strlastchar_s.c b/vendor/safestringlib/safeclib/strlastchar_s.c new file mode 100644 index 000000000..36f63896f --- /dev/null +++ b/vendor/safestringlib/safeclib/strlastchar_s.c @@ -0,0 +1,132 @@ +/*------------------------------------------------------------------ + * strlastchar_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strlastchar_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strlastchar_s(char *dest, rsize_t dmax, char c, char **last) + * + * DESCRIPTION + * Returns a pointer to the last occurrence of character c in + * dest. The scanning stops at the first null or after dmax + * characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax restricted maximum length of string + * + * c character to locate + * + * last returned pointer to last occurrence + * + * OUTPUT PARAMETERS + * last updated pointer to last occurrence + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * last shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * pointer to the last occurrence, when the return code is OK + * + * EOK pointer to the last occurence is returned + * ESNOTFND c not found in dest + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strfirstchar_s(), strfirstdiff_s(), strfirstsame_s(), + * strlastdiff_s(), strlastsame_s() + * + */ +errno_t +strlastchar_s(char *dest, rsize_t dmax, char c, char **last) +{ + if (last == NULL) { + invoke_safe_str_constraint_handler("strlastchar_s: last is null", + NULL, ESNULLP); + return (ESNULLP); + } + *last = NULL; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strlastchar_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strlastchar_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strlastchar_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + while (*dest && dmax) { + + if (*dest == c) { + *last = dest; + } + + dest++; + dmax--; + } + + if (*last == NULL) { + return (ESNOTFND); + } else { + return (EOK); + } +} +EXPORT_SYMBOL(strlastchar_s) diff --git a/vendor/safestringlib/safeclib/strlastdiff_s.c b/vendor/safestringlib/safeclib/strlastdiff_s.c new file mode 100644 index 000000000..43ad28613 --- /dev/null +++ b/vendor/safestringlib/safeclib/strlastdiff_s.c @@ -0,0 +1,152 @@ +/*------------------------------------------------------------------ + * strlastdiff_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strlastdiff_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strlastdiff_s(const char *dest, rsize_t dmax, + * const char *src, rsize_t *index) + * + * DESCRIPTION + * Returns the index of the last character that is different + * between dest and src. Index is valid only for EOK. + * The scanning stops at the first null in dest or src, or + * after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string dest + * + * src pointer to the string to be compared to dest + * + * index pointer to returned index of last difference + * + * OUTPUT PARAMETERS + * index updated index of last difference + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * index to last difference, when the return code is OK + * + * EOK index to last diff is returned + * ESNODIFF no difference + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strfirstchar_s(), strfirstdiff_s(), strfirstsame_s(), + * strlastchar_s(), strlastsame_s() + * + */ +errno_t +strlastdiff_s(const char *dest, rsize_t dmax, + const char *src, rsize_t *index) +{ + const char *rp; + bool there_is_a_diff = false; + + if (index == NULL) { + invoke_safe_str_constraint_handler("strlastdiff_s: index is null", + NULL, ESNULLP); + return (ESNULLP); + } + *index = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strlastdiff_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strlastdiff_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strlastdiff_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strlastdiff_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* hold reference point */ + rp = dest; + + /* + * find the last diff + */ + while (*dest && *src && dmax) { + + if (*dest != *src) { + there_is_a_diff = true; + *index = dest - rp; + } + + dest++; + src++; + dmax--; + } + + if (there_is_a_diff) { + return (EOK); + } else { + return (ESNODIFF); + } +} +EXPORT_SYMBOL(strlastdiff_s) diff --git a/vendor/safestringlib/safeclib/strlastsame_s.c b/vendor/safestringlib/safeclib/strlastsame_s.c new file mode 100644 index 000000000..7f8dd5bad --- /dev/null +++ b/vendor/safestringlib/safeclib/strlastsame_s.c @@ -0,0 +1,153 @@ +/*------------------------------------------------------------------ + * strlastsame_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strlastsame_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strlastsame_s(const char *dest, rsize_t dmax, + * const char *src, rsize_t *index) + * + * DESCRIPTION + * Returns the index of the last character that is the + * same between dest and src. The scanning stops at the + * first nul in dest or src, or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of string dest + * + * src pointer to the string to be compared to dest + * + * index pointer to returned index + * + * OUTPUT PARAMETERS + * index updated index + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall not be a null pointer. + * indicator shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * index to last same char, when the return code is OK + * + * EOK index to last same char is returned + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESNOTFND not found + * ESUNTERM string unterminated + * + * ALSO SEE + * strfirstchar_s(), strfirstdiff_s(), strfirstsame_s(), + * strlastchar_s(), strlastdiff_s() + * + */ +errno_t +strlastsame_s (const char *dest, rsize_t dmax, + const char *src, rsize_t *index) +{ + const char *rp; + bool similarity; + + if (index == NULL) { + invoke_safe_str_constraint_handler("strlastsame_s: index is null", + NULL, ESNULLP); + return (ESNULLP); + } + *index = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strlastsame_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strlastsame_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strlastsame_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strlastsame_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* hold reference point */ + rp = dest; + + /* + * find the last offset + */ + similarity = false; + while (*dest && *src && dmax) { + + if (*dest == *src) { + similarity = true; + *index = (uint32_t)(dest - rp); + } + + dest++; + src++; + dmax--; + } + + if (similarity) { + return (EOK); + } else { + return (ESNOTFND); + } +} +EXPORT_SYMBOL(strlastsame_s) diff --git a/vendor/safestringlib/safeclib/strljustify_s.c b/vendor/safestringlib/safeclib/strljustify_s.c new file mode 100644 index 000000000..77f978790 --- /dev/null +++ b/vendor/safestringlib/safeclib/strljustify_s.c @@ -0,0 +1,160 @@ +/*------------------------------------------------------------------ + * strljustify_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reseved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strljustify_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strljustify_s(char *dest, rsize_t dmax) + * + * DESCRIPTION + * Removes beginning whitespace from the string pointed to by + * dest by shifting the text left over writting the beginning + * whitespace, left justifying the text. The left justified + * text is null terminated. + * + * The text is shifted so the original pointer can continue + * to be used. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to left justify + * + * dmax restricted maximum length of string + * + * OUTPUT PARAMETERS + * dest left justified + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * dest shall be null terminated + * + * RETURN VALUE + * EOK + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESUNTERM dest was not null terminated + * + * ALSO SEE + * strremovews_s(), + * + */ +errno_t +strljustify_s (char *dest, rsize_t dmax) +{ + char *orig_dest; + rsize_t orig_dmax; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strljustify_s_s: " + "dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strljustify_s_s: " + "dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strljustify_s_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* + * corner case, a dmax of one allows only for a null + */ + if (*dest == '\0' || dmax <= RSIZE_MIN_STR) { + *dest = '\0'; + return (EOK); + } + + orig_dmax = dmax; + orig_dest = dest; + + /* + * scan the string to be sure it is properly terminated + */ + while (*dest) { + if (dmax == 0) { + while (orig_dmax) { *orig_dest++ = '\0'; orig_dmax--; } + + invoke_safe_str_constraint_handler( + "strljustify_s: dest is unterminated", + NULL, ESUNTERM); + return (ESUNTERM); + } + dmax--; + dest++; + } + + /* + * find first non-white space char + */ + dest = orig_dest; + while ((*dest == ' ') || (*dest == '\t')) { + dest++; + } + + /* + * shift text, removing spaces, to left justify + */ + if (orig_dest != dest && *dest) { + while (*dest) { + *orig_dest++ = *dest; + *dest++ = ' '; + } + *orig_dest = '\0'; + } + + return (EOK); +} +EXPORT_SYMBOL(strljustify_s) diff --git a/vendor/safestringlib/safeclib/strncat_s.c b/vendor/safestringlib/safeclib/strncat_s.c new file mode 100644 index 000000000..9b73da633 --- /dev/null +++ b/vendor/safestringlib/safeclib/strncat_s.c @@ -0,0 +1,265 @@ +/*------------------------------------------------------------------ + * strncat_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strncat_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strncat_s(char *dest, rsize_t dmax, const char *src, rsize_t slen) + * + * DESCRIPTION + * The strncat_s function appends a copy of the string pointed + * to by src (including the terminating null character) to the + * end of the string pointed to by dest. The initial character + * from src overwrites the null character at the end of dest. + * + * All elements following the terminating null character (if + * any) written by strncat_s in the array of dmax characters + * pointed to by dest take unspecified values when strncat_s returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be extended by src + * if dmax allows. The string is null terminated. + * If the resulting concatenated string is less + * than dmax, the remaining slack space is nulled. + * + * dmax restricted maximum length of the resulting dest, + * including the null + * + * src pointer to the string that will be concatenaed + * to string dest + * + * slen maximum characters to append + * + * OUTPUT PARAMETERS + * dest updated string + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer + * dmax shall not equal zero + * dmax shall not be greater than RSIZE_STR_MAX + * dmax shall be greater than strnlen_s(src,m). + * Copying shall not takeplace between objects that overlap + * If there is a runtime-constraint violation, then if dest is + * not a null pointer and dmax is greater than zero and not + * greater thanRSIZE_MAX, then strncat_s sets dest[0] to the + * null character. + * + * RETURN VALUE + * EOK successful operation, all the characters from src + * were appended to dest and the result in dest is + * null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESUNTERM dest not terminated + * + * + */ +errno_t +strncat_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strncat_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strncat_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (slen > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strncat_s: slen exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strncat_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strncat_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + /* Find the end of dest */ + while (*dest != '\0') { + + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strncat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + dest++; + dmax--; + if (dmax == 0) { + handle_error(orig_dest, orig_dmax, "strncat_s: " + "dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strncat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + /* + * Copying truncated before the source null is encountered + */ + if (slen == 0) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null remaining string */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + /* Find the end of dest */ + while (*dest != '\0') { + + /* + * NOTE: no need to check for overlap here since src comes first + * in memory and we're not incrementing src here. + */ + dest++; + dmax--; + if (dmax == 0) { + handle_error(orig_dest, orig_dmax, "strncat_s: " + "dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strncat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + /* + * Copying truncated + */ + if (slen == 0) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null remaining string */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + } + + /* + * the entire src was not copied, so the string will be nulled. + */ + handle_error(orig_dest, orig_dmax, "strncat_s: not enough " + "space for src", + ESNOSPC); + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(strncat_s) diff --git a/vendor/safestringlib/safeclib/strncpy_s.c b/vendor/safestringlib/safeclib/strncpy_s.c new file mode 100644 index 000000000..1fcdf6f56 --- /dev/null +++ b/vendor/safestringlib/safeclib/strncpy_s.c @@ -0,0 +1,238 @@ +/*------------------------------------------------------------------ + * strncpy_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/* + * NAME + * strncpy_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t slen) + * + * DESCRIPTION + * The strncpy_s function copies not more than slen successive characters + * (characters that follow a null character are not copied) from the + * array pointed to by src to the array pointed to by dest. If no null + * character was copied from src, then dest[n] is set to a null character. + * + * All elements following the terminating null character (if any) + * written by strncpy_s in the array of dmax characters pointed to + * by dest take on the null value when strncpy_s returns. + * + * Specicified in: + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * The resulting string is null terminated. + * + * dmax restricted maximum length of the resulting dest, + * including the null + * + * src pointer to the string that will be copied + * to string dest + * + * slen the maximum number of characters to copy from src + * + * OUTPUT PARAMETERS + * dest updated with src string + * + * RUNTIME CONSTRAINTS + * Neither dmax nor slen shall be equal to zero. + * Neither dmax nor slen shall be equal zero. + * Neither dmax nor slen shall be greater than RSIZE_MAX_STR. + * If slen is either greater than or equal to dmax, then dmax + * should be more than strnlen_s(src,dmax) + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and dmax greater than RSIZE_MAX_STR, + * then strncpy_s nulls dest. + * + * RETURN VALUE + * EOK successful operation, the characters in src were copied + * to dest and the result is null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * ESNOSPC not enough space to copy src + * + * ALSO SEE + * strcat_s(), strncat_s(), strcpy_s() + *- + */ +errno_t +strncpy_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) +{ + rsize_t orig_dmax; + char *orig_dest; + const char *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strncpy_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strncpy_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strncpy_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* hold base in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (src == NULL) { + handle_error(orig_dest, orig_dmax, "strncpy_s: " + "src is null", + ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (slen == 0) { + handle_error(orig_dest, orig_dmax, "strncpy_s: " + "slen is zero", + ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (slen > RSIZE_MAX_STR) { + handle_error(orig_dest, orig_dmax, "strncpy_s: " + "slen exceeds max", + ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strncpy_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + if (slen == 0) { + /* + * Copying truncated to slen chars. Note that the TR says to + * copy slen chars plus the null char. We null the slack. + */ +#ifdef SAFECLIB_STR_NULL_SLACK + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_error(orig_dest, orig_dmax, "strncpy_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + if (slen == 0) { + /* + * Copying truncated to slen chars. Note that the TR says to + * copy slen chars plus the null char. We null the slack. + */ +#ifdef SAFECLIB_STR_NULL_SLACK + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + } + + /* + * the entire src was not copied, so zero the string + */ + handle_error(orig_dest, orig_dmax, "strncpy_s: not enough " + "space for src", + ESNOSPC); + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(strncpy_s) diff --git a/vendor/safestringlib/safeclib/strnlen_s.c b/vendor/safestringlib/safeclib/strnlen_s.c new file mode 100644 index 000000000..659755106 --- /dev/null +++ b/vendor/safestringlib/safeclib/strnlen_s.c @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------ + * strnlen_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strnlen_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * rsize_t + * strnlen_s(const char *dest, rsize_t dmax) + * + * DESCRIPTION + * The strnlen_s function computes the length of the string pointed + * to by dest. + * + * SPECIFIED IN + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax restricted maximum length. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer + * dmax shall not be greater than RSIZE_MAX_STR + * dmax shall not equal zero + * + * RETURN VALUE + * The function returns the string length, excluding the terminating + * null character. If dest is NULL, then strnlen_s returns 0. + * + * Otherwise, the strnlen_s function returns the number of characters + * that precede the terminating null character. If there is no null + * character in the first dmax characters of dest then strnlen_s returns + * dmax. At most the first dmax characters of dest are accessed + * by strnlen_s. + * + * ALSO SEE + * strnterminate_s() + * + */ +rsize_t +strnlen_s (const char *dest, rsize_t dmax) +{ + rsize_t count; + + if (dest == NULL) { + return RCNEGATE(0); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strnlen_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(0); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strnlen_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(0); + } + + count = 0; + while (*dest && dmax) { + count++; + dmax--; + dest++; + } + + return RCNEGATE(count); +} +EXPORT_SYMBOL(strnlen_s) diff --git a/vendor/safestringlib/safeclib/strnterminate_s.c b/vendor/safestringlib/safeclib/strnterminate_s.c new file mode 100644 index 000000000..ab4f8d533 --- /dev/null +++ b/vendor/safestringlib/safeclib/strnterminate_s.c @@ -0,0 +1,113 @@ +/*------------------------------------------------------------------ + * strnterminate_s.c + * + * February 2011, Bo Berry + * + * Copyright (c) 2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strnterminate_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * rsize_t + * strnterminate_s(char *dest, rsize_t dmax) + * + * DESCRIPTION + * The strnterminate_s function will terminate the string if a + * null is not encountered before dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest - pointer to string + * + * dmax - restricted maximum length + * + * OUTPUT PARAMETERS + * dest - dest is terminated if needed + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer + * dmax shall not be greater than RSIZE_MAX_STR + * dmax shall not equal zero + * + * RETURN VALUE + * The function returns a terminated string. If a null is not + * encountered prior to dmax characters, the dmax character is + * set to null terminating the string. The string length is + * also returned. + * + * ALSO SEE + * strnlen_s() + * + */ +rsize_t +strnterminate_s (char *dest, rsize_t dmax) +{ + rsize_t count; + + if (dest == NULL) { + return (0); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strnterminate_s: dmax is 0", + NULL, ESZEROL); + return (0); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strnterminate_s: dmax exceeds max", + NULL, ESLEMAX); + return (0); + } + + count = 0; + while (dmax > 1) { + if (*dest) { + count++; + dmax--; + dest++; + } else { + break; + } + } + *dest = '\0'; + + return (count); +} +EXPORT_SYMBOL(strnterminate_s) diff --git a/vendor/safestringlib/safeclib/strpbrk_s.c b/vendor/safestringlib/safeclib/strpbrk_s.c new file mode 100644 index 000000000..ec7e2ee61 --- /dev/null +++ b/vendor/safestringlib/safeclib/strpbrk_s.c @@ -0,0 +1,163 @@ +/*------------------------------------------------------------------ + * strpbrk_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strpbrk_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strpbrk_s(char *dest, rsize_t dmax, + * char *src, rsize_t slen, char **first) + * + * DESCRIPTION + * Returns a pointer, first, to the first ocurrence of any character + * in src which is contained in dest. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax restricted maximum length of string dest + * + * src pointer to string + * + * slen restricted length of string src + * + * first returned pointer to first occurence + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * first shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * pointer to the first ocurrence of any character + * contained in src + * + * EOK count + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strfirstchar_s(), strlastchar_s(), strfirstdiff_s(), + * strfirstsame_s(), strlastdiff_s(), strlastsame_s() + * + */ +errno_t +strpbrk_s (char *dest, rsize_t dmax, + char *src, rsize_t slen, char **first) +{ + char *ps; + rsize_t len; + + if (first == NULL) { + invoke_safe_str_constraint_handler("strpbrk_s: count is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + *first = NULL; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strpbrk_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strpbrk_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strpbrk_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strpbrk_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (slen == 0 ) { + invoke_safe_str_constraint_handler("strpbrk_s: slen is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (slen > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strpbrk_s: slen exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* + * look for a matching char in the substring src + */ + while (*dest && dmax) { + + ps = src; + len = slen; + while (*ps) { + + /* check for a match with the substring */ + if (*dest == *ps) { + *first = dest; + return RCNEGATE(EOK); + } + ps++; + len--; + } + dest++; + dmax--; + } + + return RCNEGATE(ESNOTFND); +} +EXPORT_SYMBOL(strpbrk_s) diff --git a/vendor/safestringlib/safeclib/strprefix_s.c b/vendor/safestringlib/safeclib/strprefix_s.c new file mode 100644 index 000000000..fd34c1f97 --- /dev/null +++ b/vendor/safestringlib/safeclib/strprefix_s.c @@ -0,0 +1,128 @@ +/*------------------------------------------------------------------ + * strprefix_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strprefix_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strprefix_s(const char *dest, rsize_t dmax, const char *src) + * + * DESCRIPTION + * Determines if the prefix pointed to by src is at the + * beginning of string pointed to by dest. The prefix + * must be a complete match in dest. Useful for command + * or user input parsing. The scanning stops at the first + * null in dest or src, or after dmax characters. + * + * EXTENSION TO + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to compare against + * + * dmax restricted maximum length of dest + * + * src pointer to the prefix + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * EOK successful operation, prefix present in dest + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESNOTFND prefix not found in dest + * + * ALSO SEE + * strspn_s(), strcspn_s(), strpbrk_s(), strstr_s() + * + */ +errno_t +strprefix_s (const char *dest, rsize_t dmax, const char *src) +{ + if (dest == NULL) { + invoke_safe_str_constraint_handler("strprefix_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strprefix_s: src is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strprefix_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strprefix_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + if (*src == '\0') { + return (ESNOTFND); + } + + while (*src && dmax) { + + if (*dest != *src) { + return (ESNOTFND); + } + + dmax--; + dest++; + src++; + } + + return (EOK); +} +EXPORT_SYMBOL(strprefix_s) diff --git a/vendor/safestringlib/safeclib/strremovews_s.c b/vendor/safestringlib/safeclib/strremovews_s.c new file mode 100644 index 000000000..1779f79a3 --- /dev/null +++ b/vendor/safestringlib/safeclib/strremovews_s.c @@ -0,0 +1,164 @@ +/*------------------------------------------------------------------ + * strremovews_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights resevered. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strremovews_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strremovews_s(char *dest, rsize_t dmax) + * + * DESCRIPTION + * Removes beginning and trailing whitespace from the string pointed to by + * dest by shifting the text left over writting the beginning whitespace. + * The shifted-trimmed text is null terminated. + * + * The text is shifted so the original pointer can continue to be used. This + * is useful when the memory was malloc'ed and will need to be freed. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to remove whitespace + * + * dmax restricted maximum length of string + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * dest shall be null terminated + * + * RETURN VALUE + * EOK + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESUNTERM dest was not null terminated + * + * SEE ALSO + * strljustify_s(), + * + */ +errno_t +strremovews_s (char *dest, rsize_t dmax) +{ + char *orig_dest; + char *orig_end; + rsize_t orig_dmax; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strremovews_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strremovews_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strremovews_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* + * corner case, a dmax of one requires a null + */ + if (*dest == '\0' || dmax <= RSIZE_MIN_STR) { + *dest = '\0'; + return (EOK); + } + + orig_dest = dest; + orig_dmax = dmax; + + /* + * scan the string to be sure it is properly terminated + */ + while (*dest) { + if (dmax == 0) { + while (orig_dmax) { *orig_dest++ = '\0'; orig_dmax--; } + + invoke_safe_str_constraint_handler( + "strremovews_s: dest is unterminated", + NULL, ESUNTERM); + return (ESUNTERM); + } + dmax--; + dest++; + } + + /* + * find first non-white space char + */ + orig_end = dest-1; + dest = orig_dest; + while ((*dest == ' ') || (*dest == '\t')) { + dest++; + } + + /* + * shift the text over the leading spaces + */ + if (orig_dest != dest && *dest) { + while (*dest) { + *orig_dest++ = *dest; + *dest++ = ' '; + } + *dest = '\0'; + } + + /* + * strip trailing whitespace + */ + dest = orig_end; + while ((*dest == ' ') || (*dest == '\t')) { + *dest = '\0'; + dest--; + } + + return (EOK); +} +EXPORT_SYMBOL(strremovews_s) diff --git a/vendor/safestringlib/safeclib/strspn_s.c b/vendor/safestringlib/safeclib/strspn_s.c new file mode 100644 index 000000000..d75750353 --- /dev/null +++ b/vendor/safestringlib/safeclib/strspn_s.c @@ -0,0 +1,170 @@ +/*------------------------------------------------------------------ + * strspn_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strspn_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strspn_s(const char *dest, rsize_t dmax, + * const char *src, rsize_t slen, rsize_t *count) + * + * DESCRIPTION + * This function computes the prefix length of the string + * pointed to by dest which consists entirely of characters + * that are included from the string pointed to by src. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to determine the prefix + * + * dmax restricted maximum length of string dest + * + * src pointer to exclusion string + * + * slen restricted maximum length of string src + * + * count pointer to a count variable that will be updated + * with the dest substring length + * + * OUTPUT PARAMETERS + * count updated count + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * count shall not be a null pointer. + * dmax shall not be 0 + * dmax shall not be greater than RSIZE_MAX_STR + * + * RETURN VALUE + * EOK count + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strcspn_s(), strpbrk_s(), strstr_s(), strprefix_s() + * + */ +errno_t +strspn_s (const char *dest, rsize_t dmax, + const char *src, rsize_t slen, rsize_t *count) +{ + const char *scan2; + rsize_t smax; + bool match_found; + + if (count== NULL) { + invoke_safe_str_constraint_handler("strspn_s: count is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + *count = 0; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strspn_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strspn_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0 ) { + invoke_safe_str_constraint_handler("strspn_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strspn_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (slen == 0 ) { + invoke_safe_str_constraint_handler("strspn_s: slen is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (slen > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strspn_s: slen exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + while (*dest && dmax) { + + /* + * Scan the entire src string for each dest character, counting + * inclusions. + */ + match_found = false; + smax = slen; + scan2 = src; + while (*scan2 && smax) { + + if (*dest == *scan2) { + match_found = true; + break; + } + scan2++; + smax--; + } + + if (match_found) { + (*count)++; + } else { + break; + } + + dest++; + dmax--; + } + + return RCNEGATE(EOK); +} +EXPORT_SYMBOL(strspn_s) diff --git a/vendor/safestringlib/safeclib/strstr_s.c b/vendor/safestringlib/safeclib/strstr_s.c new file mode 100644 index 000000000..0dff4d465 --- /dev/null +++ b/vendor/safestringlib/safeclib/strstr_s.c @@ -0,0 +1,179 @@ +/*------------------------------------------------------------------ + * strstr_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strstr_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strstr_s(char *dest, rsize_t dmax, + * const char *src, rsize_t slen, char **substring) + * + * DESCRIPTION + * The strstr_s() function locates the first occurrence of the + * substring pointed to by src which would be located in the + * string pointed to by dest. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to be searched for the substring + * + * dmax restricted maximum length of dest string + * + * src pointer to the sub string + * + * slen the maximum number of characters to copy from src + * + * substring the returned substring pointer + * + * OUTPUT PARAMETERS + * substring returned substring pointer + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Meither dmax nor slen shall be zero. + * Neither dmax nor slen shall be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * EOK successful operation, substring found. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESNOTFND substring not found + * + * ALSO SEE + * strprefix_s(), strspn_s(), strcspn_s(), strpbrk_s() + * + */ +errno_t +strstr_s (char *dest, rsize_t dmax, + const char *src, rsize_t slen, char **substring) +{ + rsize_t len; + rsize_t dlen; + int i; + + if (substring == NULL) { + invoke_safe_str_constraint_handler("strstr_s: substring is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + *substring = NULL; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("strstr_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strstr_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strstr_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strstr_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (slen == 0) { + invoke_safe_str_constraint_handler("strstr_s: slen is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (slen > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strstr_s: slen exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* + * src points to a string with zero length, or + * src equals dest, return dest + */ + if (*src == '\0' || dest == src) { + *substring = dest; + return RCNEGATE(EOK); + } + + while (*dest && dmax) { + i = 0; + len = slen; + dlen = dmax; + + while (src[i] && dlen) { + + /* not a match, not a substring */ + if (dest[i] != src[i]) { + break; + } + + /* move to the next char */ + i++; + len--; + dlen--; + + if (src[i] == '\0' || !len) { + *substring = dest; + return RCNEGATE(EOK); + } + } + dest++; + dmax--; + } + + /* + * substring was not found, return NULL + */ + *substring = NULL; + return RCNEGATE(ESNOTFND); +} +EXPORT_SYMBOL(strstr_s) diff --git a/vendor/safestringlib/safeclib/strtok_s.c b/vendor/safestringlib/safeclib/strtok_s.c new file mode 100644 index 000000000..2b5f29a2f --- /dev/null +++ b/vendor/safestringlib/safeclib/strtok_s.c @@ -0,0 +1,325 @@ +/*------------------------------------------------------------------ + * strtok_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strtok_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * char * + * strtok_s(char *dest, rsize_t *dmax, char *src, char **ptr) + * + * DESCRIPTION + * A sequence of calls to the strtok_s function breaks the string + * pointed to by dest into a sequence of tokens, each of which is + * delimited by a character from the string pointed to by src. The + * fourth argument points to a caller-provided char pointer into + * which the strtok_s function stores information necessary for + * it to continue scanning the same string. + * + * The first call in a sequence has a non-null first argument and + * dmax points to an object whose value is the number of elements + * in the character array pointed to by the first argument. The + * first call stores an initial value in the object pointed to by + * ptr and updates the value pointed to by dmax to reflect the + * number of elements that remain in relation to ptr. Subsequent + * calls in the sequence have a null first argument and the objects + * pointed to by dmax and ptr are required to have the values + * stored by the previous call in the sequence, which are then + * updated. The separator string pointed to by src may be different + * from call to call. + * + * The first call in the sequence searches the string pointed to + * by dest for the first character that is not contained in the + * current separator string pointed to by src. If no such character + * is found, then there are no tokens in the string pointed to + * by dest and the strtok_s function returns a null pointer. If + * such a character is found, it is the start of the first token. + * + * The strtok_s function then searches from there for the first + * character in dest that is contained in the current separator + * string. If no such character is found, the current token + * extends to the end of the string pointed to by dest, and + * subsequent searches in the same string for a token return + * a null pointer. If such a character is found, it is + * overwritten by a null character, which terminates the + * current token. + * + * In all cases, the strtok_s function stores sufficient information + * in the pointer pointed to by ptr so that subsequent calls, + * with a null pointer for dest and the unmodified pointer value + * for ptr, shall start searching just past the element overwritten + * by a null character (if any). + * + * SPECIFIED IN + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string to tokenize + * + * dmax restricted maximum length of dest string + * + * src pointer to delimiter string (len < 255) + * + * ptr returned pointer to token + * + * OUTPUT PARAMETERS + * dmax update length + * + * ptr update pointer to token + * + * RUNTIME CONSTRAINTS + * src shall not be a null pointer. + * ptr shall not be a null pointer. + * dmax shall not be a null pointer. + * *dmax shall not be 0. + * + * If dest is a null pointer, then *ptr shall not be a null pointer. + * + * dest must not be unterminated. + * + * The value of *dmax shall not be greater than RSIZE_MAX_STR. The + * end of the token found shall occur within the first *dmax + * characters of dest for the first call, and shall occur within + * the first *dmax characters of where searching resumes on + * subsequent calls. + * + * RETURN VALUE + * The strtok_s function returns a pointer to the first character + * of a token; or a null pointer if there is no token or there + * is a runtime-constraint violation. + * + * EOK + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESUNTERM unterminated string + * + * EXAMPLES + * [1] Sequencial strtok_s() calls to tokenize a string + * + * String to tokenize str1 = ",.:*one,two;three,;four*.*.five-six***" + * len=38 + * String of delimiters str2 = ",.;*" + * + * p2tok = strtok_s(str1, &len, str2, &p2str); + * token -one- remaining -two;three,;four*.*.five-six***- len=30 + * + * p2tok = strtok_s(NULL, &len, str2, &p2str); + * token -two- remaining -three,;four*.*.five-six***- len=26 + * + * p2tok = strtok_s(NULL, &len, str2, &p2str); + * token -three- remaining -;four*.*.five-six***- len=20 + * + * p2tok = strtok_s(NULL, &len, str2, &p2str); + * token -four- remaining -.*.five-six***- len=14 + * + * p2tok = strtok_s(NULL, &len, str2, &p2str); + * token -five-six- remaining -**- len=2 + * + * p2tok = strtok_s(NULL, &len, str2, &p2str); + * token -(null)- remaining -**- len=0 + * + * + * [2] While loop with same entry data as [1] + * + * p2tok = str1; + * while (p2tok && len) { + * p2tok = strtok_s(NULL, &len, str2, &p2str); + * printf(" token -- remaining -- len=0 \n", + * p2tok, p2str, (int)len ); + * } + * + *- + */ +char * +strtok_s(char *dest, rsize_t *dmax, const char *src, char **ptr) +{ + +/* + * CONFIGURE: The spec does not call out a maximum for the src + * string, so one is defined here. + */ +#define STRTOK_DELIM_MAX_LEN ( 16 ) + + + const char *pt; + char *ptoken; + rsize_t dlen; + rsize_t slen; + + if (dmax == NULL) { + invoke_safe_str_constraint_handler("strtok_s: dmax is NULL", + NULL, ESNULLP); + return (NULL); + } + + if (*dmax == 0) { + invoke_safe_str_constraint_handler("strtok_s: dmax is 0", + NULL, ESZEROL); + return (NULL); + } + + if (*dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strtok_s: dmax exceeds max", + NULL, ESLEMAX); + return (NULL); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("strtok_s: src is null", + NULL, ESNULLP); + return (NULL); + } + + if (ptr == NULL) { + invoke_safe_str_constraint_handler("strtok_s: ptr is null", + NULL, ESNULLP); + return (NULL); + } + + /* if the source was NULL, use the tokenizer context */ + if (dest == NULL) { + dest = *ptr; + } + + /* + * scan dest for a delimiter + */ + dlen = *dmax; + ptoken = NULL; + while (*dest != '\0' && !ptoken) { + + if (dlen == 0) { + *ptr = NULL; + invoke_safe_str_constraint_handler( + "strtok_s: dest is unterminated", + NULL, ESUNTERM); + return (NULL); + } + + /* + * must scan the entire delimiter list + * ISO should have included a delimiter string limit!! + */ + slen = STRTOK_DELIM_MAX_LEN; + pt = src; + while (*pt != '\0') { + + if (slen == 0) { + *ptr = NULL; + invoke_safe_str_constraint_handler( + "strtok_s: src is unterminated", + NULL, ESUNTERM); + return (NULL); + } + slen--; + + if (*dest == *pt) { + ptoken = NULL; + break; + } else { + pt++; + ptoken = dest; + } + } + dest++; + dlen--; + } + + /* + * if the beginning of a token was not found, then no + * need to continue the scan. + */ + if (ptoken == NULL) { + *dmax = dlen; + return (ptoken); + } + + /* + * Now we need to locate the end of the token + */ + while (*dest != '\0') { + + if (dlen == 0) { + *ptr = NULL; + invoke_safe_str_constraint_handler( + "strtok_s: dest is unterminated", + NULL, ESUNTERM); + return (NULL); + } + + slen = STRTOK_DELIM_MAX_LEN; + pt = src; + while (*pt != '\0') { + + if (slen == 0) { + *ptr = NULL; + invoke_safe_str_constraint_handler( + "strtok_s: src is unterminated", + NULL, ESUNTERM); + return (NULL); + } + slen--; + + if (*dest == *pt) { + /* + * found a delimiter, set to null + * and return context ptr to next char + */ + *dest = '\0'; + *ptr = (dest + 1); /* return pointer for next scan */ + *dmax = dlen - 1; /* account for the nulled delimiter */ + return (ptoken); + } else { + /* + * simply scanning through the delimiter string + */ + pt++; + } + } + dest++; + dlen--; + } + + *dmax = dlen; + return (ptoken); +} +EXPORT_SYMBOL(strtok_s) + diff --git a/vendor/safestringlib/safeclib/strtolowercase_s.c b/vendor/safestringlib/safeclib/strtolowercase_s.c new file mode 100644 index 000000000..20bd3ec4e --- /dev/null +++ b/vendor/safestringlib/safeclib/strtolowercase_s.c @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------ + * strtolowercase_s.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strtolowercase_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strlolowercase_s(char *dest, rsize_t dmax) + * + * DESCRIPTION + * Scans the string converting uppercase characters to + * lowercase, leaving all other characters unchanged. + * The scanning stops at the first null or after dmax + * characters. + * + * Extenstion to: + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * dest updated string + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strtouppercase_s() + * + */ +errno_t +strtolowercase_s (char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strtolowercase_s: " + "dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strtolowercase_s: " + "dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strtolowercase_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + while (*dest && dmax) { + + if ( (*dest >= 'A') && (*dest <= 'Z')) { + *dest = (char)(*dest + (char)32); + } + dest++; + dmax--; + } + + return (EOK); +} +EXPORT_SYMBOL(strtolowercase_s) diff --git a/vendor/safestringlib/safeclib/strtouppercase_s.c b/vendor/safestringlib/safeclib/strtouppercase_s.c new file mode 100644 index 000000000..d00fe8d4d --- /dev/null +++ b/vendor/safestringlib/safeclib/strtouppercase_s.c @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------ + * safe_str_touppercase.c + * + * November 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strtouppercase_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strlouppercase_s(char *dest, rsize_t dmax) + * + * DESCRIPTION + * Scans the string converting lowercase characters to + * uppercase, leaving all other characters unchanged. + * The scanning stops at the first null or after dmax + * characters. + * + * Extenstion to: + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string + * + * dmax maximum length of string + * + * OUTPUT PARAMETERS + * dest updated string + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * dmax shall not equal zero. + * dmax shall not be greater than RSIZE_MAX_STR. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strtolowercase_s() + * + */ +errno_t +strtouppercase_s (char *dest, rsize_t dmax) +{ + if (!dest) { + invoke_safe_str_constraint_handler("strtouppercase_s: " + "dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strtouppercase_s: " + "dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strtouppercase_s: " + "dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + while (*dest && dmax) { + + if ((*dest >= 'a') && (*dest <= 'z')) { + *dest = (char)(*dest - 32); + } + dest++; + dmax--; + } + + return (EOK); +} +EXPORT_SYMBOL(strtouppercase_s) diff --git a/vendor/safestringlib/safeclib/strzero_s.c b/vendor/safestringlib/safeclib/strzero_s.c new file mode 100644 index 000000000..7496e7046 --- /dev/null +++ b/vendor/safestringlib/safeclib/strzero_s.c @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------ + * strzero_s.c + * + * October 2008, Bo Berry + * + * Copyright (c) 2008-2011 by Cisco Systems, Inc + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * strzero_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * strzero_s(char *dest, rsize_t dmax) + * + * DESCRIPTION + * Nulls dmax characters of dest. This function can be used + * to clear strings that contained sensitive data. + * + * EXTENSION TO + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be nulled. + * + * dmax restricted maximum length of dest + * + * OUTPUT PARAMETERS + * dest updated string + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * strispassword_s() + * + */ +errno_t +strzero_s (char *dest, rsize_t dmax) +{ + if (dest == NULL) { + invoke_safe_str_constraint_handler("strzero_s: dest is null", + NULL, ESNULLP); + return (ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("strzero_s: dmax is 0", + NULL, ESZEROL); + return (ESZEROL); + } + + if (dmax > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("strzero_s: dmax exceeds max", + NULL, ESLEMAX); + return (ESLEMAX); + } + + /* null string to eliminate data */ + while (dmax) { + *dest = '\0'; + dmax--; + dest++; + } + + return (EOK); +} +EXPORT_SYMBOL(strzero_s) diff --git a/vendor/safestringlib/safeclib/wcpcpy_s.c b/vendor/safestringlib/safeclib/wcpcpy_s.c new file mode 100644 index 000000000..d388dc6de --- /dev/null +++ b/vendor/safestringlib/safeclib/wcpcpy_s.c @@ -0,0 +1,219 @@ +/*------------------------------------------------------------------ + * wcpcpy_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * wcpcpy_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * wchar_t * + * wcpcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, errno_t *err) + * + * DESCRIPTION + * The wcpcpy_s function copies the wide character string pointed + * to by src (including the terminating null character) into the + * array pointed to by dest, and returns a pointer to the end of + * the wide character string. All elements following the terminating + * null character (if any) written by wcpcpy_s in the array of + * dmax characters pointed to by dest are nulled when + * wcpcpy_s returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * + * dmax restricted maximum length of dest + * + * src pointer to the wide character string that will be copied + * to dest + * + * err the error code upon error, or EOK if successful + * + * OUTPUT PARAMETERS + * dest updated + * err updated as follows: + * EOK successful operation, the characters in src were + * copied into dest and the result is null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * ESNOSPC not enough space to copy src + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not be greater than RSIZE_MAX_STR. + * dmax shall not equal zero. + * dmax shall be greater than strnlen_s(src, dmax). + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and destmax is greater than zero and + * not greater than RSIZE_MAX_STR, then strcpy_s nulls dest. + * + * RETURN VALUE + * a wchar_t pointer to the terminating null at the end of dest + * + * ALSO SEE + * wcscpy_s(), wcscat_s(), wcsncat_s(), wcsncpy_s() + * strcpy_s, strcat_s(), strncat_s(), strncpy_s() + * + */ +wchar_t * +wcpcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, errno_t *err) +{ + rsize_t orig_dmax; + wchar_t *orig_dest; + const wchar_t *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("wcpcpy_s: dest is null", + NULL, ESNULLP); + *err = RCNEGATE(ESNULLP); + return NULL; + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("wcpcpy_s: dmax is 0", + NULL, ESZEROL); + *err = RCNEGATE(ESZEROL); + return NULL; + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcpcpy_s: dmax exceeds max", + NULL, ESLEMAX); + *err = RCNEGATE(ESLEMAX); + return NULL; + } + + if (src == NULL) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to clear data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#else + *dest = L'\0'; +#endif + invoke_safe_str_constraint_handler("wcpcpy_s: src is null", + NULL, ESNULLP); + *err = RCNEGATE(ESNULLP); + return NULL; + } + + if (dest == src) { + /* move dest to the end of the string */ + while (dmax && (*dest != L'\0')) { dmax--; dest++; } + if ( *dest != L'\0' ) { + invoke_safe_str_constraint_handler("wcpcpy_s: no null terminator in dest", + NULL, ESLEMAX); + *err = RCNEGATE(ESLEMAX); + return NULL; + } + *err = RCNEGATE(EOK); + return dest; + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcpcpy_s: overlapping objects", + ESOVRLP); + *err = RCNEGATE(ESOVRLP); + return NULL; + } + + *dest = *src; + if (*dest == L'\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#endif + *err = RCNEGATE(EOK); + return dest; /* successful return */ + } + + dmax--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcpcpy_s: overlapping objects", + ESOVRLP); + *err = RCNEGATE(ESOVRLP); + return NULL; + } + + *dest = *src; + if (*dest == L'\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#endif + *err = RCNEGATE(EOK); + return dest; /* successful return */ + } + + dmax--; + dest++; + src++; + } + } + + /* + * the entire src must have been copied, if not reset dest + * to null the string. + */ + handle_wc_error(orig_dest, orig_dmax, "wcpcpy_s: not enough space for src", + ESNOSPC); + *err = RCNEGATE(ESNOSPC); + return NULL; +} +EXPORT_SYMBOL(wcpcpy_s) diff --git a/vendor/safestringlib/safeclib/wcscat_s.c b/vendor/safestringlib/safeclib/wcscat_s.c new file mode 100644 index 000000000..19363dfda --- /dev/null +++ b/vendor/safestringlib/safeclib/wcscat_s.c @@ -0,0 +1,226 @@ +/*------------------------------------------------------------------ + * wcscat_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * wcscat_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * wcscat_s(wchar_t* dest, rsize_t dmax, const wchar_t* src) + * + * DESCRIPTION + * The wcscat_s function appends a copy of the wide character string pointed + * to by src (including the terminating null character) to the + * end of the string pointed to by dest. The initial wide character + * from src overwrites the null character at the end of dest. + * + * All elements following the terminating null character (if + * any) written by strcat_s in the array of dmax characters + * pointed to by dest take unspecified values when strcat_s + * returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to wide character string that will be extended by src + * if dmax allows. The string is null terminated. + * If the resulting concatenated string is less + * than dmax, the remaining slack space is nulled. + * + * dmax restricted maximum length of the resulting dest, + * including the null + * + * src pointer to the string that will be concatenaed + * to string dest + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer + * dmax shall not equal zero + * dmax shall not be greater than RSIZE_MAX_STR + * dmax shall be greater than strnlen_s(src,m). + * Copying shall not takeplace between objects that overlap + * If there is a runtime-constraint violation, then if dest is + * not a null pointer and dmax is greater than zero and not + * greater than RSIZE_MAX_STR, then strcat_s nulls dest. + * + * RETURN VALUE + * EOK successful operation, all the characters from src + * were appended to dest and the result in dest is + * null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max + * ESUNTERM dest not terminated + * + * ALSO SEE + * strcat_s, strncat_s(), strcpy_s(), strncpy_s() + * + */ +errno_t +wcscat_s(wchar_t* dest, rsize_t dmax, const wchar_t* src) +{ + rsize_t orig_dmax; + wchar_t *orig_dest; + const wchar_t *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("wcscat_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("wcscat_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("wcscat_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcscat_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + /* Find the end of dest */ + while (*dest != L'\0') { + + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcscat_s: overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + dest++; + dmax--; + if (dmax == 0) { + handle_wc_error(orig_dest, orig_dmax, "wcscat_s: dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcscat_s: overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == L'\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + /* Find the end of dest */ + while (*dest != L'\0') { + + /* + * NOTE: no need to check for overlap here since src comes first + * in memory and we're not incrementing src here. + */ + dest++; + dmax--; + if (dmax == 0) { + handle_wc_error(orig_dest, orig_dmax, "wcscat_s: dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcscat_s: overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == L'\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + } + + /* + * the entire src was not copied, so null the string + */ + handle_wc_error(orig_dest, orig_dmax, "wcscat_s: not enough space for src", + ESNOSPC); + + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(wcscat_s) diff --git a/vendor/safestringlib/safeclib/wcscpy_s.c b/vendor/safestringlib/safeclib/wcscpy_s.c new file mode 100644 index 000000000..64aad6116 --- /dev/null +++ b/vendor/safestringlib/safeclib/wcscpy_s.c @@ -0,0 +1,207 @@ +/*------------------------------------------------------------------ + * wcscpy_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * wcscpy_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * wcscpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src) + * + * DESCRIPTION + * The wcscpy_s function copies the wide character string pointed + * to by src (including the terminating null character) into the + * array pointed to by dest. All elements following the terminating + * null character (if any) written by strcpy_s in the array of + * dmax characters pointed to by dest are nulled when + * wcscpy_s returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * + * dmax restricted maximum length of dest + * + * src pointer to the wide character string that will be copied + * to dest + * + * OUTPUT PARAMETERS + * dest updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * dmax shall not be greater than RSIZE_MAX_STR. + * dmax shall not equal zero. + * dmax shall be greater than strnlen_s(src, dmax). + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and destmax is greater than zero and + * not greater than RSIZE_MAX_STR, then strcpy_s nulls dest. + * + * RETURN VALUE + * EOK successful operation, the characters in src were + * copied into dest and the result is null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * ESNOSPC not enough space to copy src + * + * ALSO SEE + * strcpy_s, strcat_s(), strncat_s(), strncpy_s() + * wcscat_s(), + * + */ +errno_t +wcscpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src) +{ + rsize_t orig_dmax; + wchar_t *orig_dest; + const wchar_t *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("wcscpy_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("wcscpy_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcscpy_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (src == NULL) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null string to clear data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + invoke_safe_str_constraint_handler("wcscpy_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + /* Verify proper length according to dmax if src = dest */ + if (dest == src) { + /* Ensure that src is not longer than dmax */ + while (*src != L'\0' && (dmax != 0)) { src++; dmax--; } + if ( *src != L'\0' ) { + invoke_safe_str_constraint_handler("wcscpy_s: src exceeds dmax", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + return RCNEGATE(EOK); + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcscpy_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcscpy_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + dest++; + src++; + } + } + + /* + * the entire src must have been copied, if not reset dest + * to null the string. + */ + handle_wc_error(orig_dest, orig_dmax, "wcscpy_s: not " + "enough space for src", + ESNOSPC); + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(wcscpy_s) diff --git a/vendor/safestringlib/safeclib/wcsncat_s.c b/vendor/safestringlib/safeclib/wcsncat_s.c new file mode 100644 index 000000000..73596cd71 --- /dev/null +++ b/vendor/safestringlib/safeclib/wcsncat_s.c @@ -0,0 +1,269 @@ +/*------------------------------------------------------------------ + * wcsncat_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * wcsncat_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * wcsncat_s(wchar_t *dest, rsize_t dmax, const wchar_t *src, rsize_t slen) + * + * DESCRIPTION + * The wcsncat_s function appends a copy of (at most) the + * first slen wide characters pointed to by src to the + * end of the string pointed to by dest and terminates the + * string with the null character. If less than slen wide + * characters are in the string src, the function stops + * copying after the null terminator is copied to dest. + * The initial character from src overwrites the null + * character at the end of dest. + * + * All elements following the terminating null character (if + * any) written by strncat_s in the array of dmax characters + * pointed to by dest take unspecified values when strncat_s returns. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be extended by src + * if dmax allows. The string is null terminated. + * If the resulting concatenated string is less + * than dmax, the remaining slack space is nulled. + * + * dmax restricted maximum length of the resulting dest, + * including the null + * + * src pointer to the string that will be concatenaed + * to string dest + * + * slen maximum characters to append + * + * OUTPUT PARAMETERS + * dest updated string + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer + * dmax shall not equal zero + * dmax shall not be greater than RSIZE_STR_MAX + * dmax shall be greater than strnlen_s(src,m). + * Copying shall not takeplace between objects that overlap + * If there is a runtime-constraint violation, then if dest is + * not a null pointer and dmax is greater than zero and not + * greater thanRSIZE_MAX, then strncat_s sets dest[0] to the + * null character. + * + * RETURN VALUE + * EOK successful operation, all the characters from src + * were appended to dest and the result in dest is + * null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESUNTERM dest not terminated + * + * + */ +errno_t +wcsncat_s (wchar_t *dest, rsize_t dmax, const wchar_t *src, rsize_t slen) +{ + rsize_t orig_dmax; + wchar_t *orig_dest; + const wchar_t *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("wcsncat_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (src == NULL) { + invoke_safe_str_constraint_handler("wcsncat_s: src is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (slen*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcsncat_s: slen exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("wcsncat_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcsncat_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* hold base of dest in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (dest < src) { + overlap_bumper = src; + + /* Find the end of dest */ + while (*dest != L'\0') { + + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcsncat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + dest++; + dmax--; + if (dmax == 0) { + handle_wc_error(orig_dest, orig_dmax, "wcsncat_s: " + "dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcsncat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + /* + * Copying truncated before the source null is encountered + */ + /* TODO: test if this copies at most slen characters including NULL */ + if (slen == 0) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null remaining string */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#else + *dest = L'\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == L'\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + /* Find the end of dest */ + while (*dest != L'\0') { + + /* + * NOTE: no need to check for overlap here since src comes first + * in memory and we're not incrementing src here. + */ + dest++; + dmax--; + if (dmax == 0) { + handle_wc_error(orig_dest, orig_dmax, "wcsncat_s: " + "dest unterminated", + ESUNTERM); + return RCNEGATE(ESUNTERM); + } + } + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcsncat_s: " + "overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + /* + * Copying truncated + */ + if (slen == 0) { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null remaining string */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#else + *dest = L'\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == L'\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack to clear any data */ + while (dmax) { *dest = L'\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + } + + /* + * the entire src was not copied, so the string will be nulled. + */ + handle_wc_error(orig_dest, orig_dmax, "wcsncat_s: not enough space for src", + ESNOSPC); + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(wcsncat_s) diff --git a/vendor/safestringlib/safeclib/wcsncpy_s.c b/vendor/safestringlib/safeclib/wcsncpy_s.c new file mode 100644 index 000000000..67ddda10b --- /dev/null +++ b/vendor/safestringlib/safeclib/wcsncpy_s.c @@ -0,0 +1,241 @@ +/*------------------------------------------------------------------ + * wcsncpy_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/* + * NAME + * wcsncpy_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * errno_t + * wcsncpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t slen) + * + * DESCRIPTION + * The wcsncpy_s function copies not more than slen successive characters + * (characters that follow a null character are not copied) from the + * array pointed to by src to the array pointed to by dest. If no null + * character was copied from src, then dest[slen] is set to a null character. + * + * All elements following the terminating null character (if any) + * written by wcsncpy_s in the array of dmax characters pointed to + * by dest take on the null value when wcsncpy_s returns. + * + * When SAFECLIB_STR_NULL_SLACK is defined to be true (#DEFINE), then + * the dest array is filled with NULL characters following the end of + * the last non-NULL character from src. While this is more secure, it + * is also incurs a performance penalty, especially when the same dest + * array is used multiple times to string manipulation routines in this + * library. If this extra security is not required, ensure that the + * library is compiled without #DEFINE SAFECLIB_STR_NULL_SLACK. + * + * Specicified in: + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to string that will be replaced by src. + * The resulting string is null terminated. + * + * dmax restricted maximum length of the resulting dest, + * including the null + * + * src pointer to the string that will be copied + * to string dest + * + * slen the maximum number of characters to copy from src + * + * OUTPUT PARAMETERS + * dest updated with src string + * + * RUNTIME CONSTRAINTS + * Neither dmax nor slen shall be equal to zero. + * Neither dmax nor slen shall be equal zero. + * Neither dmax nor slen shall be greater than RSIZE_MAX_STR. + * If slen is either greater than or equal to dmax, then dmax + * should be more than strnlen_s(src,dmax) + * Copying shall not take place between objects that overlap. + * If there is a runtime-constraint violation, then if dest + * is not a null pointer and dmax greater than RSIZE_MAX_STR, + * then strncpy_s nulls dest. + * + * RETURN VALUE + * EOK successful operation, the characters in src were copied + * to dest and the result is null terminated. + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP strings overlap + * ESNOSPC not enough space to copy src + * + * ALSO SEE + * strcat_s(), strncat_s(), strcpy_s() + * wcscat_s(), wcsncat_s(), wcscpy_s() + *- + */ +errno_t +wcsncpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t slen) +{ + rsize_t orig_dmax; + wchar_t *orig_dest; + const wchar_t *overlap_bumper; + + if (dest == NULL) { + invoke_safe_str_constraint_handler("wcsncpy_s: dest is null", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("wcsncpy_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcsncpy_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + /* hold base in case src was not copied */ + orig_dmax = dmax; + orig_dest = dest; + + if (src == NULL) { + handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: src is null", + ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (slen == 0) { + handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: slen is zero", + ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (slen*sizeof(wchar_t) > RSIZE_MAX_STR) { + handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: slen exceeds max", + ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + + if (dest < src) { + overlap_bumper = src; + + while (dmax > 0) { + if (dest == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + if (slen == 0) { + /* + * Copying truncated to slen chars. Note that the TR says to + * copy slen chars plus the null char. We null the slack. + */ +#ifdef SAFECLIB_STR_NULL_SLACK + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + + } else { + overlap_bumper = dest; + + while (dmax > 0) { + if (src == overlap_bumper) { + handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: overlapping objects", + ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + if (slen == 0) { + /* + * Copying truncated to slen chars. Note that the TR says to + * copy slen chars plus the null char. We null the slack. + */ +#ifdef SAFECLIB_STR_NULL_SLACK + while (dmax) { *dest = '\0'; dmax--; dest++; } +#else + *dest = '\0'; +#endif + return RCNEGATE(EOK); + } + + *dest = *src; + if (*dest == '\0') { +#ifdef SAFECLIB_STR_NULL_SLACK + /* null slack */ + while (dmax) { *dest = '\0'; dmax--; dest++; } +#endif + return RCNEGATE(EOK); + } + + dmax--; + slen--; + dest++; + src++; + } + } + + /* + * the entire src was not copied, so zero the string + */ + handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: not enough space for src", + ESNOSPC); + return RCNEGATE(ESNOSPC); +} +EXPORT_SYMBOL(wcsncpy_s) diff --git a/vendor/safestringlib/safeclib/wcsnlen_s.c b/vendor/safestringlib/safeclib/wcsnlen_s.c new file mode 100644 index 000000000..564af51cc --- /dev/null +++ b/vendor/safestringlib/safeclib/wcsnlen_s.c @@ -0,0 +1,113 @@ +/*------------------------------------------------------------------ + * wcsnlen_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 by Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_str_constraint.h" +#include "safe_str_lib.h" + + +/** + * NAME + * wcsnlen_s + * + * SYNOPSIS + * #include "safe_str_lib.h" + * rsize_t + * wcsnlen_s(const wchar_t *dest, rsize_t dmax) + * + * DESCRIPTION + * The wcsnlen_s function computes the length of the wide character string pointed + * to by dest. + * + * SPECIFIED IN + * ISO/IEC TR 24731-1, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to wide character string + * + * dmax restricted maximum length. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer + * dmax shall not be greater than RSIZE_MAX_STR + * dmax shall not equal zero + * + * RETURN VALUE + * The function returns the number of wide characters in the string + * pointed to by dest, excluding the terminating null character. + * If dest is NULL, then wcsnlen_s returns 0. + * + * Otherwise, the wcsnlen_s function returns the number of wide characters + * that precede the terminating null character. If there is no null + * character in the first dmax characters of dest then wcsnlen_s returns + * dmax. At most the first dmax characters of dest are accessed + * by wcsnlen_s. + * + * ALSO SEE + * strnlen_s, strnterminate_s() + * + */ +rsize_t +wcsnlen_s (const wchar_t *dest, rsize_t dmax) +{ + rsize_t count; + + if (dest == NULL) { + return RCNEGATE(0); + } + + if (dmax == 0) { + invoke_safe_str_constraint_handler("wcsnlen_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(0); + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + invoke_safe_str_constraint_handler("wcsnlen_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(0); + } + + count = 0; + while (*dest && dmax) { + count++; + dmax--; + dest++; + } + + return RCNEGATE(count); +} +EXPORT_SYMBOL(wcsnlen_s) diff --git a/vendor/safestringlib/safeclib/wmemcmp_s.c b/vendor/safestringlib/safeclib/wmemcmp_s.c new file mode 100644 index 000000000..5438e7008 --- /dev/null +++ b/vendor/safestringlib/safeclib/wmemcmp_s.c @@ -0,0 +1,169 @@ +/*------------------------------------------------------------------ + * wmemcmp_s.c - Compares memory + * + * September 2014, D. Wheeler + * + * Copyright (c) 2014 Intel Corp + * All rights reserved. + * + * Based on memcmp32_s.c, October 2008, by Bo Berry + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "safe_mem_lib.h" + +/** + * NAME + * wmemcmp_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * wmemcmp_s(const wchar_t *dest, rsize_t dmax, + * const wchar_t *src, rsize_t smax, int *diff) + * + * DESCRIPTION + * Compares wide-character strings until they differ, and their difference is + * returned in diff. If the wide character string is the same, diff=0. + * + * EXTENSION TO + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory to compare against + * + * dmax maximum length of dest, in uint32_t + * + * src pointer to the source memory to compare with dest + * + * smax maximum length of src, in uint32_t + * + * *diff pointer to the diff which is an integer greater + * than, equal to or less than zero according to + * whether the object pointed to by dest is + * greater than, equal to or less than the object + * pointed to by src. + * + * OUTPUT PARAMETERS + * none + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be zero. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memcmp_s(), memcmp16_s() + * + */ +errno_t +wmemcmp_s (const wchar_t *dest, rsize_t dmax, + const wchar_t *src, rsize_t smax, int *diff) +{ + /* + * must be able to return the diff + */ + if (diff == NULL) { + invoke_safe_mem_constraint_handler("wmemcmp_s: diff is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + *diff = -1; /* default diff */ + + + if (dest == NULL) { + invoke_safe_mem_constraint_handler("wmemcmp_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (src == NULL) { + invoke_safe_mem_constraint_handler("wmemcmp_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("wmemcmp_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax > RSIZE_MAX_MEM32) { + invoke_safe_mem_constraint_handler("wmemcmp_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + invoke_safe_mem_constraint_handler("wmemcmp_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + invoke_safe_mem_constraint_handler("wmemcmp_s: smax exceeds dmax", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + /* + * no need to compare the same memory + */ + if (dest == src) { + *diff = 0; + return (RCNEGATE(EOK)); + } + + /* + * now compare src to dest + */ + *diff = 0; + while (dmax != 0 && smax != 0) { + if (*dest != *src) { + *diff = *dest - *src; + break; + } + + dmax--; + smax--; + + dest++; + src++; + } + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(wmemcmp_s) diff --git a/vendor/safestringlib/safeclib/wmemcpy_s.c b/vendor/safestringlib/safeclib/wmemcpy_s.c new file mode 100644 index 000000000..b14013265 --- /dev/null +++ b/vendor/safestringlib/safeclib/wmemcpy_s.c @@ -0,0 +1,158 @@ +/*------------------------------------------------------------------ + * wmemcpy_s + * + * AUgust 2014, D. Wheeler + * + * Copyright (c) 2014 Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" +#include + + +/** + * NAME + * wmemcpy_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * wmemcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t smax) + * + * DESCRIPTION + * This function copies at most smax wide characters from src to dest, up to + * dmax. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be replaced by src. + * + * dmax maximum length of the resulting dest + * + * src pointer to the memory that will be copied to dest + * + * smax maximum number bytes of src to copy + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be zero. + * dmax shall not be greater than RSIZE_MAX_MEM. + * smax shall not be greater than dmax. + * Copying shall not take place between regions that overlap. + * If there is a runtime-constraint violation, the memcpy_s function + * stores zeros in the first dmax bytes of the region pointed to + * by dest if dest is not a null pointer and smax is valid. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * ESOVRLP source memory overlaps destination + * + * ALSO SEE + * memcpy16_s(), memcpy32_s(), memcpy_s(), + * wmemmove_s(), memmove_s(), memmove16_s(), memmove32_s(), + * + */ +errno_t +wmemcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t smax) +{ + wchar_t *dp; + const wchar_t *sp; + + dp = dest; + sp = src; + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("wmemcpy_s: dest is NULL", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("wmemcpy_s: dmax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (dmax > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("wmemcpy_s: dmax exceeds max", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (smax == 0) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemcpy_s: smax is 0", + NULL, ESZEROL); + return RCNEGATE(ESZEROL); + } + + if (smax > dmax) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemcpy_s: smax exceeds dmax", + NULL, ESLEMAX); + return RCNEGATE(ESLEMAX); + } + + if (sp == NULL) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemcpy_s: src is NULL", + NULL, ESNULLP); + return RCNEGATE(ESNULLP); + } + + + /* + * overlap is undefined behavior, do not allow + */ + if( ((dp > sp) && (dp < (sp+smax))) || + ((sp > dp) && (sp < (dp+dmax))) ) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemcpy_s: overlap undefined", + NULL, ESOVRLP); + return RCNEGATE(ESOVRLP); + } + + /* + * now perform the copy + */ + mem_prim_move(dp, sp, smax*sizeof(wchar_t)); + + return RCNEGATE(EOK); +} +EXPORT_SYMBOL(wmemcpy_s) diff --git a/vendor/safestringlib/safeclib/wmemmove_s.c b/vendor/safestringlib/safeclib/wmemmove_s.c new file mode 100644 index 000000000..56d3dd6c6 --- /dev/null +++ b/vendor/safestringlib/safeclib/wmemmove_s.c @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------ + * wmemmove_s.c + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" +#include + +/** + * NAME + * wmemmove_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * wmemmove_s(wchar_t* dest, rsize_t dmax, + * const wchar_t* src, size_t smax) + * + * DESCRIPTION + * The wmemmove_s function copies smax wide characters from the region pointed + * to by src into the region pointed to by dest. This copying takes place + * as if the smax wide characters from the region pointed to by src are first copied + * into a temporary array of smax bytes that does not overlap the region + * pointed to by dest or src, and then the smax bytes from the temporary + * array are copied into the object region to by dest. + * + * SPECIFIED IN + * ISO/IEC TR 24731, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to the memory that will be replaced by src. + * + * dmax maximum number of resulting wide characters in dest + * + * src pointer to the memory that will be copied + * to dest + * + * smax maximum number wide characters of src that can be copied + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * Neither dest nor src shall be a null pointer. + * Neither dmax nor smax shall be 0. + * dmax shall not be greater than RSIZE_MAX_MEM/sizeof(wchar_t). + * smax shall not be greater than dmax. + * If there is a runtime-constraint violation, the wmemmove_s function + * stores zeros in the first dmax characters of the region pointed to + * by dest if dest is not a null pointer and dmax is not greater + * than RSIZE_MAX_MEM/sizeof(wchar_t). + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memmove16_s(), memmove32_s(), memcpy_s(), memcpy16_s() memcpy32_s() + * wmemcpy_s() + * + */ +errno_t +wmemmove_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, size_t smax) +{ + wchar_t *dp; + const wchar_t *sp; + + dp= dest; + sp = src; + + if (dp == NULL) { + invoke_safe_mem_constraint_handler("wmemmove_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (dmax == 0) { + invoke_safe_mem_constraint_handler("wmemmove_s: dmax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (dmax*sizeof(wchar_t) > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("wmemmove_s: dmax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (smax == 0) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemmove_s: smax is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (smax > dmax) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemmove_s: smax exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + if (sp == NULL) { + mem_prim_set(dp, dmax*sizeof(wchar_t), 0); + invoke_safe_mem_constraint_handler("wmemmove_s: src is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + /* + * now perform the copy + */ + mem_prim_move(dp, sp, smax*sizeof(wchar_t)); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(wmemmove_s) diff --git a/vendor/safestringlib/safeclib/wmemset_s.c b/vendor/safestringlib/safeclib/wmemset_s.c new file mode 100644 index 000000000..335058408 --- /dev/null +++ b/vendor/safestringlib/safeclib/wmemset_s.c @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------ + * wmemset_s + * + * August 2014, D Wheeler + * + * Copyright (c) 2014 Intel Corp + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + *------------------------------------------------------------------ + */ + +#include "safeclib_private.h" +#include "safe_mem_constraint.h" +#include "mem_primitives_lib.h" +#include "safe_mem_lib.h" + + +/** + * NAME + * wmemset_s + * + * SYNOPSIS + * #include "safe_mem_lib.h" + * errno_t + * wmemset_s(wchar_t *dest, wchar_t value, rsize_t len) + * + * DESCRIPTION + * Sets len number of wide characters starting at dest to the specified value. + * + * SPECIFIED IN + * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments + * and system software interfaces, Extensions to the C Library, + * Part I: Bounds-checking interfaces + * + * INPUT PARAMETERS + * dest pointer to memory that will be set to the value + * + * value byte value + * + * len number of wide characters to be set + * + * OUTPUT PARAMETERS + * dest is updated + * + * RUNTIME CONSTRAINTS + * dest shall not be a null pointer. + * len shall not be 0 nor greater than RSIZE_MAX_MEM/sizeof(wchar_t). + * If there is a runtime constraint, the operation is not performed. + * + * RETURN VALUE + * EOK successful operation + * ESNULLP NULL pointer + * ESZEROL zero length + * ESLEMAX length exceeds max limit + * + * ALSO SEE + * memset_s, memset16_s(), memset32_s() + * + */ +errno_t +wmemset_s (wchar_t *dest, wchar_t value, rsize_t len) +{ + if (dest == NULL) { + invoke_safe_mem_constraint_handler("wmemset_s: dest is null", + NULL, ESNULLP); + return (RCNEGATE(ESNULLP)); + } + + if (len == 0) { + invoke_safe_mem_constraint_handler("wmemset_s: len is 0", + NULL, ESZEROL); + return (RCNEGATE(ESZEROL)); + } + + if (len*sizeof(wchar_t) > RSIZE_MAX_MEM) { + invoke_safe_mem_constraint_handler("wmemset_s: len exceeds max", + NULL, ESLEMAX); + return (RCNEGATE(ESLEMAX)); + } + + mem_prim_set32((uint32_t *)dest, len, value); + + return (RCNEGATE(EOK)); +} +EXPORT_SYMBOL(wmemset_s) From 8de8b62669f0251f34859d6d5ce01030ed19846b Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Tue, 4 Feb 2020 14:05:25 +0100 Subject: [PATCH 2/4] Convert unsafe APIs to safe ones --- .circleci/config.yml | 3 + .ignore | 1 + ci/banned.h.sh | 54 ++++ src/backend/distributed/Makefile | 14 +- src/backend/distributed/commands/collation.c | 10 +- src/backend/distributed/commands/function.c | 10 +- src/backend/distributed/commands/multi_copy.c | 22 +- src/backend/distributed/commands/type.c | 10 +- .../connection/connection_configuration.c | 5 +- .../connection/connection_management.c | 8 +- .../executor/multi_task_tracker_executor.c | 13 +- .../master/master_metadata_utility.c | 5 +- .../distributed/master/worker_node_manager.c | 2 +- .../distributed/metadata/metadata_cache.c | 16 +- .../distributed/metadata/node_metadata.c | 2 +- .../distributed/planner/distributed_planner.c | 2 +- .../planner/multi_router_planner.c | 3 +- .../distributed/planner/recursive_planning.c | 2 +- .../distributed/planner/shard_pruning.c | 2 +- .../distributed/relay/relay_event_utility.c | 17 +- src/backend/distributed/shared_library_init.c | 21 +- .../distributed/transaction/backend_data.c | 2 +- .../transaction/remote_transaction.c | 7 +- .../transaction/transaction_management.c | 3 +- src/backend/distributed/utils/acquire_lock.c | 21 +- .../distributed/utils/citus_safe_lib.c | 302 ++++++++++++++++++ src/backend/distributed/utils/listutils.c | 3 +- src/backend/distributed/utils/maintenanced.c | 17 +- .../distributed/utils/statistics_collection.c | 113 ------- src/backend/distributed/worker/task_tracker.c | 10 +- .../worker/worker_data_fetch_protocol.c | 2 +- src/include/distributed/citus_safe_lib.h | 29 ++ 32 files changed, 528 insertions(+), 203 deletions(-) create mode 100644 .ignore create mode 100755 ci/banned.h.sh create mode 100644 src/backend/distributed/utils/citus_safe_lib.c create mode 100644 src/include/distributed/citus_safe_lib.h diff --git a/.circleci/config.yml b/.circleci/config.yml index 015983c23..2376a49d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,6 +40,9 @@ jobs: - run: name: 'Check if changed' command: git diff --exit-code + - run: + name: 'Check for banned C API usage' + command: ci/banned.h.sh check-sql-snapshots: docker: - image: 'citus/extbuilder:latest' diff --git a/.ignore b/.ignore new file mode 100644 index 000000000..61ead8666 --- /dev/null +++ b/.ignore @@ -0,0 +1 @@ +/vendor diff --git a/ci/banned.h.sh b/ci/banned.h.sh new file mode 100755 index 000000000..6b91e6072 --- /dev/null +++ b/ci/banned.h.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# Checks for the APIs that are banned by microsoft. Since we compile for Linux +# we use the replacements from https://github.com/intel/safestringlib +# Not all replacement functions are available in safestringlib. If it doesn't +# exist and you cannot rewrite the code to not use the banned API, then you can +# add a comment containing "IGNORE-BANNED" to the line where the error is and +# this check will ignore that match. +# +# The replacement function that you should use are listed here: +# https://liquid.microsoft.com/Web/Object/Read/ms.security/Requirements/Microsoft.Security.SystemsADM.10082#guide + +set -eu + +files=$(find src -iname '*.[ch]' | git check-attr --stdin citus-style | grep -v ': unset$' | sed 's/: citus-style: set$//') + +# grep is allowed to fail, that means no banned matches are found +set +e +# Required banned from banned.h. These functions are not allowed to be used at +# all. +# shellcheck disable=SC2086 +grep -E '\b(strcpy|strcpyA|strcpyW|wcscpy|_tcscpy|_mbscpy|StrCpy|StrCpyA|StrCpyW|lstrcpy|lstrcpyA|lstrcpyW|_tccpy|_mbccpy|_ftcscpy|strcat|strcatA|strcatW|wcscat|_tcscat|_mbscat|StrCat|StrCatA|StrCatW|lstrcat|lstrcatA|lstrcatW|StrCatBuff|StrCatBuffA|StrCatBuffW|StrCatChainW|_tccat|_mbccat|_ftcscat|sprintfW|sprintfA|wsprintf|wsprintfW|wsprintfA|sprintf|swprintf|_stprintf|wvsprintf|wvsprintfA|wvsprintfW|vsprintf|_vstprintf|vswprintf|strncpy|wcsncpy|_tcsncpy|_mbsncpy|_mbsnbcpy|StrCpyN|StrCpyNA|StrCpyNW|StrNCpy|strcpynA|StrNCpyA|StrNCpyW|lstrcpyn|lstrcpynA|lstrcpynW|strncat|wcsncat|_tcsncat|_mbsncat|_mbsnbcat|StrCatN|StrCatNA|StrCatNW|StrNCat|StrNCatA|StrNCatW|lstrncat|lstrcatnA|lstrcatnW|lstrcatn|gets|_getts|_gettws|IsBadWritePtr|IsBadHugeWritePtr|IsBadReadPtr|IsBadHugeReadPtr|IsBadCodePtr|IsBadStringPtr|memcpy|RtlCopyMemory|CopyMemory|wmemcpy|lstrlen)\(' $files \ + | grep -v "IGNORE-BANNED" \ + && echo "ERROR: Required banned API usage detected" && exit 1 + +# Required banned from table on liquid. These functions are not allowed to be +# used at all. +# shellcheck disable=SC2086 +grep -E '\b(strcat|strcpy|strerror|strncat|strncpy|strtok|wcscat|wcscpy|wcsncat|wcsncpy|wcstok|fprintf|fwprintf|printf|snprintf|sprintf|swprintf|vfprintf|vprintf|vsnprintf|vsprintf|vswprintf|vwprintf|wprintf|fscanf|fwscanf|gets|scanf|sscanf|swscanf|vfscanf|vfwscanf|vscanf|vsscanf|vswscanf|vwscanf|wscanf|asctime|atof|atoi|atol|atoll|bsearch|ctime|fopen|freopen|getenv|gmtime|localtime|mbsrtowcs|mbstowcs|memcpy|memmove|qsort|rewind|setbuf|wmemcpy|wmemmove)\(' $files \ + | grep -v "IGNORE-BANNED" \ + && echo "ERROR: Required banned API usage from table detected" && exit 1 + +# Recommended banned from banned.h. If you can change the code not to use these +# that would be great. You can use IGNORE-BANNED if you need to use it anyway. +# You can also remove it from the regex, if you want to mark the API as allowed +# throughout the codebase (to not have to add IGNORED-BANNED everywhere). In +# that case note it in this comment that you did so. +# shellcheck disable=SC2086 +grep -E '\b(wnsprintf|wnsprintfA|wnsprintfW|_snwprintf|_snprintf|_sntprintf|_vsnprintf|vsnprintf|_vsnwprintf|_vsntprintf|wvnsprintf|wvnsprintfA|wvnsprintfW|strtok|_tcstok|wcstok|_mbstok|makepath|_tmakepath| _makepath|_wmakepath|_splitpath|_tsplitpath|_wsplitpath|scanf|wscanf|_tscanf|sscanf|swscanf|_stscanf|snscanf|snwscanf|_sntscanf|_itoa|_itow|_i64toa|_i64tow|_ui64toa|_ui64tot|_ui64tow|_ultoa|_ultot|_ultow|CharToOem|CharToOemA|CharToOemW|OemToChar|OemToCharA|OemToCharW|CharToOemBuffA|CharToOemBuffW|alloca|_alloca|ChangeWindowMessageFilter)\(' $files \ + | grep -v "IGNORE-BANNED" \ + && echo "ERROR: Recomended banned API usage detected" && exit 1 + +# Recommended banned from table on liquid. If you can change the code not to use these +# that would be great. You can use IGNORE-BANNED if you need to use it anyway. +# You can also remove it from the regex, if you want to mark the API as allowed +# throughout the codebase (to not have to add IGNORED-BANNED everywhere). In +# that case note it in this comment that you did so. +# Banned APIs ignored throughout the codebase: +# - strlen +# shellcheck disable=SC2086 +grep -E '\b(alloca|getwd|mktemp|tmpnam|wcrtomb|wcrtombs|wcslen|wcsrtombs|wcstombs|wctomb|class_addMethod|class_replaceMethod)\(' $files \ + | grep -v "IGNORE-BANNED" \ + && echo "ERROR: Recomended banned API usage detected" && exit 1 +exit 0 diff --git a/src/backend/distributed/Makefile b/src/backend/distributed/Makefile index 76cf0acbb..d5356c0ba 100644 --- a/src/backend/distributed/Makefile +++ b/src/backend/distributed/Makefile @@ -2,6 +2,10 @@ citus_subdir = src/backend/distributed citus_top_builddir = ../../.. +safestringlib_srcdir = $(citus_abs_top_srcdir)/vendor/safestringlib +safestringlib_builddir = $(citus_top_builddir)/vendor/safestringlib/build +safestringlib_a = $(safestringlib_builddir)/libsafestring_static.a +safestringlib_sources = $(wildcard $(safestringlib_srcdir)/safeclib/*) MODULE_big = citus EXTENSION = citus @@ -39,11 +43,19 @@ utils/citus_version.o: $(CITUS_VERSION_INVALIDATE) SHLIB_LINK += $(filter -lssl -lcrypto -lssleay32 -leay32, $(LIBS)) -override CPPFLAGS += -I$(libpq_srcdir) +override LDFLAGS += $(safestringlib_a) +override CPPFLAGS += -I$(libpq_srcdir) -I$(safestringlib_srcdir)/include SQL_DEPDIR=.deps/sql SQL_BUILDDIR=build/sql +$(safestringlib_a): $(safestringlib_sources) + rm -rf $(safestringlib_builddir) + mkdir -p $(safestringlib_builddir) + cd $(safestringlib_builddir) && cmake $(safestringlib_srcdir) && make -j5 + +citus.so: $(safestringlib_a) + $(generated_sql_files): $(citus_abs_srcdir)/build/%: % @mkdir -p $(citus_abs_srcdir)/$(SQL_DEPDIR) $(citus_abs_srcdir)/$(SQL_BUILDDIR) cd $(citus_abs_srcdir) && cpp -undef -w -P -MMD -MP -MF$(SQL_DEPDIR)/$(*F).Po -MT$@ $< > $@ diff --git a/src/backend/distributed/commands/collation.c b/src/backend/distributed/commands/collation.c index af0eb6bcf..8b7063cf1 100644 --- a/src/backend/distributed/commands/collation.c +++ b/src/backend/distributed/commands/collation.c @@ -13,6 +13,7 @@ #include "access/htup_details.h" #include "access/xact.h" #include "catalog/pg_collation.h" +#include "distributed/citus_safe_lib.h" #include "distributed/commands/utility_hook.h" #include "distributed/commands.h" #include "distributed/deparser.h" @@ -529,16 +530,17 @@ GenerateBackupNameForCollationCollision(const ObjectAddress *address) while (true) { - int suffixLength = snprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)", - count); + int suffixLength = SafeSnprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)", + count); /* trim the base name at the end to leave space for the suffix and trailing \0 */ baseLength = Min(baseLength, NAMEDATALEN - suffixLength - 1); /* clear newName before copying the potentially trimmed baseName and suffix */ memset(newName, 0, NAMEDATALEN); - strncpy(newName, baseName, baseLength); - strncpy(newName + baseLength, suffix, suffixLength); + strncpy_s(newName, NAMEDATALEN, baseName, baseLength); + strncpy_s(newName + baseLength, NAMEDATALEN - baseLength, suffix, + suffixLength); List *newCollationName = list_make2(namespace, makeString(newName)); diff --git a/src/backend/distributed/commands/function.c b/src/backend/distributed/commands/function.c index 9bffb1bac..da6cefa3f 100644 --- a/src/backend/distributed/commands/function.c +++ b/src/backend/distributed/commands/function.c @@ -30,6 +30,7 @@ #include "catalog/pg_type.h" #include "commands/extension.h" #include "distributed/citus_ruleutils.h" +#include "distributed/citus_safe_lib.h" #include "distributed/colocation_utils.h" #include "distributed/commands.h" #include "distributed/commands/utility_hook.h" @@ -1715,16 +1716,17 @@ GenerateBackupNameForProcCollision(const ObjectAddress *address) while (true) { - int suffixLength = snprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)", - count); + int suffixLength = SafeSnprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)", + count); /* trim the base name at the end to leave space for the suffix and trailing \0 */ baseLength = Min(baseLength, NAMEDATALEN - suffixLength - 1); /* clear newName before copying the potentially trimmed baseName and suffix */ memset(newName, 0, NAMEDATALEN); - strncpy(newName, baseName, baseLength); - strncpy(newName + baseLength, suffix, suffixLength); + strncpy_s(newName, NAMEDATALEN, baseName, baseLength); + strncpy_s(newName + baseLength, NAMEDATALEN - baseLength, suffix, + suffixLength); List *newProcName = list_make2(namespace, makeString(newName)); diff --git a/src/backend/distributed/commands/multi_copy.c b/src/backend/distributed/commands/multi_copy.c index 108739832..d6d3cbee1 100644 --- a/src/backend/distributed/commands/multi_copy.c +++ b/src/backend/distributed/commands/multi_copy.c @@ -65,6 +65,7 @@ #include "catalog/pg_type.h" #include "commands/copy.h" #include "commands/defrem.h" +#include "distributed/citus_safe_lib.h" #include "distributed/commands/multi_copy.h" #include "distributed/commands/utility_hook.h" #include "distributed/intermediate_results.h" @@ -432,9 +433,8 @@ CopyToExistingShards(CopyStmt *copyStatement, char *completionTag) * There is no need to deep copy everything. We will just deep copy of the fields * we will change. */ - memcpy(copiedDistributedRelation, distributedRelation, sizeof(RelationData)); - memcpy(copiedDistributedRelationTuple, distributedRelation->rd_rel, - CLASS_TUPLE_SIZE); + *copiedDistributedRelation = *distributedRelation; + *copiedDistributedRelationTuple = *distributedRelation->rd_rel; copiedDistributedRelation->rd_rel = copiedDistributedRelationTuple; copiedDistributedRelation->rd_att = CreateTupleDescCopyConstr(tupleDescriptor); @@ -511,8 +511,8 @@ CopyToExistingShards(CopyStmt *copyStatement, char *completionTag) if (completionTag != NULL) { - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "COPY " UINT64_FORMAT, processedRowCount); + SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE, + "COPY " UINT64_FORMAT, processedRowCount); } } @@ -696,8 +696,8 @@ CopyToNewShards(CopyStmt *copyStatement, char *completionTag, Oid relationId) if (completionTag != NULL) { - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "COPY " UINT64_FORMAT, processedRowCount); + SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE, + "COPY " UINT64_FORMAT, processedRowCount); } } @@ -2693,8 +2693,8 @@ ProcessCopyStmt(CopyStmt *copyStatement, char *completionTag, const char *queryS int64 tuplesSent = WorkerExecuteSqlTask(query, filename, binaryCopyFormat); - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "COPY " UINT64_FORMAT, tuplesSent); + SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE, + "COPY " UINT64_FORMAT, tuplesSent); return NULL; } @@ -2795,8 +2795,8 @@ CitusCopyTo(CopyStmt *copyStatement, char *completionTag) if (completionTag != NULL) { - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "COPY " UINT64_FORMAT, - tuplesSent); + SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE, "COPY " UINT64_FORMAT, + tuplesSent); } } diff --git a/src/backend/distributed/commands/type.c b/src/backend/distributed/commands/type.c index fec7e68fb..2e46a0f41 100644 --- a/src/backend/distributed/commands/type.c +++ b/src/backend/distributed/commands/type.c @@ -50,6 +50,7 @@ #include "catalog/pg_enum.h" #include "catalog/pg_type.h" #include "commands/extension.h" +#include "distributed/citus_safe_lib.h" #include "distributed/commands.h" #include "distributed/commands/utility_hook.h" #include "distributed/deparser.h" @@ -1075,16 +1076,17 @@ GenerateBackupNameForTypeCollision(const ObjectAddress *address) while (true) { - int suffixLength = snprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)", - count); + int suffixLength = SafeSnprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)", + count); /* trim the base name at the end to leave space for the suffix and trailing \0 */ baseLength = Min(baseLength, NAMEDATALEN - suffixLength - 1); /* clear newName before copying the potentially trimmed baseName and suffix */ memset(newName, 0, NAMEDATALEN); - strncpy(newName, baseName, baseLength); - strncpy(newName + baseLength, suffix, suffixLength); + strncpy_s(newName, NAMEDATALEN, baseName, baseLength); + strncpy_s(newName + baseLength, NAMEDATALEN - baseLength, suffix, + suffixLength); rel->relname = newName; TypeName *newTypeName = makeTypeNameFromNameList(MakeNameListFromRangeVar(rel)); diff --git a/src/backend/distributed/connection/connection_configuration.c b/src/backend/distributed/connection/connection_configuration.c index 9d1e423e9..8e21fcee0 100644 --- a/src/backend/distributed/connection/connection_configuration.c +++ b/src/backend/distributed/connection/connection_configuration.c @@ -10,6 +10,7 @@ #include "postgres.h" +#include "distributed/citus_safe_lib.h" #include "distributed/connection_management.h" #include "distributed/metadata_cache.h" #include "distributed/worker_manager.h" @@ -189,8 +190,8 @@ CheckConninfo(const char *conninfo, const char **whitelist, continue; } - void *matchingKeyword = bsearch(&option->keyword, whitelist, whitelistLength, - sizeof(char *), pg_qsort_strcmp); + void *matchingKeyword = SafeBsearch(&option->keyword, whitelist, whitelistLength, + sizeof(char *), pg_qsort_strcmp); if (matchingKeyword == NULL) { /* the whitelist lacks this keyword; error out! */ diff --git a/src/backend/distributed/connection/connection_management.c b/src/backend/distributed/connection/connection_management.c index 359431eb6..3e8d992f2 100644 --- a/src/backend/distributed/connection/connection_management.c +++ b/src/backend/distributed/connection/connection_management.c @@ -15,6 +15,8 @@ #include "miscadmin.h" +#include "safe_lib.h" + #include "access/hash.h" #include "commands/dbcommands.h" #include "distributed/connection_management.h" @@ -109,7 +111,8 @@ InitializeConnectionManagement(void) info.hcxt = ConnectionContext; uint32 hashFlags = (HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); - memcpy(&connParamsInfo, &info, sizeof(HASHCTL)); + /* connParamsInfo is same as info, except for entrysize */ + connParamsInfo = info; connParamsInfo.entrysize = sizeof(ConnParamsHashEntry); ConnectionHash = hash_create("citus connection cache (host,port,user,database)", @@ -1223,7 +1226,8 @@ DefaultCitusNoticeProcessor(void *arg, const char *message) char *nodeName = connection->hostname; uint32 nodePort = connection->port; char *trimmedMessage = TrimLogLevel(message); - char *level = strtok((char *) message, ":"); + char *strtokPosition; + char *level = strtok_r((char *) message, ":", &strtokPosition); ereport(CitusNoticeLogLevel, (errmsg("%s", ApplyLogRedaction(trimmedMessage)), diff --git a/src/backend/distributed/executor/multi_task_tracker_executor.c b/src/backend/distributed/executor/multi_task_tracker_executor.c index 459406e45..77da0a6e0 100644 --- a/src/backend/distributed/executor/multi_task_tracker_executor.c +++ b/src/backend/distributed/executor/multi_task_tracker_executor.c @@ -692,16 +692,17 @@ TrackerHash(const char *taskTrackerHashName, List *workerNodeList, char *userNam char *nodeName = workerNode->workerName; uint32 nodePort = workerNode->workerPort; - char taskStateHashName[MAXPGPATH]; uint32 taskStateCount = 32; HASHCTL info; /* insert task tracker into the tracker hash */ TaskTracker *taskTracker = TrackerHashEnter(taskTrackerHash, nodeName, nodePort); + /* for each task tracker, create hash to track its assigned tasks */ - snprintf(taskStateHashName, MAXPGPATH, - "Task Tracker \"%s:%u\" Task State Hash", nodeName, nodePort); + StringInfo taskStateHashName = makeStringInfo(); + appendStringInfo(taskStateHashName, "Task Tracker \"%s:%u\" Task State Hash", + nodeName, nodePort); memset(&info, 0, sizeof(info)); info.keysize = sizeof(uint64) + sizeof(uint32); @@ -710,12 +711,12 @@ TrackerHash(const char *taskTrackerHashName, List *workerNodeList, char *userNam info.hcxt = CurrentMemoryContext; int hashFlags = (HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); - HTAB *taskStateHash = hash_create(taskStateHashName, taskStateCount, &info, + HTAB *taskStateHash = hash_create(taskStateHashName->data, taskStateCount, &info, hashFlags); if (taskStateHash == NULL) { ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("could not initialize %s", taskStateHashName))); + errmsg("could not initialize %s", taskStateHashName->data))); } taskTracker->taskStateHash = taskStateHash; @@ -781,7 +782,7 @@ TrackerHashEnter(HTAB *taskTrackerHash, char *nodeName, uint32 nodePort) } /* init task tracker object with zeroed out task tracker key */ - memcpy(taskTracker, &taskTrackerKey, sizeof(TaskTracker)); + *taskTracker = taskTrackerKey; taskTracker->trackerStatus = TRACKER_CONNECT_START; taskTracker->connectionId = INVALID_CONNECTION_ID; taskTracker->currentTaskIndex = -1; diff --git a/src/backend/distributed/master/master_metadata_utility.c b/src/backend/distributed/master/master_metadata_utility.c index 88d9a1161..ca3c162ed 100644 --- a/src/backend/distributed/master/master_metadata_utility.c +++ b/src/backend/distributed/master/master_metadata_utility.c @@ -31,6 +31,7 @@ #include "distributed/colocation_utils.h" #include "distributed/connection_management.h" #include "distributed/citus_nodes.h" +#include "distributed/citus_safe_lib.h" #include "distributed/listutils.h" #include "distributed/master_metadata_utility.h" #include "distributed/master_protocol.h" @@ -230,7 +231,7 @@ DistributedTableSizeOnWorker(WorkerNode *workerNode, Oid relationId, char *sizeQ List *sizeList = ReadFirstColumnAsText(result); StringInfo tableSizeStringInfo = (StringInfo) linitial(sizeList); char *tableSizeString = tableSizeStringInfo->data; - uint64 tableSize = atol(tableSizeString); + uint64 tableSize = SafeStringToUint64(tableSizeString); PQclear(result); ClearResults(connection, raiseErrors); @@ -608,7 +609,7 @@ void CopyShardPlacement(ShardPlacement *srcPlacement, ShardPlacement *destPlacement) { /* first copy all by-value fields */ - memcpy(destPlacement, srcPlacement, sizeof(ShardPlacement)); + *destPlacement = *srcPlacement; /* and then the fields pointing to external values */ if (srcPlacement->nodeName) diff --git a/src/backend/distributed/master/worker_node_manager.c b/src/backend/distributed/master/worker_node_manager.c index 63924ba00..f06dafa12 100644 --- a/src/backend/distributed/master/worker_node_manager.c +++ b/src/backend/distributed/master/worker_node_manager.c @@ -355,7 +355,7 @@ FilterActiveNodeListFunc(LOCKMODE lockMode, bool (*checkFunction)(WorkerNode *)) if (workerNode->isActive && checkFunction(workerNode)) { WorkerNode *workerNodeCopy = palloc0(sizeof(WorkerNode)); - memcpy(workerNodeCopy, workerNode, sizeof(WorkerNode)); + *workerNodeCopy = *workerNode; workerNodeList = lappend(workerNodeList, workerNodeCopy); } } diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index f455b2ecd..712821624 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -438,7 +438,7 @@ LoadGroupShardPlacement(uint64 shardId, uint64 placementId) { GroupShardPlacement *shardPlacement = CitusMakeNode(GroupShardPlacement); - memcpy(shardPlacement, &placementArray[i], sizeof(GroupShardPlacement)); + *shardPlacement = placementArray[i]; return shardPlacement; } @@ -513,9 +513,11 @@ ResolveGroupShardPlacement(GroupShardPlacement *groupShardPlacement, WorkerNode *workerNode = LookupNodeForGroup(groupId); /* copy everything into shardPlacement but preserve the header */ - memcpy((((CitusNode *) shardPlacement) + 1), - (((CitusNode *) groupShardPlacement) + 1), - sizeof(GroupShardPlacement) - sizeof(CitusNode)); + CitusNode header = shardPlacement->type; + GroupShardPlacement *shardPlacementAsGroupPlacement = + (GroupShardPlacement *) shardPlacement; + *shardPlacementAsGroupPlacement = *groupShardPlacement; + shardPlacement->type = header; shardPlacement->nodeName = pstrdup(workerNode->workerName); shardPlacement->nodePort = workerNode->workerPort; @@ -561,7 +563,7 @@ LookupNodeByNodeId(uint32 nodeId) if (workerNode->nodeId == nodeId) { WorkerNode *workerNodeCopy = palloc0(sizeof(WorkerNode)); - memcpy(workerNodeCopy, workerNode, sizeof(WorkerNode)); + *workerNodeCopy = *workerNode; return workerNodeCopy; } @@ -3597,7 +3599,7 @@ LookupDistPartitionTuple(Relation pgDistPartition, Oid relationId) ScanKeyData scanKey[1]; /* copy scankey to local copy, it will be modified during the scan */ - memcpy(scanKey, DistPartitionScanKey, sizeof(DistPartitionScanKey)); + scanKey[0] = DistPartitionScanKey[0]; /* set scan arguments */ scanKey[0].sk_argument = ObjectIdGetDatum(relationId); @@ -3631,7 +3633,7 @@ LookupDistShardTuples(Oid relationId) Relation pgDistShard = heap_open(DistShardRelationId(), AccessShareLock); /* copy scankey to local copy, it will be modified during the scan */ - memcpy(scanKey, DistShardScanKey, sizeof(DistShardScanKey)); + scanKey[0] = DistShardScanKey[0]; /* set scan arguments */ scanKey[0].sk_argument = ObjectIdGetDatum(relationId); diff --git a/src/backend/distributed/metadata/node_metadata.c b/src/backend/distributed/metadata/node_metadata.c index dd6e26119..28eece83c 100644 --- a/src/backend/distributed/metadata/node_metadata.c +++ b/src/backend/distributed/metadata/node_metadata.c @@ -873,7 +873,7 @@ FindWorkerNode(char *nodeName, int32 nodePort) if (handleFound) { WorkerNode *workerNode = (WorkerNode *) palloc(sizeof(WorkerNode)); - memcpy(workerNode, cachedWorkerNode, sizeof(WorkerNode)); + *workerNode = *cachedWorkerNode; return workerNode; } diff --git a/src/backend/distributed/planner/distributed_planner.c b/src/backend/distributed/planner/distributed_planner.c index e0d25cb97..63d970c2a 100644 --- a/src/backend/distributed/planner/distributed_planner.c +++ b/src/backend/distributed/planner/distributed_planner.c @@ -1029,7 +1029,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi standard_planner(newQuery, 0, boundParams); /* overwrite the old transformed query with the new transformed query */ - memcpy(query, newQuery, sizeof(Query)); + *query = *newQuery; /* recurse into CreateDistributedPlan with subqueries/CTEs replaced */ distributedPlan = CreateDistributedPlan(planId, originalQuery, query, NULL, false, diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index f0c371bf9..f953fb105 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -3294,8 +3294,7 @@ CopyRelationRestrictionContext(RelationRestrictionContext *oldContext) /* can't be copied, we copy (flatly) a RelOptInfo, and then decouple baserestrictinfo */ newRestriction->relOptInfo = palloc(sizeof(RelOptInfo)); - memcpy(newRestriction->relOptInfo, oldRestriction->relOptInfo, - sizeof(RelOptInfo)); + *newRestriction->relOptInfo = *oldRestriction->relOptInfo; newRestriction->relOptInfo->baserestrictinfo = copyObject(oldRestriction->relOptInfo->baserestrictinfo); diff --git a/src/backend/distributed/planner/recursive_planning.c b/src/backend/distributed/planner/recursive_planning.c index 4548f5499..89a3e3fd5 100644 --- a/src/backend/distributed/planner/recursive_planning.c +++ b/src/backend/distributed/planner/recursive_planning.c @@ -1142,7 +1142,7 @@ RecursivelyPlanSubquery(Query *subquery, RecursivePlanningContext *planningConte } /* finally update the input subquery to point the result query */ - memcpy(subquery, resultQuery, sizeof(Query)); + *subquery = *resultQuery; } diff --git a/src/backend/distributed/planner/shard_pruning.c b/src/backend/distributed/planner/shard_pruning.c index 2fbbc6d0c..24d909b83 100644 --- a/src/backend/distributed/planner/shard_pruning.c +++ b/src/backend/distributed/planner/shard_pruning.c @@ -981,7 +981,7 @@ CopyPartialPruningInstance(PruningInstance *sourceInstance) * being partial - if necessary it'll be marked so again by * PrunableExpressionsWalker(). */ - memcpy(newInstance, sourceInstance, sizeof(PruningInstance)); + *newInstance = *sourceInstance; newInstance->addedToPruningInstances = false; newInstance->isPartial = false; diff --git a/src/backend/distributed/relay/relay_event_utility.c b/src/backend/distributed/relay/relay_event_utility.c index f59fffc0f..deb2d3e0c 100644 --- a/src/backend/distributed/relay/relay_event_utility.c +++ b/src/backend/distributed/relay/relay_event_utility.c @@ -29,6 +29,7 @@ #include "catalog/namespace.h" #include "catalog/pg_class.h" #include "catalog/pg_constraint.h" +#include "distributed/citus_safe_lib.h" #include "distributed/commands.h" #include "distributed/metadata_cache.h" #include "distributed/relay_utility.h" @@ -694,8 +695,8 @@ AppendShardIdToName(char **name, uint64 shardId) NAMEDATALEN))); } - snprintf(shardIdAndSeparator, NAMEDATALEN, "%c" UINT64_FORMAT, - SHARD_NAME_SEPARATOR, shardId); + SafeSnprintf(shardIdAndSeparator, NAMEDATALEN, "%c" UINT64_FORMAT, + SHARD_NAME_SEPARATOR, shardId); int shardIdAndSeparatorLength = strlen(shardIdAndSeparator); /* @@ -705,7 +706,7 @@ AppendShardIdToName(char **name, uint64 shardId) if (nameLength < (NAMEDATALEN - shardIdAndSeparatorLength)) { - snprintf(extendedName, NAMEDATALEN, "%s%s", (*name), shardIdAndSeparator); + SafeSnprintf(extendedName, NAMEDATALEN, "%s%s", (*name), shardIdAndSeparator); } /* @@ -739,14 +740,14 @@ AppendShardIdToName(char **name, uint64 shardId) multiByteClipLength = pg_mbcliplen(*name, nameLength, (NAMEDATALEN - shardIdAndSeparatorLength - 10)); - snprintf(extendedName, NAMEDATALEN, "%.*s%c%.8x%s", - multiByteClipLength, (*name), - SHARD_NAME_SEPARATOR, longNameHash, - shardIdAndSeparator); + SafeSnprintf(extendedName, NAMEDATALEN, "%.*s%c%.8x%s", + multiByteClipLength, (*name), + SHARD_NAME_SEPARATOR, longNameHash, + shardIdAndSeparator); } (*name) = (char *) repalloc((*name), NAMEDATALEN); - int neededBytes = snprintf((*name), NAMEDATALEN, "%s", extendedName); + int neededBytes = SafeSnprintf((*name), NAMEDATALEN, "%s", extendedName); if (neededBytes < 0) { ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index b0ae355f8..c82f64553 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -13,7 +13,7 @@ #include #include -/* necessary to get alloca() on illumos */ +/* necessary to get alloca on illumos */ #ifdef __sun #include #endif @@ -21,11 +21,14 @@ #include "fmgr.h" #include "miscadmin.h" +#include "safe_lib.h" + #include "citus_version.h" #include "commands/explain.h" #include "executor/executor.h" #include "distributed/backend_data.h" #include "distributed/citus_nodefuncs.h" +#include "distributed/citus_safe_lib.h" #include "distributed/commands.h" #include "distributed/commands/multi_copy.h" #include "distributed/commands/utility_hook.h" @@ -187,6 +190,14 @@ _PG_init(void) "shared_preload_libraries."))); } + /* + * Register contstraint_handler hooks of safestringlib first. This way + * loading the extension will error out if one of these constraints are hit + * during load. + */ + set_str_constraint_handler_s(ereport_constraint_handler); + set_mem_constraint_handler_s(ereport_constraint_handler); + /* * Perform checks before registering any hooks, to avoid erroring out in a * partial state. @@ -290,7 +301,13 @@ ResizeStackToMaximumDepth(void) #ifndef WIN32 long max_stack_depth_bytes = max_stack_depth * 1024L; - volatile char *stack_resizer = alloca(max_stack_depth_bytes); + /* + * Explanation of IGNORE-BANNED: + * alloca is safe to use here since we limit the allocated size. We cannot + * use malloc as a replacement, since we actually want to grow the stack + * here. + */ + volatile char *stack_resizer = alloca(max_stack_depth_bytes); /* IGNORE-BANNED */ /* * Different architectures might have different directions while diff --git a/src/backend/distributed/transaction/backend_data.c b/src/backend/distributed/transaction/backend_data.c index 27222e69e..268d9b521 100644 --- a/src/backend/distributed/transaction/backend_data.c +++ b/src/backend/distributed/transaction/backend_data.c @@ -806,7 +806,7 @@ GetBackendDataForProc(PGPROC *proc, BackendData *result) SpinLockAcquire(&backendData->mutex); - memcpy(result, backendData, sizeof(BackendData)); + *result = *backendData; SpinLockRelease(&backendData->mutex); } diff --git a/src/backend/distributed/transaction/remote_transaction.c b/src/backend/distributed/transaction/remote_transaction.c index 34e1cb15f..6c4a011a7 100644 --- a/src/backend/distributed/transaction/remote_transaction.c +++ b/src/backend/distributed/transaction/remote_transaction.c @@ -16,6 +16,7 @@ #include "access/xact.h" #include "distributed/backend_data.h" +#include "distributed/citus_safe_lib.h" #include "distributed/connection_management.h" #include "distributed/metadata_cache.h" #include "distributed/remote_commands.h" @@ -1330,9 +1331,9 @@ Assign2PCIdentifier(MultiConnection *connection) uint64 transactionNumber = CurrentDistributedTransactionNumber(); /* print all numbers as unsigned to guarantee no minus symbols appear in the name */ - snprintf(connection->remoteTransaction.preparedName, NAMEDATALEN, - PREPARED_TRANSACTION_NAME_FORMAT, GetLocalGroupId(), MyProcPid, - transactionNumber, connectionNumber++); + SafeSnprintf(connection->remoteTransaction.preparedName, NAMEDATALEN, + PREPARED_TRANSACTION_NAME_FORMAT, GetLocalGroupId(), MyProcPid, + transactionNumber, connectionNumber++); } diff --git a/src/backend/distributed/transaction/transaction_management.c b/src/backend/distributed/transaction/transaction_management.c index b5bedc3ac..a547ddec7 100644 --- a/src/backend/distributed/transaction/transaction_management.c +++ b/src/backend/distributed/transaction/transaction_management.c @@ -20,6 +20,7 @@ #include "access/twophase.h" #include "access/xact.h" #include "distributed/backend_data.h" +#include "distributed/citus_safe_lib.h" #include "distributed/connection_management.h" #include "distributed/distributed_planner.h" #include "distributed/hash_helpers.h" @@ -538,7 +539,7 @@ AdjustMaxPreparedTransactions(void) { char newvalue[12]; - snprintf(newvalue, sizeof(newvalue), "%d", MaxConnections * 2); + SafeSnprintf(newvalue, sizeof(newvalue), "%d", MaxConnections * 2); SetConfigOption("max_prepared_transactions", newvalue, PGC_POSTMASTER, PGC_S_OVERRIDE); diff --git a/src/backend/distributed/utils/acquire_lock.c b/src/backend/distributed/utils/acquire_lock.c index 229340c97..dee96fb68 100644 --- a/src/backend/distributed/utils/acquire_lock.c +++ b/src/backend/distributed/utils/acquire_lock.c @@ -34,6 +34,7 @@ #include "utils/snapmgr.h" #include "distributed/citus_acquire_lock.h" +#include "distributed/citus_safe_lib.h" #include "distributed/connection_management.h" #include "distributed/version_compat.h" @@ -75,27 +76,21 @@ StartLockAcquireHelperBackgroundWorker(int backendToHelp, int32 lock_cooldown) args.lock_cooldown = lock_cooldown; /* construct the background worker and start it */ - snprintf(worker.bgw_name, BGW_MAXLEN, - "Citus Lock Acquire Helper: %d/%u", - backendToHelp, MyDatabaseId); - snprintf(worker.bgw_type, BGW_MAXLEN, "citus_lock_aqcuire"); + SafeSnprintf(worker.bgw_name, sizeof(worker.bgw_name), + "Citus Lock Acquire Helper: %d/%u", backendToHelp, MyDatabaseId); + strcpy_s(worker.bgw_type, sizeof(worker.bgw_type), "citus_lock_aqcuire"); worker.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION; worker.bgw_start_time = BgWorkerStart_RecoveryFinished; worker.bgw_restart_time = BGW_NEVER_RESTART; - snprintf(worker.bgw_library_name, BGW_MAXLEN, "citus"); - snprintf(worker.bgw_function_name, BGW_MAXLEN, "LockAcquireHelperMain"); + strcpy_s(worker.bgw_library_name, sizeof(worker.bgw_library_name), "citus"); + strcpy_s(worker.bgw_function_name, sizeof(worker.bgw_function_name), + "LockAcquireHelperMain"); worker.bgw_main_arg = Int32GetDatum(backendToHelp); worker.bgw_notify_pid = 0; - /* - * we check if args fits in bgw_extra to make sure it is safe to copy the data. Once - * we exceed the size of data to copy this way we need to look into a different way of - * passing the arguments to the worker. - */ - Assert(sizeof(worker.bgw_extra) >= sizeof(args)); - memcpy(worker.bgw_extra, &args, sizeof(args)); + memcpy_s(worker.bgw_extra, sizeof(worker.bgw_extra), &args, sizeof(args)); if (!RegisterDynamicBackgroundWorker(&worker, &handle)) { diff --git a/src/backend/distributed/utils/citus_safe_lib.c b/src/backend/distributed/utils/citus_safe_lib.c new file mode 100644 index 000000000..2e9875051 --- /dev/null +++ b/src/backend/distributed/utils/citus_safe_lib.c @@ -0,0 +1,302 @@ +/*------------------------------------------------------------------------- + * + * safe_lib.c + * + * This file contains all SafeXXXX helper functions that we implement to + * replace missing xxxx_s functions implemented by safestringlib. It also + * contains a constraint handler for use in both our SafeXXX and safestringlib + * its xxxx_s functions. + * + * Copyright (c) Citus Data, Inc. + * + *------------------------------------------------------------------------- + */ + +/* In PG 11 pg_vsnprintf is not exported unless you set this define */ +#if PG_VERSION_NUM < 120000 +#define USE_REPL_SNPRINTF 1 +#endif + +#include "postgres.h" + +#include "safe_lib.h" + +#include + +#include "distributed/citus_safe_lib.h" +#include "lib/stringinfo.h" + + +/* + * ereport_constraint_handler is a constraint handler that calls ereport. A + * constraint handler is called whenever an error occurs in any of the + * safestringlib xxxx_s functions or our SafeXXXX functions. + * + * More info on constraint handlers can be found here: + * https://en.cppreference.com/w/c/error/set_constraint_handler_s + */ +void +ereport_constraint_handler(const char *message, + void *pointer, + errno_t error) +{ + if (message && error) + { + ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg( + "Memory constraint error: %s (errno %d)", message, error))); + } + else if (message) + { + ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg( + "Memory constraint error: %s", message))); + } + else if (error) + { + ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg( + "Unknown function failed with memory constraint error (errno %d)", + error))); + } + else + { + ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg( + "Unknown function failed with memory constraint error"))); + } +} + + +/* + * SafeStringToInt64 converts a string containing a number to a int64. When it + * fails it calls ereport. + * + * The different error cases are inspired by + * https://stackoverflow.com/a/26083517/2570866 + */ +int64 +SafeStringToInt64(const char *str) +{ + char *endptr; + errno = 0; + int64 number = strtol(str, &endptr, 10); + + if (str == endptr) + { + ereport(ERROR, (errmsg("Error parsing %s as int64, no digits found\n", str))); + } + else if (errno == ERANGE && number == LONG_MIN) + { + ereport(ERROR, (errmsg("Error parsing %s as int64, underflow occured\n", str))); + } + else if (errno == ERANGE && number == LONG_MAX) + { + ereport(ERROR, (errmsg("Error parsing %s as int64, overflow occured\n", str))); + } + else if (errno == EINVAL) + { + ereport(ERROR, (errmsg( + "Error parsing %s as int64, base contains unsupported value\n", + str))); + } + else if (errno != 0 && number == 0) + { + int err = errno; + ereport(ERROR, (errmsg("Error parsing %s as int64, errno %d\n", str, err))); + } + else if (errno == 0 && str && *endptr != '\0') + { + ereport(ERROR, (errmsg( + "Error parsing %s as int64, aditional characters remain after int64\n", + str))); + } + return number; +} + + +/* + * SafeStringToUint64 converts a string containing a number to a uint64. When it + * fails it calls ereport. + * + * The different error cases are inspired by + * https://stackoverflow.com/a/26083517/2570866 + */ +uint64 +SafeStringToUint64(const char *str) +{ + char *endptr; + errno = 0; + uint64 number = strtoul(str, &endptr, 10); + + if (str == endptr) + { + ereport(ERROR, (errmsg("Error parsing %s as uint64, no digits found\n", str))); + } + else if (errno == ERANGE && number == LONG_MIN) + { + ereport(ERROR, (errmsg("Error parsing %s as uint64, underflow occured\n", str))); + } + else if (errno == ERANGE && number == LONG_MAX) + { + ereport(ERROR, (errmsg("Error parsing %s as uint64, overflow occured\n", str))); + } + else if (errno == EINVAL) + { + ereport(ERROR, (errmsg( + "Error parsing %s as uint64, base contains unsupported value\n", + str))); + } + else if (errno != 0 && number == 0) + { + int err = errno; + ereport(ERROR, (errmsg("Error parsing %s as uint64, errno %d\n", str, err))); + } + else if (errno == 0 && str && *endptr != '\0') + { + ereport(ERROR, (errmsg( + "Error parsing %s as uint64, aditional characters remain after uint64\n", + str))); + } + return number; +} + + +/* + * SafeQsort is the non reentrant version of qsort (qsort vs qsort_r), but it + * does the input checks required for qsort_s: + * 1. count or size is greater than RSIZE_MAX + * 2. ptr or comp is a null pointer (unless count is zero) + * source: https://en.cppreference.com/w/c/algorithm/qsort + * + * When it hits these errors it calls the ereport_constraint_handler. + * + * NOTE: this functions calls pg_qsort instead of stdlib qsort. + */ +void +SafeQsort(void *ptr, rsize_t count, rsize_t size, + int (*comp)(const void *, const void *)) +{ + if (count > RSIZE_MAX_MEM) + { + ereport_constraint_handler("SafeQsort: count exceeds max", + NULL, ESLEMAX); + } + + if (size > RSIZE_MAX_MEM) + { + ereport_constraint_handler("SafeQsort: size exceeds max", + NULL, ESLEMAX); + } + if (size != 0) + { + if (ptr == NULL) + { + ereport_constraint_handler("SafeQsort: ptr is NULL", NULL, ESNULLP); + } + if (comp == NULL) + { + ereport_constraint_handler("SafeQsort: comp is NULL", NULL, ESNULLP); + } + } + pg_qsort(ptr, count, size, comp); +} + + +/* + * SafeBsearch is a non reentrant version of bsearch, but it does the + * input checks required for bsearch_s: + * 1. count or size is greater than RSIZE_MAX + * 2. key, ptr or comp is a null pointer (unless count is zero) + * source: https://en.cppreference.com/w/c/algorithm/bsearch + * + * When it hits these errors it calls the ereport_constraint_handler. + * + * NOTE: this functions calls pg_qsort instead of stdlib qsort. + */ +void * +SafeBsearch(const void *key, const void *ptr, rsize_t count, rsize_t size, + int (*comp)(const void *, const void *)) +{ + if (count > RSIZE_MAX_MEM) + { + ereport_constraint_handler("SafeBsearch: count exceeds max", + NULL, ESLEMAX); + } + + if (size > RSIZE_MAX_MEM) + { + ereport_constraint_handler("SafeBsearch: size exceeds max", + NULL, ESLEMAX); + } + if (size != 0) + { + if (key == NULL) + { + ereport_constraint_handler("SafeBsearch: key is NULL", NULL, ESNULLP); + } + if (ptr == NULL) + { + ereport_constraint_handler("SafeBsearch: ptr is NULL", NULL, ESNULLP); + } + if (comp == NULL) + { + ereport_constraint_handler("SafeBsearch: comp is NULL", NULL, ESNULLP); + } + } + + /* + * Explanation of IGNORE-BANNED: + * bsearch is safe to use here since we check the same thing bsearch_s + * does. We cannot use bsearch_s as a replacement, since it's not available + * in safestringlib. + */ + return bsearch(key, ptr, count, size, comp); /* IGNORE-BANNED */ +} + + +/* + * SafeSnprintf is a safer replacement for snprintf, which is needed since + * safestringlib doesn't implement snprintf_s. + * + * The required failure modes of snprint_s are as follows (in parentheses if + * this implements it and how): + * 1. the conversion specifier %n is present in format (yes, %n is not + * supported by pg_vsnprintf) + * 2. any of the arguments corresponding to %s is a null pointer (half, checked + * in postgres when asserts are enabled) + * 3. format or buffer is a null pointer (yes, checked by this function) + * 4. bufsz is zero or greater than RSIZE_MAX (yes, checked by this function) + * 5. encoding errors occur in any of string and character conversion + * specifiers (no clue what postgres does in this case) + * source: https://en.cppreference.com/w/c/io/fprintf + */ +int +SafeSnprintf(char *restrict buffer, rsize_t bufsz, const char *restrict format, ...) +{ + /* failure mode 3 */ + if (buffer == NULL) + { + ereport_constraint_handler("SafeSnprintf: buffer is NULL", NULL, ESNULLP); + } + if (format == NULL) + { + ereport_constraint_handler("SafeSnprintf: format is NULL", NULL, ESNULLP); + } + + /* failure mode 4 */ + if (bufsz == 0) + { + ereport_constraint_handler("SafeSnprintf: bufsz is 0", + NULL, ESZEROL); + } + + if (bufsz > RSIZE_MAX_STR) + { + ereport_constraint_handler("SafeSnprintf: bufsz exceeds max", + NULL, ESLEMAX); + } + + va_list args; + + va_start(args, format); + size_t result = pg_vsnprintf(buffer, bufsz, format, args); + va_end(args); + return result; +} diff --git a/src/backend/distributed/utils/listutils.c b/src/backend/distributed/utils/listutils.c index a94beab91..831418f0f 100644 --- a/src/backend/distributed/utils/listutils.c +++ b/src/backend/distributed/utils/listutils.c @@ -15,6 +15,7 @@ #include "utils/lsyscache.h" #include "lib/stringinfo.h" +#include "distributed/citus_safe_lib.h" #include "distributed/listutils.h" #include "nodes/pg_list.h" #include "utils/memutils.h" @@ -49,7 +50,7 @@ SortList(List *pointerList, int (*comparisonFunction)(const void *, const void * } /* sort the array of pointers using the comparison function */ - qsort(array, arraySize, sizeof(void *), comparisonFunction); + SafeQsort(array, arraySize, sizeof(void *), comparisonFunction); /* convert the sorted array of pointers back to a sorted list */ for (arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) diff --git a/src/backend/distributed/utils/maintenanced.c b/src/backend/distributed/utils/maintenanced.c index efcf6c4ea..d6ba2ad0f 100644 --- a/src/backend/distributed/utils/maintenanced.c +++ b/src/backend/distributed/utils/maintenanced.c @@ -30,6 +30,7 @@ #include "commands/extension.h" #include "libpq/pqsignal.h" #include "catalog/namespace.h" +#include "distributed/citus_safe_lib.h" #include "distributed/distributed_deadlock_detection.h" #include "distributed/maintenanced.h" #include "distributed/master_protocol.h" @@ -171,9 +172,9 @@ InitializeMaintenanceDaemonBackend(void) memset(&worker, 0, sizeof(worker)); - snprintf(worker.bgw_name, BGW_MAXLEN, - "Citus Maintenance Daemon: %u/%u", - MyDatabaseId, extensionOwner); + SafeSnprintf(worker.bgw_name, sizeof(worker.bgw_name), + "Citus Maintenance Daemon: %u/%u", + MyDatabaseId, extensionOwner); /* request ability to connect to target database */ worker.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION; @@ -186,10 +187,14 @@ InitializeMaintenanceDaemonBackend(void) /* Restart after a bit after errors, but don't bog the system. */ worker.bgw_restart_time = 5; - sprintf(worker.bgw_library_name, "citus"); - sprintf(worker.bgw_function_name, "CitusMaintenanceDaemonMain"); + strcpy_s(worker.bgw_library_name, + sizeof(worker.bgw_library_name), "citus"); + strcpy_s(worker.bgw_function_name, sizeof(worker.bgw_library_name), + "CitusMaintenanceDaemonMain"); + worker.bgw_main_arg = ObjectIdGetDatum(MyDatabaseId); - memcpy(worker.bgw_extra, &extensionOwner, sizeof(Oid)); + memcpy_s(worker.bgw_extra, sizeof(worker.bgw_extra), &extensionOwner, + sizeof(Oid)); worker.bgw_notify_pid = MyProcPid; if (!RegisterDynamicBackgroundWorker(&worker, &handle)) diff --git a/src/backend/distributed/utils/statistics_collection.c b/src/backend/distributed/utils/statistics_collection.c index 0cce1181f..81d51c598 100644 --- a/src/backend/distributed/utils/statistics_collection.c +++ b/src/backend/distributed/utils/statistics_collection.c @@ -21,17 +21,7 @@ PG_FUNCTION_INFO_V1(citus_server_id); #ifdef HAVE_LIBCURL #include -#ifndef WIN32 #include -#else -typedef struct utsname -{ - char sysname[65]; - char release[65]; - char version[65]; - char machine[65]; -} utsname; -#endif #include "access/xact.h" #include "distributed/metadata_cache.h" @@ -54,9 +44,6 @@ static bool SendHttpPostJsonRequest(const char *url, const char *postFields, long timeoutSeconds, curl_write_callback responseCallback); static bool PerformHttpRequest(CURL *curl); -#ifdef WIN32 -static int uname(struct utsname *buf); -#endif /* WarnIfSyncDNS warns if libcurl is compiled with synchronous DNS. */ @@ -360,103 +347,3 @@ citus_server_id(PG_FUNCTION_ARGS) PG_RETURN_UUID_P((pg_uuid_t *) buf); } - - -#ifdef WIN32 - -/* - * Inspired by perl5's win32_uname - * https://github.com/Perl/perl5/blob/69374fe705978962b85217f3eb828a93f836fd8d/win32/win32.c#L2057 - */ -static int -uname(struct utsname *buf) -{ - OSVERSIONINFO ver; - - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); - - switch (ver.dwPlatformId) - { - case VER_PLATFORM_WIN32_WINDOWS: - { - strcpy(buf->sysname, "Windows"); - break; - } - - case VER_PLATFORM_WIN32_NT: - { - strcpy(buf->sysname, "Windows NT"); - break; - } - - case VER_PLATFORM_WIN32s: - { - strcpy(buf->sysname, "Win32s"); - break; - } - - default: - { - strcpy(buf->sysname, "Win32 Unknown"); - break; - } - } - - sprintf(buf->release, "%d.%d", ver.dwMajorVersion, ver.dwMinorVersion); - - { - SYSTEM_INFO info; - char *arch; - - GetSystemInfo(&info); - DWORD procarch = info.wProcessorArchitecture; - - switch (procarch) - { - case PROCESSOR_ARCHITECTURE_INTEL: - { - arch = "x86"; - break; - } - - case PROCESSOR_ARCHITECTURE_IA64: - { - arch = "x86"; - break; - } - - case PROCESSOR_ARCHITECTURE_AMD64: - { - arch = "x86"; - break; - } - - case PROCESSOR_ARCHITECTURE_UNKNOWN: - { - arch = "x86"; - break; - } - - default: - { - arch = NULL; - break; - } - } - - if (arch != NULL) - { - strcpy(buf->machine, arch); - } - else - { - sprintf(buf->machine, "unknown(0x%x)", procarch); - } - } - - return 0; -} - - -#endif diff --git a/src/backend/distributed/worker/task_tracker.c b/src/backend/distributed/worker/task_tracker.c index 5d7bbe4fe..5858ef446 100644 --- a/src/backend/distributed/worker/task_tracker.c +++ b/src/backend/distributed/worker/task_tracker.c @@ -30,6 +30,7 @@ #include #include "commands/dbcommands.h" +#include "distributed/citus_safe_lib.h" #include "distributed/multi_client_executor.h" #include "distributed/multi_server_executor.h" #include "distributed/task_tracker.h" @@ -117,10 +118,11 @@ TaskTrackerRegister(void) worker.bgw_flags = BGWORKER_SHMEM_ACCESS; worker.bgw_start_time = BgWorkerStart_ConsistentState; worker.bgw_restart_time = 1; - snprintf(worker.bgw_library_name, BGW_MAXLEN, "citus"); - snprintf(worker.bgw_function_name, BGW_MAXLEN, "TaskTrackerMain"); + strcpy_s(worker.bgw_library_name, sizeof(worker.bgw_library_name), "citus"); + strcpy_s(worker.bgw_function_name, sizeof(worker.bgw_function_name), + "TaskTrackerMain"); worker.bgw_notify_pid = 0; - snprintf(worker.bgw_name, BGW_MAXLEN, "task tracker"); + strcpy_s(worker.bgw_name, sizeof(worker.bgw_name), "task tracker"); RegisterBackgroundWorker(&worker); } @@ -702,7 +704,7 @@ SchedulableTaskPriorityQueue(HTAB *WorkerTasksHash) } /* now order elements in the queue according to our sorting criterion */ - qsort(priorityQueue, queueSize, WORKER_TASK_SIZE, CompareTasksByTime); + SafeQsort(priorityQueue, queueSize, WORKER_TASK_SIZE, CompareTasksByTime); return priorityQueue; } diff --git a/src/backend/distributed/worker/worker_data_fetch_protocol.c b/src/backend/distributed/worker/worker_data_fetch_protocol.c index c6d72d549..9e3a364f1 100644 --- a/src/backend/distributed/worker/worker_data_fetch_protocol.c +++ b/src/backend/distributed/worker/worker_data_fetch_protocol.c @@ -226,7 +226,7 @@ ReceiveRegularFile(const char *nodeName, uint32 nodePort, const char *nodeUser, bool copyDone = false; /* create local file to append remote data to */ - snprintf(filename, MAXPGPATH, "%s", filePath->data); + strlcpy(filename, filePath->data, MAXPGPATH); int32 fileDescriptor = BasicOpenFilePerm(filename, fileFlags, fileMode); if (fileDescriptor < 0) diff --git a/src/include/distributed/citus_safe_lib.h b/src/include/distributed/citus_safe_lib.h new file mode 100644 index 000000000..f1552fbe1 --- /dev/null +++ b/src/include/distributed/citus_safe_lib.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * safe_lib.h + * + * This file contains helper functions to expand on the _s functions from + * safestringlib. + * + * Copyright (c) Citus Data, Inc. + * + *------------------------------------------------------------------------- + */ + +#ifndef CITUS_safe_lib_H +#define CITUS_safe_lib_H + +#include "postgres.h" + +#include "safe_lib.h" + +extern void ereport_constraint_handler(const char *message, void *pointer, errno_t error); +extern int64 SafeStringToInt64(const char *str); +extern uint64 SafeStringToUint64(const char *str); +extern void SafeQsort(void *ptr, rsize_t count, rsize_t size, + int (*comp)(const void *, const void *)); +void * SafeBsearch(const void *key, const void *ptr, rsize_t count, rsize_t size, + int (*comp)(const void *, const void *)); +int SafeSnprintf(char *str, rsize_t count, const char *fmt, ...); + +#endif From 7d24cebc8003ec058551ff56f3a40bd6987545cd Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Tue, 25 Feb 2020 15:04:35 +0100 Subject: [PATCH 3/4] Add pg11 snprintf file to repo for use in pg11 when it's not compiled --- .gitattributes | 1 + src/backend/distributed/utils/pg11_snprintf.c | 1169 +++++++++++++++++ 2 files changed, 1170 insertions(+) create mode 100644 src/backend/distributed/utils/pg11_snprintf.c diff --git a/.gitattributes b/.gitattributes index 264e4fe69..37f1ef2bb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -26,6 +26,7 @@ configure -whitespace # except these exceptions... src/backend/distributed/utils/citus_outfuncs.c -citus-style +src/backend/distributed/utils/pg11_snprintf.c -citus-style src/backend/distributed/deparser/ruleutils_10.c -citus-style src/backend/distributed/deparser/ruleutils_11.c -citus-style src/backend/distributed/deparser/ruleutils_12.c -citus-style diff --git a/src/backend/distributed/utils/pg11_snprintf.c b/src/backend/distributed/utils/pg11_snprintf.c new file mode 100644 index 000000000..54b32de60 --- /dev/null +++ b/src/backend/distributed/utils/pg11_snprintf.c @@ -0,0 +1,1169 @@ +/* + * Copyright (c) 1983, 1995, 1996 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * src/port/snprintf.c + */ + +#include "c.h" + +#include +#ifdef _MSC_VER +#include /* for _isnan */ +#endif +#include +#include +#ifndef WIN32 +#include +#endif +#include + +/* + * We used to use the platform's NL_ARGMAX here, but that's a bad idea, + * first because the point of this module is to remove platform dependencies + * not perpetuate them, and second because some platforms use ridiculously + * large values, leading to excessive stack consumption in dopr(). + */ +#define PG_NL_ARGMAX 31 + + +/* + * SNPRINTF, VSNPRINTF and friends + * + * These versions have been grabbed off the net. They have been + * cleaned up to compile properly and support for most of the C99 + * specification has been added. Remaining unimplemented features are: + * + * 1. No locale support: the radix character is always '.' and the ' + * (single quote) format flag is ignored. + * + * 2. No support for the "%n" format specification. + * + * 3. No support for wide characters ("lc" and "ls" formats). + * + * 4. No support for "long double" ("Lf" and related formats). + * + * 5. Space and '#' flags are not implemented. + * + * + * Historically the result values of sprintf/snprintf varied across platforms. + * This implementation now follows the C99 standard: + * + * 1. -1 is returned if an error is detected in the format string, or if + * a write to the target stream fails (as reported by fwrite). Note that + * overrunning snprintf's target buffer is *not* an error. + * + * 2. For successful writes to streams, the actual number of bytes written + * to the stream is returned. + * + * 3. For successful sprintf/snprintf, the number of bytes that would have + * been written to an infinite-size buffer (excluding the trailing '\0') + * is returned. snprintf will truncate its output to fit in the buffer + * (ensuring a trailing '\0' unless count == 0), but this is not reflected + * in the function result. + * + * snprintf buffer overrun can be detected by checking for function result + * greater than or equal to the supplied count. + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point. (now it does ... tgl) + **************************************************************/ + +/* Prevent recursion */ +#undef vsnprintf +#undef snprintf +#undef sprintf +#undef vfprintf +#undef fprintf +#undef printf + +/* + * Info about where the formatted output is going. + * + * dopr and subroutines will not write at/past bufend, but snprintf + * reserves one byte, ensuring it may place the trailing '\0' there. + * + * In snprintf, we use nchars to count the number of bytes dropped on the + * floor due to buffer overrun. The correct result of snprintf is thus + * (bufptr - bufstart) + nchars. (This isn't as inconsistent as it might + * seem: nchars is the number of emitted bytes that are not in the buffer now, + * either because we sent them to the stream or because we couldn't fit them + * into the buffer to begin with.) + */ +typedef struct +{ + char *bufptr; /* next buffer output position */ + char *bufstart; /* first buffer element */ + char *bufend; /* last+1 buffer element, or NULL */ + /* bufend == NULL is for sprintf, where we assume buf is big enough */ + FILE *stream; /* eventual output destination, or NULL */ + int nchars; /* # chars sent to stream, or dropped */ + bool failed; /* call is a failure; errno is set */ +} PrintfTarget; + +/* + * Info about the type and value of a formatting parameter. Note that we + * don't currently support "long double", "wint_t", or "wchar_t *" data, + * nor the '%n' formatting code; else we'd need more types. Also, at this + * level we need not worry about signed vs unsigned values. + */ +typedef enum +{ + ATYPE_NONE = 0, + ATYPE_INT, + ATYPE_LONG, + ATYPE_LONGLONG, + ATYPE_DOUBLE, + ATYPE_CHARPTR +} PrintfArgType; + +typedef union +{ + int i; + long l; + int64 ll; + double d; + char *cptr; +} PrintfArgValue; + + +static void flushbuffer(PrintfTarget *target); +static void dopr(PrintfTarget *target, const char *format, va_list args); + + +int +pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) +{ + PrintfTarget target; + char onebyte[1]; + + /* + * C99 allows the case str == NULL when count == 0. Rather than + * special-casing this situation further down, we substitute a one-byte + * local buffer. Callers cannot tell, since the function result doesn't + * depend on count. + */ + if (count == 0) + { + str = onebyte; + count = 1; + } + target.bufstart = target.bufptr = str; + target.bufend = str + count - 1; + target.stream = NULL; + target.nchars = 0; + target.failed = false; + dopr(&target, fmt, args); + *(target.bufptr) = '\0'; + return target.failed ? -1 : (target.bufptr - target.bufstart + + target.nchars); +} + +int +pg_snprintf(char *str, size_t count, const char *fmt,...) +{ + int len; + va_list args; + + va_start(args, fmt); + len = pg_vsnprintf(str, count, fmt, args); + va_end(args); + return len; +} + +static int +pg_vsprintf(char *str, const char *fmt, va_list args) +{ + PrintfTarget target; + + target.bufstart = target.bufptr = str; + target.bufend = NULL; + target.stream = NULL; + target.nchars = 0; /* not really used in this case */ + target.failed = false; + dopr(&target, fmt, args); + *(target.bufptr) = '\0'; + return target.failed ? -1 : (target.bufptr - target.bufstart + + target.nchars); +} + +int +pg_sprintf(char *str, const char *fmt,...) +{ + int len; + va_list args; + + va_start(args, fmt); + len = pg_vsprintf(str, fmt, args); + va_end(args); + return len; +} + +int +pg_vfprintf(FILE *stream, const char *fmt, va_list args) +{ + PrintfTarget target; + char buffer[1024]; /* size is arbitrary */ + + if (stream == NULL) + { + errno = EINVAL; + return -1; + } + target.bufstart = target.bufptr = buffer; + target.bufend = buffer + sizeof(buffer); /* use the whole buffer */ + target.stream = stream; + target.nchars = 0; + target.failed = false; + dopr(&target, fmt, args); + /* dump any remaining buffer contents */ + flushbuffer(&target); + return target.failed ? -1 : target.nchars; +} + +int +pg_fprintf(FILE *stream, const char *fmt,...) +{ + int len; + va_list args; + + va_start(args, fmt); + len = pg_vfprintf(stream, fmt, args); + va_end(args); + return len; +} + +int +pg_printf(const char *fmt,...) +{ + int len; + va_list args; + + va_start(args, fmt); + len = pg_vfprintf(stdout, fmt, args); + va_end(args); + return len; +} + +/* + * Attempt to write the entire buffer to target->stream; discard the entire + * buffer in any case. Call this only when target->stream is defined. + */ +static void +flushbuffer(PrintfTarget *target) +{ + size_t nc = target->bufptr - target->bufstart; + + /* + * Don't write anything if we already failed; this is to ensure we + * preserve the original failure's errno. + */ + if (!target->failed && nc > 0) + { + size_t written; + + written = fwrite(target->bufstart, 1, nc, target->stream); + target->nchars += written; + if (written != nc) + target->failed = true; + } + target->bufptr = target->bufstart; +} + + +static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, + int pointflag, PrintfTarget *target); +static void fmtptr(void *value, PrintfTarget *target); +static void fmtint(int64 value, char type, int forcesign, + int leftjust, int minlen, int zpad, int precision, int pointflag, + PrintfTarget *target); +static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target); +static void fmtfloat(double value, char type, int forcesign, + int leftjust, int minlen, int zpad, int precision, int pointflag, + PrintfTarget *target); +static void dostr(const char *str, int slen, PrintfTarget *target); +static void dopr_outch(int c, PrintfTarget *target); +static int adjust_sign(int is_negative, int forcesign, int *signvalue); +static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen); +static void leading_pad(int zpad, int *signvalue, int *padlen, + PrintfTarget *target); +static void trailing_pad(int *padlen, PrintfTarget *target); + + +/* + * dopr(): poor man's version of doprintf + */ +static void +dopr(PrintfTarget *target, const char *format, va_list args) +{ + const char *format_start = format; + int ch; + bool have_dollar; + bool have_non_dollar; + bool have_star; + bool afterstar; + int accum; + int longlongflag; + int longflag; + int pointflag; + int leftjust; + int fieldwidth; + int precision; + int zpad; + int forcesign; + int last_dollar; + int fmtpos; + int cvalue; + int64 numvalue; + double fvalue; + char *strvalue; + int i; + PrintfArgType argtypes[PG_NL_ARGMAX + 1]; + PrintfArgValue argvalues[PG_NL_ARGMAX + 1]; + + /* + * Parse the format string to determine whether there are %n$ format + * specs, and identify the types and order of the format parameters. + */ + have_dollar = have_non_dollar = false; + last_dollar = 0; + MemSet(argtypes, 0, sizeof(argtypes)); + + while ((ch = *format++) != '\0') + { + if (ch != '%') + continue; + longflag = longlongflag = pointflag = 0; + fmtpos = accum = 0; + afterstar = false; +nextch1: + ch = *format++; + if (ch == '\0') + break; /* illegal, but we don't complain */ + switch (ch) + { + case '-': + case '+': + goto nextch1; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + accum = accum * 10 + (ch - '0'); + goto nextch1; + case '.': + pointflag = 1; + accum = 0; + goto nextch1; + case '*': + if (afterstar) + have_non_dollar = true; /* multiple stars */ + afterstar = true; + accum = 0; + goto nextch1; + case '$': + have_dollar = true; + if (accum <= 0 || accum > PG_NL_ARGMAX) + goto bad_format; + if (afterstar) + { + if (argtypes[accum] && + argtypes[accum] != ATYPE_INT) + goto bad_format; + argtypes[accum] = ATYPE_INT; + last_dollar = Max(last_dollar, accum); + afterstar = false; + } + else + fmtpos = accum; + accum = 0; + goto nextch1; + case 'l': + if (longflag) + longlongflag = 1; + else + longflag = 1; + goto nextch1; + case 'z': +#if SIZEOF_SIZE_T == 8 +#ifdef HAVE_LONG_INT_64 + longflag = 1; +#elif defined(HAVE_LONG_LONG_INT_64) + longlongflag = 1; +#else +#error "Don't know how to print 64bit integers" +#endif +#else + /* assume size_t is same size as int */ +#endif + goto nextch1; + case 'h': + case '\'': + /* ignore these */ + goto nextch1; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + if (fmtpos) + { + PrintfArgType atype; + + if (longlongflag) + atype = ATYPE_LONGLONG; + else if (longflag) + atype = ATYPE_LONG; + else + atype = ATYPE_INT; + if (argtypes[fmtpos] && + argtypes[fmtpos] != atype) + goto bad_format; + argtypes[fmtpos] = atype; + last_dollar = Max(last_dollar, fmtpos); + } + else + have_non_dollar = true; + break; + case 'c': + if (fmtpos) + { + if (argtypes[fmtpos] && + argtypes[fmtpos] != ATYPE_INT) + goto bad_format; + argtypes[fmtpos] = ATYPE_INT; + last_dollar = Max(last_dollar, fmtpos); + } + else + have_non_dollar = true; + break; + case 's': + case 'p': + if (fmtpos) + { + if (argtypes[fmtpos] && + argtypes[fmtpos] != ATYPE_CHARPTR) + goto bad_format; + argtypes[fmtpos] = ATYPE_CHARPTR; + last_dollar = Max(last_dollar, fmtpos); + } + else + have_non_dollar = true; + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (fmtpos) + { + if (argtypes[fmtpos] && + argtypes[fmtpos] != ATYPE_DOUBLE) + goto bad_format; + argtypes[fmtpos] = ATYPE_DOUBLE; + last_dollar = Max(last_dollar, fmtpos); + } + else + have_non_dollar = true; + break; + case '%': + break; + } + + /* + * If we finish the spec with afterstar still set, there's a + * non-dollar star in there. + */ + if (afterstar) + have_non_dollar = true; + } + + /* Per spec, you use either all dollar or all not. */ + if (have_dollar && have_non_dollar) + goto bad_format; + + /* + * In dollar mode, collect the arguments in physical order. + */ + for (i = 1; i <= last_dollar; i++) + { + switch (argtypes[i]) + { + case ATYPE_NONE: + goto bad_format; + case ATYPE_INT: + argvalues[i].i = va_arg(args, int); + break; + case ATYPE_LONG: + argvalues[i].l = va_arg(args, long); + break; + case ATYPE_LONGLONG: + argvalues[i].ll = va_arg(args, int64); + break; + case ATYPE_DOUBLE: + argvalues[i].d = va_arg(args, double); + break; + case ATYPE_CHARPTR: + argvalues[i].cptr = va_arg(args, char *); + break; + } + } + + /* + * At last we can parse the format for real. + */ + format = format_start; + while ((ch = *format++) != '\0') + { + if (target->failed) + break; + + if (ch != '%') + { + dopr_outch(ch, target); + continue; + } + fieldwidth = precision = zpad = leftjust = forcesign = 0; + longflag = longlongflag = pointflag = 0; + fmtpos = accum = 0; + have_star = afterstar = false; +nextch2: + ch = *format++; + if (ch == '\0') + break; /* illegal, but we don't complain */ + switch (ch) + { + case '-': + leftjust = 1; + goto nextch2; + case '+': + forcesign = 1; + goto nextch2; + case '0': + /* set zero padding if no nonzero digits yet */ + if (accum == 0 && !pointflag) + zpad = '0'; + /* FALL THRU */ + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + accum = accum * 10 + (ch - '0'); + goto nextch2; + case '.': + if (have_star) + have_star = false; + else + fieldwidth = accum; + pointflag = 1; + accum = 0; + goto nextch2; + case '*': + if (have_dollar) + { + /* process value after reading n$ */ + afterstar = true; + } + else + { + /* fetch and process value now */ + int starval = va_arg(args, int); + + if (pointflag) + { + precision = starval; + if (precision < 0) + { + precision = 0; + pointflag = 0; + } + } + else + { + fieldwidth = starval; + if (fieldwidth < 0) + { + leftjust = 1; + fieldwidth = -fieldwidth; + } + } + } + have_star = true; + accum = 0; + goto nextch2; + case '$': + if (afterstar) + { + /* fetch and process star value */ + int starval = argvalues[accum].i; + + if (pointflag) + { + precision = starval; + if (precision < 0) + { + precision = 0; + pointflag = 0; + } + } + else + { + fieldwidth = starval; + if (fieldwidth < 0) + { + leftjust = 1; + fieldwidth = -fieldwidth; + } + } + afterstar = false; + } + else + fmtpos = accum; + accum = 0; + goto nextch2; + case 'l': + if (longflag) + longlongflag = 1; + else + longflag = 1; + goto nextch2; + case 'z': +#if SIZEOF_SIZE_T == 8 +#ifdef HAVE_LONG_INT_64 + longflag = 1; +#elif defined(HAVE_LONG_LONG_INT_64) + longlongflag = 1; +#else +#error "Don't know how to print 64bit integers" +#endif +#else + /* assume size_t is same size as int */ +#endif + goto nextch2; + case 'h': + case '\'': + /* ignore these */ + goto nextch2; + case 'd': + case 'i': + if (!have_star) + { + if (pointflag) + precision = accum; + else + fieldwidth = accum; + } + if (have_dollar) + { + if (longlongflag) + numvalue = argvalues[fmtpos].ll; + else if (longflag) + numvalue = argvalues[fmtpos].l; + else + numvalue = argvalues[fmtpos].i; + } + else + { + if (longlongflag) + numvalue = va_arg(args, int64); + else if (longflag) + numvalue = va_arg(args, long); + else + numvalue = va_arg(args, int); + } + fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad, + precision, pointflag, target); + break; + case 'o': + case 'u': + case 'x': + case 'X': + if (!have_star) + { + if (pointflag) + precision = accum; + else + fieldwidth = accum; + } + if (have_dollar) + { + if (longlongflag) + numvalue = (uint64) argvalues[fmtpos].ll; + else if (longflag) + numvalue = (unsigned long) argvalues[fmtpos].l; + else + numvalue = (unsigned int) argvalues[fmtpos].i; + } + else + { + if (longlongflag) + numvalue = (uint64) va_arg(args, int64); + else if (longflag) + numvalue = (unsigned long) va_arg(args, long); + else + numvalue = (unsigned int) va_arg(args, int); + } + fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad, + precision, pointflag, target); + break; + case 'c': + if (!have_star) + { + if (pointflag) + precision = accum; + else + fieldwidth = accum; + } + if (have_dollar) + cvalue = (unsigned char) argvalues[fmtpos].i; + else + cvalue = (unsigned char) va_arg(args, int); + fmtchar(cvalue, leftjust, fieldwidth, target); + break; + case 's': + if (!have_star) + { + if (pointflag) + precision = accum; + else + fieldwidth = accum; + } + if (have_dollar) + strvalue = argvalues[fmtpos].cptr; + else + strvalue = va_arg(args, char *); + /* Whine if someone tries to print a NULL string */ + Assert(strvalue != NULL); + fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag, + target); + break; + case 'p': + /* fieldwidth/leftjust are ignored ... */ + if (have_dollar) + strvalue = argvalues[fmtpos].cptr; + else + strvalue = va_arg(args, char *); + fmtptr((void *) strvalue, target); + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (!have_star) + { + if (pointflag) + precision = accum; + else + fieldwidth = accum; + } + if (have_dollar) + fvalue = argvalues[fmtpos].d; + else + fvalue = va_arg(args, double); + fmtfloat(fvalue, ch, forcesign, leftjust, + fieldwidth, zpad, + precision, pointflag, + target); + break; + case '%': + dopr_outch('%', target); + break; + } + } + + return; + +bad_format: + errno = EINVAL; + target->failed = true; +} + +static void +fmtstr(char *value, int leftjust, int minlen, int maxwidth, + int pointflag, PrintfTarget *target) +{ + int padlen, + vallen; /* amount to pad */ + + /* + * If a maxwidth (precision) is specified, we must not fetch more bytes + * than that. + */ + if (pointflag) + vallen = strnlen(value, maxwidth); + else + vallen = strlen(value); + + adjust_padlen(minlen, vallen, leftjust, &padlen); + + while (padlen > 0) + { + dopr_outch(' ', target); + --padlen; + } + + dostr(value, vallen, target); + + trailing_pad(&padlen, target); +} + +static void +fmtptr(void *value, PrintfTarget *target) +{ + int vallen; + char convert[64]; + + /* we rely on regular C library's sprintf to do the basic conversion */ + vallen = sprintf(convert, "%p", value); + if (vallen < 0) + target->failed = true; + else + dostr(convert, vallen, target); +} + +static void +fmtint(int64 value, char type, int forcesign, int leftjust, + int minlen, int zpad, int precision, int pointflag, + PrintfTarget *target) +{ + uint64 base; + int dosign; + const char *cvt = "0123456789abcdef"; + int signvalue = 0; + char convert[64]; + int vallen = 0; + int padlen = 0; /* amount to pad */ + int zeropad; /* extra leading zeroes */ + + switch (type) + { + case 'd': + case 'i': + base = 10; + dosign = 1; + break; + case 'o': + base = 8; + dosign = 0; + break; + case 'u': + base = 10; + dosign = 0; + break; + case 'x': + base = 16; + dosign = 0; + break; + case 'X': + cvt = "0123456789ABCDEF"; + base = 16; + dosign = 0; + break; + default: + return; /* keep compiler quiet */ + } + + /* Handle +/- */ + if (dosign && adjust_sign((value < 0), forcesign, &signvalue)) + value = -value; + + /* + * SUS: the result of converting 0 with an explicit precision of 0 is no + * characters + */ + if (value == 0 && pointflag && precision == 0) + vallen = 0; + else + { + /* make integer string */ + uint64 uvalue = (uint64) value; + + do + { + convert[vallen++] = cvt[uvalue % base]; + uvalue = uvalue / base; + } while (uvalue); + } + + zeropad = Max(0, precision - vallen); + + adjust_padlen(minlen, vallen + zeropad, leftjust, &padlen); + + leading_pad(zpad, &signvalue, &padlen, target); + + while (zeropad-- > 0) + dopr_outch('0', target); + + while (vallen > 0) + dopr_outch(convert[--vallen], target); + + trailing_pad(&padlen, target); +} + +static void +fmtchar(int value, int leftjust, int minlen, PrintfTarget *target) +{ + int padlen = 0; /* amount to pad */ + + adjust_padlen(minlen, 1, leftjust, &padlen); + + while (padlen > 0) + { + dopr_outch(' ', target); + --padlen; + } + + dopr_outch(value, target); + + trailing_pad(&padlen, target); +} + +static void +fmtfloat(double value, char type, int forcesign, int leftjust, + int minlen, int zpad, int precision, int pointflag, + PrintfTarget *target) +{ + int signvalue = 0; + int prec; + int vallen; + char fmt[32]; + char convert[1024]; + int zeropadlen = 0; /* amount to pad with zeroes */ + int padlen = 0; /* amount to pad with spaces */ + + /* + * We rely on the regular C library's sprintf to do the basic conversion, + * then handle padding considerations here. + * + * The dynamic range of "double" is about 1E+-308 for IEEE math, and not + * too wildly more than that with other hardware. In "f" format, sprintf + * could therefore generate at most 308 characters to the left of the + * decimal point; while we need to allow the precision to get as high as + * 308+17 to ensure that we don't truncate significant digits from very + * small values. To handle both these extremes, we use a buffer of 1024 + * bytes and limit requested precision to 350 digits; this should prevent + * buffer overrun even with non-IEEE math. If the original precision + * request was more than 350, separately pad with zeroes. + */ + if (precision < 0) /* cover possible overflow of "accum" */ + precision = 0; + prec = Min(precision, 350); + + if (pointflag) + { + if (sprintf(fmt, "%%.%d%c", prec, type) < 0) + goto fail; + zeropadlen = precision - prec; + } + else if (sprintf(fmt, "%%%c", type) < 0) + goto fail; + + if (!isnan(value) && adjust_sign((value < 0), forcesign, &signvalue)) + value = -value; + + vallen = sprintf(convert, fmt, value); + if (vallen < 0) + goto fail; + + /* If it's infinity or NaN, forget about doing any zero-padding */ + if (zeropadlen > 0 && !isdigit((unsigned char) convert[vallen - 1])) + zeropadlen = 0; + + adjust_padlen(minlen, vallen + zeropadlen, leftjust, &padlen); + + leading_pad(zpad, &signvalue, &padlen, target); + + if (zeropadlen > 0) + { + /* If 'e' or 'E' format, inject zeroes before the exponent */ + char *epos = strrchr(convert, 'e'); + + if (!epos) + epos = strrchr(convert, 'E'); + if (epos) + { + /* pad after exponent */ + dostr(convert, epos - convert, target); + while (zeropadlen-- > 0) + dopr_outch('0', target); + dostr(epos, vallen - (epos - convert), target); + } + else + { + /* no exponent, pad after the digits */ + dostr(convert, vallen, target); + while (zeropadlen-- > 0) + dopr_outch('0', target); + } + } + else + { + /* no zero padding, just emit the number as-is */ + dostr(convert, vallen, target); + } + + trailing_pad(&padlen, target); + return; + +fail: + target->failed = true; +} + +static void +dostr(const char *str, int slen, PrintfTarget *target) +{ + while (slen > 0) + { + int avail; + + if (target->bufend != NULL) + avail = target->bufend - target->bufptr; + else + avail = slen; + if (avail <= 0) + { + /* buffer full, can we dump to stream? */ + if (target->stream == NULL) + { + target->nchars += slen; /* no, lose the data */ + return; + } + flushbuffer(target); + continue; + } + avail = Min(avail, slen); + memmove(target->bufptr, str, avail); + target->bufptr += avail; + str += avail; + slen -= avail; + } +} + +static void +dopr_outch(int c, PrintfTarget *target) +{ + if (target->bufend != NULL && target->bufptr >= target->bufend) + { + /* buffer full, can we dump to stream? */ + if (target->stream == NULL) + { + target->nchars++; /* no, lose the data */ + return; + } + flushbuffer(target); + } + *(target->bufptr++) = c; +} + + +static int +adjust_sign(int is_negative, int forcesign, int *signvalue) +{ + if (is_negative) + { + *signvalue = '-'; + return true; + } + else if (forcesign) + *signvalue = '+'; + return false; +} + + +static void +adjust_padlen(int minlen, int vallen, int leftjust, int *padlen) +{ + *padlen = minlen - vallen; + if (*padlen < 0) + *padlen = 0; + if (leftjust) + *padlen = -(*padlen); +} + + +static void +leading_pad(int zpad, int *signvalue, int *padlen, PrintfTarget *target) +{ + if (*padlen > 0 && zpad) + { + if (*signvalue) + { + dopr_outch(*signvalue, target); + --(*padlen); + *signvalue = 0; + } + while (*padlen > 0) + { + dopr_outch(zpad, target); + --(*padlen); + } + } + while (*padlen > (*signvalue != 0)) + { + dopr_outch(' ', target); + --(*padlen); + } + if (*signvalue) + { + dopr_outch(*signvalue, target); + if (*padlen > 0) + --(*padlen); + else if (*padlen < 0) + ++(*padlen); + } +} + + +static void +trailing_pad(int *padlen, PrintfTarget *target) +{ + while (*padlen < 0) + { + dopr_outch(' ', target); + ++(*padlen); + } +} From 62bf571cedcfdf4451614b8520448d105df07045 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Tue, 25 Feb 2020 15:19:20 +0100 Subject: [PATCH 4/4] Make SafeSnprintf work on PG11 --- .../distributed/utils/citus_safe_lib.c | 19 +++++++---- src/backend/distributed/utils/pg11_snprintf.c | 34 +++++++++++++------ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/backend/distributed/utils/citus_safe_lib.c b/src/backend/distributed/utils/citus_safe_lib.c index 2e9875051..56ea7cdc7 100644 --- a/src/backend/distributed/utils/citus_safe_lib.c +++ b/src/backend/distributed/utils/citus_safe_lib.c @@ -12,11 +12,6 @@ *------------------------------------------------------------------------- */ -/* In PG 11 pg_vsnprintf is not exported unless you set this define */ -#if PG_VERSION_NUM < 120000 -#define USE_REPL_SNPRINTF 1 -#endif - #include "postgres.h" #include "safe_lib.h" @@ -26,6 +21,18 @@ #include "distributed/citus_safe_lib.h" #include "lib/stringinfo.h" +/* + * In PG 11 pg_vsnprintf is not exported and compiled in most cases, in that + * case use the copied one from pg11_snprintf.c + * NOTE: Whenever removing this section also remove pg11_snprintf.c + */ +#if PG_VERSION_NUM < 120000 +extern int pg11_vsnprintf(char *str, size_t count, const char *fmt, va_list args); +#define citus_vsnprintf pg11_vsnprintf +#else +#define citus_vsnprintf pg_vsnprintf +#endif + /* * ereport_constraint_handler is a constraint handler that calls ereport. A @@ -296,7 +303,7 @@ SafeSnprintf(char *restrict buffer, rsize_t bufsz, const char *restrict format, va_list args; va_start(args, format); - size_t result = pg_vsnprintf(buffer, bufsz, format, args); + size_t result = citus_vsnprintf(buffer, bufsz, format, args); va_end(args); return result; } diff --git a/src/backend/distributed/utils/pg11_snprintf.c b/src/backend/distributed/utils/pg11_snprintf.c index 54b32de60..0b2ca14ec 100644 --- a/src/backend/distributed/utils/pg11_snprintf.c +++ b/src/backend/distributed/utils/pg11_snprintf.c @@ -44,6 +44,9 @@ #endif #include +/* Include this file only for PG11 and only when USE_REPL_SNPRINTF is not set */ +#if PG_VERSION_NUM < 120000 +#ifndef USE_REPL_SNPRINTF /* * We used to use the platform's NL_ARGMAX here, but that's a bad idea, * first because the point of this module is to remove platform dependencies @@ -108,6 +111,13 @@ #undef fprintf #undef printf +extern int pg11_vsnprintf(char *str, size_t count, const char *fmt, va_list args); +extern int pg11_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); +extern int pg11_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg11_vfprintf(FILE *stream, const char *fmt, va_list args); +extern int pg11_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg11_printf(const char *fmt,...) pg_attribute_printf(1, 2); + /* * Info about where the formatted output is going. * @@ -163,7 +173,7 @@ static void dopr(PrintfTarget *target, const char *format, va_list args); int -pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) +pg11_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { PrintfTarget target; char onebyte[1]; @@ -191,19 +201,19 @@ pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) } int -pg_snprintf(char *str, size_t count, const char *fmt,...) +pg11_snprintf(char *str, size_t count, const char *fmt,...) { int len; va_list args; va_start(args, fmt); - len = pg_vsnprintf(str, count, fmt, args); + len = pg11_vsnprintf(str, count, fmt, args); va_end(args); return len; } static int -pg_vsprintf(char *str, const char *fmt, va_list args) +pg11_vsprintf(char *str, const char *fmt, va_list args) { PrintfTarget target; @@ -219,19 +229,19 @@ pg_vsprintf(char *str, const char *fmt, va_list args) } int -pg_sprintf(char *str, const char *fmt,...) +pg11_sprintf(char *str, const char *fmt,...) { int len; va_list args; va_start(args, fmt); - len = pg_vsprintf(str, fmt, args); + len = pg11_vsprintf(str, fmt, args); va_end(args); return len; } int -pg_vfprintf(FILE *stream, const char *fmt, va_list args) +pg11_vfprintf(FILE *stream, const char *fmt, va_list args) { PrintfTarget target; char buffer[1024]; /* size is arbitrary */ @@ -253,25 +263,25 @@ pg_vfprintf(FILE *stream, const char *fmt, va_list args) } int -pg_fprintf(FILE *stream, const char *fmt,...) +pg11_fprintf(FILE *stream, const char *fmt,...) { int len; va_list args; va_start(args, fmt); - len = pg_vfprintf(stream, fmt, args); + len = pg11_vfprintf(stream, fmt, args); va_end(args); return len; } int -pg_printf(const char *fmt,...) +pg11_printf(const char *fmt,...) { int len; va_list args; va_start(args, fmt); - len = pg_vfprintf(stdout, fmt, args); + len = pg11_vfprintf(stdout, fmt, args); va_end(args); return len; } @@ -1167,3 +1177,5 @@ trailing_pad(int *padlen, PrintfTarget *target) ++(*padlen); } } +#endif /* USE_REPL_SNPRINTF */ +#endif /* PG_VERSION_NUM < 120000 */