diff options
Diffstat (limited to 'libcilkrts/runtime/sslib')
-rw-r--r-- | libcilkrts/runtime/sslib/ignore_handler_s.c | 72 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safe_lib.h | 61 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safe_lib_errno.h | 100 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safe_str_constraint.c | 146 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safe_str_constraint.h | 78 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safe_str_lib.h | 70 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safe_types.h | 61 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/safeclib_private.h | 93 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/snprintf_s.h | 49 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/snprintf_support.c | 353 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/strcpy_s.c | 198 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/strncpy_s.c | 238 | ||||
-rw-r--r-- | libcilkrts/runtime/sslib/strnlen_s.c | 112 |
13 files changed, 1631 insertions, 0 deletions
diff --git a/libcilkrts/runtime/sslib/ignore_handler_s.c b/libcilkrts/runtime/sslib/ignore_handler_s.c new file mode 100644 index 00000000000..54b65c9a23f --- /dev/null +++ b/libcilkrts/runtime/sslib/ignore_handler_s.c @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------ + * ignore_handler_s.c + * + * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net> + * + * 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/libcilkrts/runtime/sslib/safe_lib.h b/libcilkrts/runtime/sslib/safe_lib.h new file mode 100644 index 00000000000..9ffb24e72ab --- /dev/null +++ b/libcilkrts/runtime/sslib/safe_lib.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------ + * safe_lib.h -- Safe C Library + * + * October 2008, Bo Berry + * Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net> + * + * 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__ + +#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" + +#endif /* __SAFE_LIB_H__ */ diff --git a/libcilkrts/runtime/sslib/safe_lib_errno.h b/libcilkrts/runtime/sslib/safe_lib_errno.h new file mode 100644 index 00000000000..8f27111c353 --- /dev/null +++ b/libcilkrts/runtime/sslib/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 <jtoppins@users.sourceforge.net> + * + * 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 <linux/errno.h> +#else +#include <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 + +/* 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/libcilkrts/runtime/sslib/safe_str_constraint.c b/libcilkrts/runtime/sslib/safe_str_constraint.c new file mode 100644 index 00000000000..17e7fbbb4d2 --- /dev/null +++ b/libcilkrts/runtime/sslib/safe_str_constraint.c @@ -0,0 +1,146 @@ +/*------------------------------------------------------------------ + * safe_str_constraint.c + * + * October 2008, Bo Berry + * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net> + * + * 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/libcilkrts/runtime/sslib/safe_str_constraint.h b/libcilkrts/runtime/sslib/safe_str_constraint.h new file mode 100644 index 00000000000..a1fba3e7e85 --- /dev/null +++ b/libcilkrts/runtime/sslib/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/libcilkrts/runtime/sslib/safe_str_lib.h b/libcilkrts/runtime/sslib/safe_str_lib.h new file mode 100644 index 00000000000..3bc841ea551 --- /dev/null +++ b/libcilkrts/runtime/sslib/safe_str_lib.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------ + * 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" + +/* + * 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 copy */ +extern errno_t +strcpy_s(char *dest, rsize_t dmax, const char *src); + +/* string length */ +extern rsize_t +strnlen_s (const char *s, rsize_t smax); + + +#endif /* __SAFE_STR_LIB_H__ */ diff --git a/libcilkrts/runtime/sslib/safe_types.h b/libcilkrts/runtime/sslib/safe_types.h new file mode 100644 index 00000000000..5c2df9c6128 --- /dev/null +++ b/libcilkrts/runtime/sslib/safe_types.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------ + * safe_types.h - C99 std types & defs or Linux kernel equivalents + * + * March 2007, Bo Berry + * Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net> + * + * 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 <linux/stddef.h> +#include <linux/types.h> +#include <linux/errno.h> + +/* errno_t isn't defined in the kernel */ +typedef int errno_t; + +#else + +#include <stdio.h> +#include <sys/types.h> +#ifndef _WRS_KERNEL +#include <inttypes.h> +#endif +#include <stdint.h> +#include <errno.h> + +typedef int errno_t; + +#include <stdbool.h> + +#endif /* __KERNEL__ */ +#endif /* __SAFE_TYPES_H__ */ diff --git a/libcilkrts/runtime/sslib/safeclib_private.h b/libcilkrts/runtime/sslib/safeclib_private.h new file mode 100644 index 00000000000..7280e879a8e --- /dev/null +++ b/libcilkrts/runtime/sslib/safeclib_private.h @@ -0,0 +1,93 @@ +/*------------------------------------------------------------------ + * safeclib_private.h - Internal library references + * + * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net> + * + * 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 <linux/kernel.h> +#include <linux/module.h> +#include <linux/ctype.h> + +#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 <stdio.h> +#ifdef STDC_HEADERS +# include <ctype.h> +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_LIMITS_H +# include <limits.h> +#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/libcilkrts/runtime/sslib/snprintf_s.h b/libcilkrts/runtime/sslib/snprintf_s.h new file mode 100644 index 00000000000..b4abb8652c1 --- /dev/null +++ b/libcilkrts/runtime/sslib/snprintf_s.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------ + * 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 <safe_lib_errno.h> + + +#define SNPRFNEGATE(x) (-1*(x)) + + + +int snprintf_s_s(char *dest, rsize_t dmax, const char *format, char *s); +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/libcilkrts/runtime/sslib/snprintf_support.c b/libcilkrts/runtime/sslib/snprintf_support.c new file mode 100644 index 00000000000..5ee0e3dd36b --- /dev/null +++ b/libcilkrts/runtime/sslib/snprintf_support.c @@ -0,0 +1,353 @@ +/*------------------------------------------------------------------ + * 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<index; start++) { printf("%c", format[start]); } + puts("]"); + break; + } + } + if (format[index] != '%') + // don't know why it skips over blindly, not handling cases such as "%s%d". + index++; // move past this character + } + + return numFormats; +} + +unsigned int +check_integer_format(const char format) +{ + unsigned int retValue = 0; // default failure + switch( format) { + case FMT_CHAR : + case FMT_SHORT : + case FMT_INT : + retValue = 1; + break; + } + return retValue; +} + + + +inline int snprintf_s_i(char *dest, rsize_t dmax, const char *format, int a) +{ + char pformatList[MAX_FORMAT_ELEMENTS]; + unsigned int index = 0; + + // Determine the number of format options in the format string + unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS); + + // Check that there are not too many format options + if ( nfo != 1 ) { + dest[0] = '\0'; + return SNPRFNEGATE(ESBADFMT); + } + // Check that the format is for an integer type + if ( check_integer_format(pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + return snprintf(dest, dmax, format, a); +} + + + +inline int snprintf_s_l(char *dest, rsize_t dmax, const char *format, long a) +{ + char pformatList[MAX_FORMAT_ELEMENTS]; + unsigned int index = 0; + + // Determine the number of format options in the format string + unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS); + + // Check that there are not too many format options + if ( nfo != 1 ) { + dest[0] = '\0'; + return SNPRFNEGATE(ESBADFMT); + } + // Check that the format is for an long type + if ( CHK_FORMAT(FMT_LONG, pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + return snprintf(dest, dmax, format, a); +} + + +inline int snprintf_s_si(char *dest, rsize_t dmax, const char *format, char *s, int a) +{ + char pformatList[MAX_FORMAT_ELEMENTS]; + unsigned int index = 0; + + // Determine the number of format options in the format string + unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS); + + // Check that there are not too many format options + if ( nfo != 2 ) { + dest[0] = '\0'; + return SNPRFNEGATE(ESBADFMT); + } + // Check first format is of string type + if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + // Check that the format is for an integer type + if ( check_integer_format(pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + return snprintf(dest, dmax, format, s, a); +} + + +inline int snprintf_s_sl(char *dest, rsize_t dmax, const char *format, char *s, long a) +{ + char pformatList[MAX_FORMAT_ELEMENTS]; + unsigned int index = 0; + + // Determine the number of format options in the format string + unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS); + + // Check that there are not too many format options + if ( nfo != 2 ) { + dest[0] = '\0'; + return SNPRFNEGATE(ESBADFMT); + } + // Check first format is of string type + if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + // Check that the format is for an integer type + if ( CHK_FORMAT(FMT_LONG, pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + return snprintf(dest, dmax, format, s, a); +} + +inline int snprintf_s_s(char *dest, rsize_t dmax, const char *format, char *s) +{ + char pformatList[MAX_FORMAT_ELEMENTS]; + unsigned int index = 0; + + // Determine the number of format options in the format string + unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS); + + // Check that there are not too many format options + if ( nfo != 1 ) { + dest[0] = '\0'; + return SNPRFNEGATE(ESBADFMT); + } + // Check first format is of string type + if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) { + dest[0] = '\0'; + return SNPRFNEGATE(ESFMTTYP); + } + index++; + + return snprintf(dest, dmax, format, s); +} diff --git a/libcilkrts/runtime/sslib/strcpy_s.c b/libcilkrts/runtime/sslib/strcpy_s.c new file mode 100644 index 00000000000..a0cbd6dc930 --- /dev/null +++ b/libcilkrts/runtime/sslib/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/libcilkrts/runtime/sslib/strncpy_s.c b/libcilkrts/runtime/sslib/strncpy_s.c new file mode 100644 index 00000000000..e1cdd6b1721 --- /dev/null +++ b/libcilkrts/runtime/sslib/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/libcilkrts/runtime/sslib/strnlen_s.c b/libcilkrts/runtime/sslib/strnlen_s.c new file mode 100644 index 00000000000..e3cab9a6428 --- /dev/null +++ b/libcilkrts/runtime/sslib/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); |