Update SeCoE Safe String Library

Signed-off-by: Jan Musial <jan.musial@intel.com>
This commit is contained in:
Jan Musial 2020-01-21 10:30:29 +01:00
parent 80d71fabea
commit 7e2b2877c8
16 changed files with 410 additions and 30 deletions

View File

@ -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.

View File

@ -69,4 +69,4 @@ void ignore_handler_s(const char *msg, void *ptr, errno_t error)
(msg) ? msg : "Null message");
return;
}
EXPORT_SYMBOL(ignore_handler_s);
EXPORT_SYMBOL(ignore_handler_s)

View File

@ -46,7 +46,9 @@
*
* DESCRIPTION
* This function copies at most smax bytes from src to dest, up to
* dmax.
* 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
@ -72,8 +74,8 @@
* 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 rst dmax bytes of the region pointed to
* by dest if dest is not a null pointer and smax is valid.
* 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
@ -114,6 +116,10 @@ memcpy_s (void *dest, rsize_t dmax, const void *src, rsize_t smax)
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",
@ -154,4 +160,4 @@ memcpy_s (void *dest, rsize_t dmax, const void *src, rsize_t smax)
return RCNEGATE(EOK);
}
EXPORT_SYMBOL(memcpy_s);
EXPORT_SYMBOL(memcpy_s)

View File

@ -34,6 +34,7 @@
#include "mem_primitives_lib.h"
#include "safe_mem_lib.h"
/**
* NAME
* memmove_s
@ -47,7 +48,7 @@
* 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 rst copied
* 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.
@ -76,9 +77,9 @@
* 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 rst dmax characters of the regionpointed to
* by dest if dest is not a null pointer and dmax is not greater
* than RSIZE_MAX_MEM.
* 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
@ -145,4 +146,4 @@ memmove_s (void *dest, rsize_t dmax, const void *src, rsize_t smax)
return (RCNEGATE(EOK));
}
EXPORT_SYMBOL(memmove_s);
EXPORT_SYMBOL(memmove_s)

View File

@ -102,4 +102,4 @@ memset_s (void *dest, rsize_t len, uint8_t value)
return (RCNEGATE(EOK));
}
EXPORT_SYMBOL(memset_s);
EXPORT_SYMBOL(memset_s)

View File

@ -33,6 +33,10 @@
#ifndef __SAFE_LIB_H__
#define __SAFE_LIB_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "safe_types.h"
#include "safe_lib_errno.h"
@ -58,4 +62,7 @@ extern void ignore_handler_s(const char *msg, void *ptr, errno_t error);
#include "safe_mem_lib.h"
#include "safe_str_lib.h"
#ifdef __cplusplus
}
#endif
#endif /* __SAFE_LIB_H__ */

View File

@ -83,6 +83,15 @@
#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 )

View File

@ -98,7 +98,7 @@ set_mem_constraint_handler_s (constraint_handler_t handler)
}
return prev_handler;
}
EXPORT_SYMBOL(set_mem_constraint_handler_s);
EXPORT_SYMBOL(set_mem_constraint_handler_s)
/**

View File

@ -34,6 +34,7 @@
#define __SAFE_MEM_LIB_H__
#include "safe_lib.h"
#include <wchar.h>
#define RSIZE_MAX_MEM ( 256UL << 20 ) /* 256MB */
#define RSIZE_MAX_MEM16 ( RSIZE_MAX_MEM/2 )
@ -43,15 +44,79 @@
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);
/* set bytes */
extern errno_t memset_s(void *dest, rsize_t dmax, uint8_t value);
/* 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__ */

View File

@ -102,7 +102,7 @@ set_str_constraint_handler_s (constraint_handler_t handler)
}
return prev_handler;
}
EXPORT_SYMBOL(set_str_constraint_handler_s);
EXPORT_SYMBOL(set_str_constraint_handler_s)
/**

View File

@ -61,4 +61,18 @@ static inline void handle_error(char *orig_dest, rsize_t orig_dmax,
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__ */

View File

@ -33,6 +33,7 @@
#define __SAFE_STR_LIB_H__
#include "safe_lib.h"
#include <wchar.h>
/*
* The shortest string is a null string!!
@ -52,20 +53,241 @@
#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__ */

View File

@ -46,7 +46,16 @@ typedef int errno_t;
#else
#include <stdio.h>
/* 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 <stdlib.h>
#include <ctype.h>
#else
#include <sys/types.h>
#endif
#include <inttypes.h>
#include <stdint.h>
#include <errno.h>

View File

@ -235,4 +235,4 @@ strncpy_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
ESNOSPC);
return RCNEGATE(ESNOSPC);
}
EXPORT_SYMBOL(strncpy_s);
EXPORT_SYMBOL(strncpy_s)

View File

@ -55,7 +55,7 @@
* INPUT PARAMETERS
* dest pointer to string
*
* dmax restricted maximum length (including null character).
* dmax restricted maximum length.
*
* OUTPUT PARAMETERS
* none
@ -64,15 +64,16 @@
* dest shall not be a null pointer
* dmax shall not be greater than RSIZE_MAX_STR
* dmax shall not equal zero
* null character shall be in first dmax characters of dest
*
* 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.
* At most the first dmax characters of dest are accessed by strnlen_s.
* 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()
@ -82,7 +83,6 @@ rsize_t
strnlen_s (const char *dest, rsize_t dmax)
{
rsize_t count;
rsize_t orig_dmax = dmax;
if (dest == NULL) {
return RCNEGATE(0);
@ -106,12 +106,7 @@ strnlen_s (const char *dest, rsize_t dmax)
dmax--;
dest++;
}
if (count == orig_dmax) {
invoke_safe_str_constraint_handler("strnlen_s: string length exceeds dmax",
NULL, ESLEMAX);
return RCNEGATE(0);
}
return RCNEGATE(count);
}
EXPORT_SYMBOL(strnlen_s);
EXPORT_SYMBOL(strnlen_s)

View File

@ -55,7 +55,7 @@
* 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 reect the
* 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
@ -79,9 +79,9 @@
* overwritten by a null character, which terminates the
* current token.
*
* In all cases, the strtok_s function stores sufcient information
* 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 unmodied pointer value
* 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).
*
@ -321,3 +321,5 @@ strtok_s(char *dest, rsize_t *dmax, const char *src, char **ptr)
*dmax = dlen;
return (ptoken);
}
EXPORT_SYMBOL(strtok_s)