diff --git a/CHANGELOG.md b/CHANGELOG.md index ea5449f..707fc6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # safestringlib +## v1.3.0: + + - parse_format: fail on unrecognized modifier + - strcpyfldin_s: avoid read over slen + - strremovews_s: check lower bound + - strcspn_s: check smax first in read + - strcmpfld_s: do not fill indicator on equal string + - fix wchar bound checking + - avoid redefining RSIZE_MAX + - cmake: BUILD_OPT_DEFAULT type should be bool + - cmake: do not probe for C++ + - cmake: update minimal version to 3.15 + - unittests: do not crash on len > RSIZE_MAX_STR + - align str rsize with the mem rsize + - workflows: upgrade actions version + - workflows: set top level read permissions + - silence unused parameters warning in error handlers + - safeclib/strpbrk_s.c: check string boundaries + - add Cmake support for creating a Debian package + - remove makefile it does not work anymore + - requires cmake version 3.5 or higer + - workflows: add codeql testing + - add security policy file + ## v1.2.0: - unittests: add test counter to strisdigit_s and strismixed_s.c - fix out of bounds check in stris_xxx functions diff --git a/include/safe_lib.h b/include/safe_lib.h index dae884d..a7d6fa5 100644 --- a/include/safe_lib.h +++ b/include/safe_lib.h @@ -15,9 +15,9 @@ extern "C" { /* Define safe_lib version number */ #define SAFEC_VERSION_MAJOR 1 -#define SAFEC_VERSION_MINOR 2 +#define SAFEC_VERSION_MINOR 3 #define SAFEC_VERSION_PATCH 0 -#define SAFEC_VERSION_STRING "1.2.0" +#define SAFEC_VERSION_STRING "1.3.0" #define SAFEC_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) #define SAFEC_VERSION \ diff --git a/safeclib/snprintf_support.c b/safeclib/snprintf_support.c index d7a4b67..2bc9f0d 100644 --- a/safeclib/snprintf_support.c +++ b/safeclib/snprintf_support.c @@ -29,8 +29,10 @@ #define CHK_FORMAT(X,Y) (((X)==(Y))?1:0) - -unsigned int +/* + * Partial parser for sanity checks + */ +static unsigned int parse_format(const char *format, char pformatList[], unsigned int maxFormats) { unsigned int numFormats = 0; @@ -167,7 +169,7 @@ parse_format(const char *format, char pformatList[], unsigned int maxFormats) printf("failed to recognize format string ["); for (;start 0 && *src) { + while (dmax > 0 && slen && *src) { if (dest == overlap_bumper) { dmax = orig_dmax; @@ -142,13 +142,14 @@ strcpyfldin_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) } dmax--; + slen--; *dest++ = *src++; } } else { overlap_bumper = dest; - while (dmax > 0 && *src) { + while (dmax > 0 && slen && *src) { if (src == overlap_bumper) { dmax = orig_dmax; @@ -164,6 +165,7 @@ strcpyfldin_s (char *dest, rsize_t dmax, const char *src, rsize_t slen) } dmax--; + slen--; *dest++ = *src++; } } diff --git a/safeclib/strcspn_s.c b/safeclib/strcspn_s.c index c0fbbae..53d3fdf 100644 --- a/safeclib/strcspn_s.c +++ b/safeclib/strcspn_s.c @@ -121,7 +121,7 @@ strcspn_s (const char *dest, rsize_t dmax, */ smax = slen; scan2 = src; - while (*scan2 && smax) { + while (smax && *scan2) { if (*dest == *scan2) { return RCNEGATE(EOK); diff --git a/safeclib/strremovews_s.c b/safeclib/strremovews_s.c index 1ad4ba4..c90411a 100644 --- a/safeclib/strremovews_s.c +++ b/safeclib/strremovews_s.c @@ -129,7 +129,7 @@ strremovews_s (char *dest, rsize_t dmax) * strip trailing whitespace */ dest = orig_end; - while ((*dest == ' ') || (*dest == '\t')) { + while ((dest >= orig_dest) && ((*dest == ' ') || (*dest == '\t'))) { *dest = '\0'; dest--; } diff --git a/safeclib/wcpcpy_s.c b/safeclib/wcpcpy_s.c index 0721d3d..ff9ecd6 100644 --- a/safeclib/wcpcpy_s.c +++ b/safeclib/wcpcpy_s.c @@ -91,7 +91,7 @@ wcpcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, errno_t *err) return NULL; } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (dmax > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcpcpy_s: dmax exceeds max", NULL, ESLEMAX); *err = RCNEGATE(ESLEMAX); diff --git a/safeclib/wcscat_s.c b/safeclib/wcscat_s.c index f682917..b3360fa 100644 --- a/safeclib/wcscat_s.c +++ b/safeclib/wcscat_s.c @@ -96,7 +96,7 @@ wcscat_s(wchar_t* dest, rsize_t dmax, const wchar_t* src) return RCNEGATE(ESZEROL); } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (dmax > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcscat_s: dmax exceeds max", NULL, ESLEMAX); return RCNEGATE(ESLEMAX); diff --git a/safeclib/wcscpy_s.c b/safeclib/wcscpy_s.c index bc0fe75..3fdc7af 100644 --- a/safeclib/wcscpy_s.c +++ b/safeclib/wcscpy_s.c @@ -84,7 +84,7 @@ wcscpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src) return RCNEGATE(ESZEROL); } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (dmax > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcscpy_s: dmax exceeds max", NULL, ESLEMAX); return RCNEGATE(ESLEMAX); diff --git a/safeclib/wcsncat_s.c b/safeclib/wcsncat_s.c index c15d991..e6845b5 100644 --- a/safeclib/wcsncat_s.c +++ b/safeclib/wcsncat_s.c @@ -94,7 +94,7 @@ wcsncat_s (wchar_t *dest, rsize_t dmax, const wchar_t *src, rsize_t slen) return RCNEGATE(ESNULLP); } - if (slen*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (slen > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcsncat_s: slen exceeds max", NULL, ESLEMAX); return RCNEGATE(ESLEMAX); @@ -106,7 +106,7 @@ wcsncat_s (wchar_t *dest, rsize_t dmax, const wchar_t *src, rsize_t slen) return RCNEGATE(ESZEROL); } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (dmax > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcsncat_s: dmax exceeds max", NULL, ESLEMAX); return RCNEGATE(ESLEMAX); diff --git a/safeclib/wcsncpy_s.c b/safeclib/wcsncpy_s.c index eeefb4f..55174c8 100644 --- a/safeclib/wcsncpy_s.c +++ b/safeclib/wcsncpy_s.c @@ -99,7 +99,7 @@ wcsncpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t slen) return RCNEGATE(ESZEROL); } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (dmax > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcsncpy_s: dmax exceeds max", NULL, ESLEMAX); return RCNEGATE(ESLEMAX); @@ -121,7 +121,7 @@ wcsncpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t slen) return RCNEGATE(ESZEROL); } - if (slen*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (slen > RSIZE_MAX_STR / sizeof(wchar_t)) { handle_wc_error(orig_dest, orig_dmax, "wcsncpy_s: slen exceeds max", ESLEMAX); return RCNEGATE(ESLEMAX); diff --git a/safeclib/wcsnlen_s.c b/safeclib/wcsnlen_s.c index e981e7f..b4fe891 100644 --- a/safeclib/wcsnlen_s.c +++ b/safeclib/wcsnlen_s.c @@ -69,7 +69,7 @@ wcsnlen_s (const wchar_t *dest, rsize_t dmax) return RCNEGATE(0); } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_STR) { + if (dmax > RSIZE_MAX_STR / sizeof(wchar_t)) { invoke_safe_str_constraint_handler("wcsnlen_s: dmax exceeds max", NULL, ESLEMAX); return RCNEGATE(0); diff --git a/safeclib/wmemmove_s.c b/safeclib/wmemmove_s.c index e3e7af9..8a7e4a4 100644 --- a/safeclib/wmemmove_s.c +++ b/safeclib/wmemmove_s.c @@ -87,7 +87,7 @@ wmemmove_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, size_t smax) return (RCNEGATE(ESZEROL)); } - if (dmax*sizeof(wchar_t) > RSIZE_MAX_MEM) { + if (dmax > RSIZE_MAX_MEM / sizeof(wchar_t)) { invoke_safe_mem_constraint_handler("wmemmove_s: dmax exceeds max", NULL, ESLEMAX); return (RCNEGATE(ESLEMAX)); diff --git a/safeclib/wmemset_s.c b/safeclib/wmemset_s.c index c0e5c93..615232b 100644 --- a/safeclib/wmemset_s.c +++ b/safeclib/wmemset_s.c @@ -66,7 +66,7 @@ wmemset_s (wchar_t *dest, wchar_t value, rsize_t len) return (RCNEGATE(ESZEROL)); } - if (len*sizeof(wchar_t) > RSIZE_MAX_MEM) { + if (len > RSIZE_MAX_MEM / sizeof(wchar_t)) { invoke_safe_mem_constraint_handler("wmemset_s: len exceeds max", NULL, ESLEMAX); return (RCNEGATE(ESLEMAX));