├── VERSION ├── DEBIAN ├── compat ├── rules ├── changelog └── control ├── tools ├── Makefile.am └── subdir-list.txt ├── test ├── test_harness_aux.h ├── openosc_test_msan.c ├── test_harness_aux.c ├── test_harness_defs.h ├── openosc_test_chk.c ├── openosc_test_asan.c ├── openosc_test_nomap.c ├── openosc_test.c ├── openosc_test_cpp.cpp ├── Makefile.am ├── test_harness_bosc_utils.c ├── README ├── test_harness_bosc.h ├── test_harness_compile_check_safec.c ├── test_harness_bosc_safec.c ├── test_harness_compile_check.c └── test_harness.c ├── include ├── openosc_api.h ├── openosc_map.h ├── openosc_nomap.h ├── openosc_fortify_map.h ├── openosc_fortify_nomap.h ├── openosc_extern.h ├── openosc_safec_nomap_metric.h ├── openosc_safec_nomap.h ├── openosc_redefine_nomap.h ├── openosc_redirect_nomap.h ├── openosc_header_metric.h ├── openosc_nomap_metric.h ├── openosc.h ├── openosc_fortify_extern.h ├── openosc_fortify.h ├── openosc_safec_map_metric.h └── openosc_metric_only.h ├── README ├── .gitignore ├── src ├── Makefile.am ├── openosc_package_info.c ├── openosc_support_priv.h ├── openosc_common.h ├── openosc_safec_map.c ├── openosc_support.c └── openosc_map.c ├── Makefile.am ├── configure.ac ├── SPECS └── openosc.spec ├── config.h.in └── LICENSE /VERSION: -------------------------------------------------------------------------------- 1 | 1.0.8 2 | -------------------------------------------------------------------------------- /DEBIAN/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /tools/Makefile.am: -------------------------------------------------------------------------------- 1 | dist_bin_SCRIPTS = oscdecode.py oscmetrics.py 2 | EXTRA_DIST = subdir-list.txt openosc_newfunc.py 3 | -------------------------------------------------------------------------------- /DEBIAN/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | override_dh_shlibdeps: 4 | dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info 5 | 6 | %: 7 | dh $@ 8 | -------------------------------------------------------------------------------- /DEBIAN/changelog: -------------------------------------------------------------------------------- 1 | openosc (PACKAGE_VERSION-1) sid; urgency=medium 2 | 3 | * Initial packaging work for OpenOSC with dpkg-buildpackage. 4 | 5 | -- Yongkui Han Mon, 10 Dec 2018 06:12:29 +0000 6 | -------------------------------------------------------------------------------- /tools/subdir-list.txt: -------------------------------------------------------------------------------- 1 | # This is README for the customized-subdirs file, provided via -c option. 2 | # 3 | # It shall contain a list of customized sub-directories to search, in order 4 | # to find binary files or shared library files to decode OSC/DCDI tracebacks. 5 | # 6 | # Put your subdir here, one subdir per line, like var/sf 7 | # Empty lines and lines that start with '#' will be ignored. 8 | 9 | -------------------------------------------------------------------------------- /test/test_harness_aux.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef TEST_HARNESS_AUX_H 11 | #define TEST_HARNESS_AUX_H 12 | 13 | size_t bosc_th_test_aux_char (char *); 14 | size_t bosc_th_test_aux_flow_char (int); 15 | size_t bosc_th_test_aux_struct_ptr (struct2 *); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/openosc_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | #ifndef __OPENOSC_API_H__ 12 | #define __OPENOSC_API_H__ 13 | 14 | const char * openosc_get_package_string (void); 15 | const char * openosc_get_package_name (void); 16 | const char * openosc_get_package_version (void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | OpenOSC Library - README 2 | ======================== 3 | OpenOSC is an open-source object size check library written in C. It has been 4 | developed in order to promote the use of compiler builtin object size check 5 | capability for enhanced security. It provides robust support for detecting 6 | buffer overflows in various functions that perform operations on memory and 7 | strings. Not all types of buffer overflows can be detected with this library, 8 | but it does provide an extra level of validation for some functions that are 9 | potentially a source of buffer overflow flaws. It protects both C and C++ code. 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES = libopenosc.la 2 | if HAS_SAFEC 3 | libopenosc_la_SOURCES = openosc_map.c openosc_support.c openosc_package_info.c openosc_support_priv.h openosc_common.h openosc_fortify_map.c openosc_safec_map.c 4 | else 5 | libopenosc_la_SOURCES = openosc_map.c openosc_support.c openosc_package_info.c openosc_support_priv.h openosc_common.h openosc_fortify_map.c 6 | endif 7 | libopenosc_la_CFLAGS = $(OPENOSC_CFLAGS) 8 | libopenosc_la_LDFLAGS = -version-info $(LT_VERSION_NUMBER) --allow-shlib-undefined 9 | include_HEADERS = $(top_srcdir)/include/*.h 10 | 11 | install-exec-hook: 12 | cd $(DESTDIR)$(libdir) && rm $(lib_LTLIBRARIES) 13 | 14 | uninstall-local: 15 | cd $(DESTDIR)$(libdir) && rm libopenosc.a libopenosc.so* 16 | -------------------------------------------------------------------------------- /include/openosc_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | #ifndef __OPENOSC_MAP_H__ 12 | #define __OPENOSC_MAP_H__ 13 | 14 | #include "openosc_map_metric.h" 15 | 16 | #ifndef _FORTIFY_SOURCE 17 | 18 | #include "openosc_fortify.h" 19 | 20 | #if (OPENOSC_MAPPING_METHOD == OPENOSC_ASM_LABEL_REDIRECT_METHOD) 21 | #include "openosc_redirect_map.h" 22 | #else 23 | #include "openosc_redefine_map.h" 24 | #endif 25 | 26 | #ifndef OPENOSC_FORTIFY_FUNCTIONS_DISABLE 27 | #include "openosc_fortify_map.h" 28 | #endif 29 | 30 | #endif 31 | 32 | #endif /* __OPENOSC_MAP_H__ */ 33 | -------------------------------------------------------------------------------- /DEBIAN/control: -------------------------------------------------------------------------------- 1 | Source: openosc 2 | Section: libs 3 | Priority: standard 4 | Maintainer: Yongkui Han 5 | Build-Depends: build-essential, debhelper (>= 9) 6 | 7 | Package: openosc 8 | Architecture: any 9 | Depends: ${shlibs:Depends}, ${misc:Depends} 10 | Description: OpenOSC package 11 | OpenOSC is an open-source object size check library written in C. It has been 12 | developed in order to promote the use of compiler builtin object size check 13 | capability for enhanced security. It provides lightweight support for detecting 14 | buffer overflows in various functions that perform operations on memory and 15 | strings. Not all types of buffer overflows can be detected with this library, 16 | but it does provide an extra level of validation for some functions that are 17 | potentially a source of buffer overflow flaws. It protects both C and C++ code. 18 | -------------------------------------------------------------------------------- /include/openosc_nomap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | #ifndef __OPENOSC_NOMAP_H__ 12 | #define __OPENOSC_NOMAP_H__ 13 | 14 | #include "openosc_nomap_metric.h" 15 | 16 | #ifndef _FORTIFY_SOURCE 17 | 18 | #include "openosc_fortify.h" 19 | 20 | #if (OPENOSC_MAPPING_METHOD == OPENOSC_ASM_LABEL_REDIRECT_METHOD) 21 | #include "openosc_redirect_nomap.h" 22 | #else 23 | #include "openosc_redefine_nomap.h" 24 | #endif 25 | 26 | #ifndef OPENOSC_FORTIFY_FUNCTIONS_DISABLE 27 | #include "openosc_fortify_nomap.h" 28 | #endif 29 | 30 | #endif 31 | 32 | #endif /* __OPENOSC_NOMAP_H__ */ 33 | 34 | -------------------------------------------------------------------------------- /test/openosc_test_msan.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | /* Uncomment the below line to do the real MSAN test for clang */ 12 | //#include "../include/openosc.h" 13 | #include 14 | #include 15 | 16 | /* Test code for Memory Sanitier, which can be enabled via -fsanitize=memory. */ 17 | /* Note that memory sanitizer is only available with clang, not yet with gcc */ 18 | int main() 19 | { 20 | char text[100]; 21 | printf("Entering msan test\n"); 22 | sprintf(text, "hello"); 23 | printf("text len: %lu\n", strlen(text)); 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/openosc_package_info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | #include "config.h" 10 | 11 | /* 12 | * This function returns the package string 13 | */ 14 | const char * openosc_get_package_string (void) 15 | { 16 | 17 | return (PACKAGE_STRING); 18 | 19 | } 20 | 21 | /* 22 | * This function returns the package name string 23 | */ 24 | const char * openosc_get_package_name (void) 25 | { 26 | 27 | return (PACKAGE_NAME); 28 | 29 | } 30 | 31 | /* 32 | * This function returns the package versionstring 33 | */ 34 | const char * openosc_get_package_version (void) 35 | { 36 | 37 | return (PACKAGE_VERSION); 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /include/openosc_fortify_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_FORTIFY_MAP_H__ 11 | #define __OPENOSC_FORTIFY_MAP_H__ 12 | 13 | 14 | #include "openosc_fortify_map_metric.h" 15 | 16 | 17 | #ifndef _FORTIFY_SOURCE 18 | 19 | #ifdef __cplusplus 20 | #include 21 | extern "C" 22 | { 23 | #endif 24 | 25 | #include "openosc_fortify_extern.h" 26 | 27 | #if (OPENOSC_MAPPING_METHOD == OPENOSC_ASM_LABEL_REDIRECT_METHOD) 28 | #include "openosc_fortify_redirect_map.h" 29 | #else 30 | #include "openosc_fortify_redefine_map.h" 31 | #endif 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif 38 | 39 | #endif /* __OPENOSC_FORTIFY_MAP_H__ */ 40 | -------------------------------------------------------------------------------- /include/openosc_fortify_nomap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_FORTIFY_NOMAP_H__ 11 | #define __OPENOSC_FORTIFY_NOMAP_H__ 12 | 13 | /* if OSC metric feature is disabled, we can completely exclude this osc_nomap.h header */ 14 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 15 | 16 | #include "openosc_fortify_nomap_metric.h" 17 | 18 | 19 | #ifndef _FORTIFY_SOURCE 20 | 21 | #ifdef __cplusplus 22 | #include 23 | extern "C" 24 | { 25 | #endif 26 | 27 | #include "openosc_fortify_extern.h" 28 | 29 | #if (OPENOSC_MAPPING_METHOD == OPENOSC_ASM_LABEL_REDIRECT_METHOD) 30 | #include "openosc_fortify_redirect_nomap.h" 31 | #else 32 | #include "openosc_fortify_redefine_nomap.h" 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif 40 | 41 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 42 | 43 | #endif /* __OPENOSC_FORTIFY_NOMAP_H__ */ 44 | -------------------------------------------------------------------------------- /test/test_harness_aux.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | #include 10 | #include "test_harness_defs.h" 11 | #include "test_harness_aux.h" 12 | 13 | /* 14 | * This file tests object size checking across .o boundaries 15 | */ 16 | 17 | /* 18 | * The next two functions are simple cross object size checks 19 | */ 20 | size_t 21 | bosc_th_test_aux_char (char *cptr) 22 | { 23 | return __builtin_object_size(cptr, TH_SIZE_CHECK_1); 24 | } 25 | 26 | size_t 27 | bosc_th_test_aux_struct_ptr (struct2 *s2ptr) 28 | { 29 | return __builtin_object_size(s2ptr->s1ptr->char_buf_mid, TH_SIZE_CHECK_1); 30 | } 31 | 32 | /* 33 | * This function tests how object size checkers deal with objects whose size can 34 | * vary between fixed values at run-time. 35 | */ 36 | size_t 37 | bosc_th_test_aux_flow_char (int flag) 38 | { 39 | char *cptr; 40 | char char_buf1[STATIC_BUF_SIZE]; 41 | char char_buf2[LARGER_BUF_SIZE]; 42 | if (flag) { 43 | cptr = char_buf1; 44 | } else { 45 | cptr = char_buf2; 46 | } 47 | return __builtin_object_size(cptr, TH_SIZE_CHECK_1); 48 | } 49 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src test tools 2 | EXTRA_DIST = SPECS DEBIAN LICENSE VERSION README.md 3 | 4 | rpm: dist 5 | if type -P "rpmbuild" &> /dev/null ; then \ 6 | echo "rpmbuild exists on the path." ; \ 7 | else \ 8 | echo "rpmbuild does not exist, please install it before building RPM." ; exit 1 ; \ 9 | fi 10 | @echo "Creating RPM package..." 11 | mkdir -p rpmbuild/SPECS ; cp SPECS/openosc.spec rpmbuild/SPECS/ ; 12 | sed -i 's/PACKAGE_VERSION/$(PACKAGE_VERSION)/g' rpmbuild/SPECS/openosc.spec ; 13 | mkdir -p rpmbuild/SOURCES ; cp openosc-$(PACKAGE_VERSION).tar.gz rpmbuild/SOURCES/ ; 14 | cd rpmbuild; rpmbuild --define "_topdir `pwd`" -ba SPECS/openosc.spec 15 | @echo "Done creating RPM package." 16 | 17 | deb: 18 | if type -P "dpkg-buildpackage" &> /dev/null ; then \ 19 | echo "dpkg-buildpackage exists on the path." ; \ 20 | else \ 21 | echo "dpkg-buildpackage does not exist, please install it before building debian package." ; exit 1 ; \ 22 | fi 23 | if type -P "dh" &> /dev/null ; then \ 24 | echo "dh exists on the path." ; \ 25 | else \ 26 | echo "dh does not exist, please install it before building debian package." ; exit 1 ; \ 27 | fi 28 | @echo "Creating debian package..." 29 | mkdir -p debian ; cp DEBIAN/* debian/ ; 30 | sed -i 's/PACKAGE_VERSION/$(PACKAGE_VERSION)/g' debian/changelog ; 31 | dpkg-buildpackage -b -uc -us 32 | @echo "Done creating debian package." 33 | -------------------------------------------------------------------------------- /src/openosc_support_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef _OPENOSC_SUPPORT_PRIV_H_ 11 | #define _OPENOSC_SUPPORT_PRIV_H_ 12 | 13 | #ifndef FALSE 14 | #define FALSE 0 15 | #endif 16 | 17 | #ifndef TRUE 18 | #define TRUE (!FALSE) 19 | #endif 20 | 21 | /* Undefine this to get a non-release version of the backtrace */ 22 | #define OSC_FINAL 1 23 | 24 | /* Max number of backtrace frames to work with */ 25 | #define OSC_BT_FRAMES 32 26 | 27 | /* Number of backtrace frames to skip when returning the backtrace */ 28 | #define OSC_FRAMES_TO_SKIP 3 29 | 30 | /* Backtrace string buffer size */ 31 | #define OSC_BT_STR_MAX 512 32 | 33 | /* Logging buffer size */ 34 | #define OSC_LOG_STR_MAX 512 35 | 36 | /* Max /proc path */ 37 | #define OSC_PROC_PATH_MAX 256 38 | 39 | 40 | #ifdef OSC_FINAL 41 | #define OPENOSC_BT_TO_STR(bt_array, bt_count, bt_str, bt_str_max) \ 42 | openosc_bt2str_offset(bt_array, bt_count, bt_str, bt_str_max) 43 | #else 44 | #define OPENOSC_BT_TO_STR(bt_array, bt_count, bt_str, bt_str_max) \ 45 | openosc_bt2str_symbol(bt_array, bt_count, bt_str, bt_str_max) 46 | #endif 47 | 48 | #endif /* _OPENOSC_SUPPORT_PRIV_H_ */ 49 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.69]) 2 | AC_INIT([openosc], [m4_esyscmd_s(cat VERSION)], [yonhan@cisco.com]) 3 | AC_CONFIG_AUX_DIR([build-tools]) 4 | AM_INIT_AUTOMAKE([-Wall -Werror foreign]) 5 | AM_PROG_AR 6 | AC_PROG_CC 7 | AC_PROG_CXX 8 | AM_PROG_CC_C_O 9 | AC_ARG_ENABLE([safec], 10 | AS_HELP_STRING([--disable-safec], [Disable feature SafeC])) 11 | AS_IF([test "x$enable_safec" != "xno"], 12 | [AC_MSG_NOTICE([The safec feature is not disabled])], 13 | [AC_MSG_NOTICE([The safec feature is disabled])]) 14 | AC_CHECK_LIB([dl], [dladdr]) 15 | AC_CHECK_LIB([ciscosafec], [memcpy_s]) 16 | AC_CHECK_HEADERS([safe_lib.h]) 17 | AC_CHECK_HEADERS([safec/safe_lib.h]) 18 | AM_CONDITIONAL([OPENOSC_TEST_CXX_PROG], [test "x$ac_cv_prog_cxx_g" = xyes]) 19 | AM_COND_IF([OPENOSC_TEST_CXX_PROG], 20 | [AC_MSG_NOTICE([The unit-test C++ code coverage is ON])], 21 | [AC_MSG_NOTICE([The unit-test C++ code coverage is OFF])]) 22 | AM_CONDITIONAL([HAS_SAFEC], [test "x$enable_safec" != xno -a "x$ac_cv_lib_ciscosafec_memcpy_s" = xyes -a "x$ac_cv_header_safe_lib_h" = xyes -o "x$ac_cv_lib_ciscosafec_memcpy_s" = xyes -a "x$ac_cv_header_safec_safe_lib_h" = xyes]) 23 | AM_COND_IF([HAS_SAFEC], 24 | [AC_MSG_NOTICE([The safec coverage is ON])], 25 | [AC_MSG_NOTICE([The safec coverage is OFF])]) 26 | AM_CONDITIONAL([OPENOSC_TEST_HARNESS_WANT_COMPILE_TIME_CHECK], [test a = b]) 27 | LT_INIT 28 | LT_VERSION_NUMBER="0:0:0" 29 | AC_SUBST(LT_VERSION_NUMBER) 30 | #AC_SUBST(OPENOSC_CFLAGS, [-fsanitize=address]) 31 | AC_SUBST(OPENOSC_CFLAGS, ["-Wsign-compare -U_FORTIFY_SOURCE -fno-stack-protector"]) 32 | AC_CONFIG_HEADERS([config.h]) 33 | AC_CONFIG_FILES([ 34 | Makefile 35 | src/Makefile 36 | test/Makefile 37 | tools/Makefile 38 | ]) 39 | AC_OUTPUT 40 | -------------------------------------------------------------------------------- /test/test_harness_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef TEST_HARNESS_DEFS_H 11 | #define TEST_HARNESS_DEFS_H 12 | 13 | /* 14 | * Type and macro definitions for the test suite 15 | */ 16 | 17 | #define BOSC_TH_VERSION 3.0 18 | #define STATIC_BUF_SIZE 10 19 | #define MALLOC_BUF_SIZE 15 20 | #define LARGER_BUF_SIZE 30 21 | #define NUMBER_OF_BUFS 3 22 | #define TH_SIZE_CHECK_0 0 23 | #define TH_SIZE_CHECK_1 1 24 | 25 | void bosc_th_show_result(const char *, int, int); 26 | void bosc_th_test_char(void); 27 | void bosc_th_call_aux_fns(void); 28 | void bosc_th_test_osc_remap(void); 29 | void bosc_th_test_osc_safec_remap(void); 30 | void bosc_th_test_osc_logging(void); 31 | void bosc_th_test_osc_truncation(void); 32 | void bosc_th_test_osc_thread_safe(void); 33 | void bosc_th_run_tests(void); 34 | 35 | struct struct1 { 36 | char char_buf_first[STATIC_BUF_SIZE]; 37 | int intvar; 38 | char char_buf_mid[STATIC_BUF_SIZE]; 39 | char charvar1; 40 | char charvar2; 41 | char char_buf_last[STATIC_BUF_SIZE]; 42 | }; 43 | typedef struct struct1 struct1; 44 | 45 | struct struct2 { 46 | struct1 *s1ptr; 47 | }; 48 | typedef struct struct2 struct2; 49 | 50 | struct struct3 { 51 | struct1 s1; 52 | }; 53 | typedef struct struct3 struct3; 54 | 55 | union union1 { 56 | struct1 structvar; 57 | char char_buf[STATIC_BUF_SIZE*2]; 58 | }; 59 | typedef union union1 union1; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /test/openosc_test_chk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | #include 12 | 13 | extern void * 14 | __openosc_memcpy_to_buf(size_t dest_len, size_t src_len, void *dst, const void *src, size_t len); 15 | 16 | /* Testing OpenOSC runtime check code */ 17 | 18 | int openosc_test_memcpy(void) { 19 | int len = 8; 20 | char dst[5]; 21 | char src[20] = "I am the source"; 22 | __openosc_memcpy_to_buf(5, 4, dst, src, 4); /* case 1 */ 23 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 24 | #if 1 25 | __openosc_memcpy_to_buf(5, 7, dst, src, 7); /* case 2 */ 26 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 27 | __openosc_memcpy_to_buf(5, 8, dst, src, 8); /* case 2 */ 28 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 29 | #endif 30 | len = (dst[3]-dst[2])/20 ; 31 | __openosc_memcpy_to_buf(5, len, dst, src, len); /* case 3 */ 32 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 33 | __openosc_memcpy_to_buf(5, 1, &len-1, src, 1); /* case 4 */ 34 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 35 | __openosc_memcpy_to_buf(5, 3, dst, src, 4); /* src over-read */ 36 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 37 | printf("End of testing memcpy!\n"); 38 | return 0; 39 | } 40 | 41 | int main(void) { 42 | return openosc_test_memcpy(); 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /test/openosc_test_asan.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | //#include "../include/openosc.h" 12 | #include 13 | #include 14 | #include 15 | 16 | /* Test code for Address Sanitier, which can be enabled by adding -fsanitize=address */ 17 | 18 | int g_var = 10; 19 | char g_dst[10] = ""; 20 | 21 | int openosc_test_stack_overflow(int n) { 22 | int stack_array[10]; 23 | stack_array[1] = 0; 24 | printf("Entering %s: n: %d\n", __FUNCTION__, n); 25 | return stack_array[n + 10]; 26 | } 27 | 28 | int openosc_test_stack_overflow2(int n) { 29 | int i; 30 | int len = 5; 31 | char *p_var = (char *)&g_var + 1; 32 | char dst[10]; 33 | char src[] = "I am source"; 34 | for (i=0; i<5; i++) { 35 | memcpy(dst, src, 4); /* case 1 */ 36 | } 37 | printf("Entering %s: n: %d &i: %p &g_var: %p\n", __FUNCTION__, n, &i, &g_var); 38 | //memcpy(p_var+1, src, n+5); /* CASE 4 */ 39 | printf("Leaving %s: n: %d\n", __FUNCTION__, n); 40 | return 0; 41 | } 42 | 43 | int openosc_test_stack_overflow3(int n) { 44 | int len = 5; 45 | char *p_var = (char *)&g_var + 1; 46 | char *dst = (char *)malloc(n); 47 | char src[] = "I am source"; 48 | printf("Entering %s: n: %d dst: %p &g_var: %p\n", __FUNCTION__, n, dst, &g_var); 49 | //memcpy(dst+1, src, 2+n); /* CASE 4 */ 50 | printf("Leaving %s: n: %d\n", __FUNCTION__, n); 51 | return 0; 52 | } 53 | 54 | int main(void) { 55 | int a = openosc_test_stack_overflow(1); 56 | a = openosc_test_stack_overflow2(3); 57 | return openosc_test_stack_overflow3(5); 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/openosc_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef _OPENOSC_COMMON_H_ 11 | #define _OPENOSC_COMMON_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #ifndef boolean 18 | typedef int boolean; 19 | #endif 20 | 21 | #ifndef TRUE 22 | #define TRUE 1 23 | #endif 24 | 25 | #ifndef FALSE 26 | #define FALSE 0 27 | #endif 28 | 29 | #define MIN(a,b) ((a) < (b) ? a : b) 30 | 31 | /* Default OSC logging, truncate and abort state */ 32 | #define OPENOSC_DEF_LOG_STATE TRUE 33 | #define OPENOSC_DEF_TRUNCATE_STATE TRUE 34 | #define OPENOSC_DEF_ABORT_STATE FALSE 35 | 36 | #ifdef OPENOSC_RUNTIME_LOGGING_DISABLE 37 | #define openosc_log FALSE 38 | #else 39 | #define openosc_log OPENOSC_DEF_LOG_STATE 40 | #endif 41 | 42 | #ifdef OPENOSC_RUNTIME_TRUNCATE_DISABLE 43 | #define openosc_truncate FALSE 44 | #else 45 | #define openosc_truncate OPENOSC_DEF_TRUNCATE_STATE 46 | #endif 47 | 48 | #ifdef OPENOSC_RUNTIME_CONFIG_FILE 49 | #define _OPENOSC_RUNTIME_CONFIG_FILE OPENOSC_RUNTIME_CONFIG_FILE 50 | #else 51 | #define _OPENOSC_RUNTIME_CONFIG_FILE "/etc/openosc.conf" 52 | #endif 53 | 54 | static inline void 55 | openosc_get_config (unsigned int *abort_flag) 56 | { 57 | int fd = 0; 58 | char c = 0; 59 | 60 | fd = open(_OPENOSC_RUNTIME_CONFIG_FILE, O_RDONLY); 61 | if (fd > 0) { 62 | (void)pread(fd, &c, 1, 0); 63 | if (c == '0' || c == 0) { 64 | *abort_flag = FALSE; 65 | } else { 66 | *abort_flag = TRUE; 67 | } 68 | close(fd); 69 | } 70 | return; 71 | } 72 | 73 | const char * openosc_get_package_string (void); 74 | const char * openosc_get_package_name (void); 75 | const char * openosc_get_package_version (void); 76 | extern void openosc_danger_error (const char *func, size_t true_len, size_t len); 77 | 78 | #endif /* _OPENOSC_COMMON_H_ */ 79 | -------------------------------------------------------------------------------- /SPECS/openosc.spec: -------------------------------------------------------------------------------- 1 | Name: openosc 2 | Version: PACKAGE_VERSION 3 | Release: 1%{?dist} 4 | Summary: Open Object Size Check Library 5 | Group: System Environment/Libraries 6 | 7 | License: ASL 2.0 8 | URL: https://github.com/cisco/openosc 9 | Source0: %{name}-%{version}.tar.gz 10 | 11 | BuildRequires: gcc 12 | BuildRequires: make 13 | 14 | %description 15 | OpenOSC is an open-source object size check library written in C. It has been 16 | developed in order to promote the use of compiler builtin object size check 17 | capability for enhanced security. It provides robust support for detecting 18 | buffer overflows in various functions that perform operations on memory and 19 | strings. Not all types of buffer overflows can be detected with this library, 20 | but it does provide an extra level of validation for some functions that are 21 | potentially a source of buffer overflow flaws. It protects both C and C++ code. 22 | 23 | 24 | %package devel 25 | Summary: The OpenOSC development package 26 | Group: Development/Libraries 27 | Requires: openosc%{?_isa} = %{version}-%{release} 28 | 29 | %description devel 30 | OpenOSC development package, containing both header files and runtime library. 31 | 32 | %package tools 33 | Summary: The OpenOSC tools package 34 | Group: Development/Libraries 35 | 36 | %description tools 37 | OpenOSC tools package, containing the tools to decode OSC tracebacks and 38 | collect OSC metrics. 39 | 40 | %package static 41 | Summary: The OpenOSC static library package 42 | Group: Development/Libraries 43 | Requires: openosc-devel = %{version}-%{release} 44 | 45 | %description static 46 | OpenOSC static package, containing the static library. 47 | 48 | %prep 49 | %autosetup -n openosc-%{version} 50 | 51 | 52 | %build 53 | %configure 54 | make %{?_smp_mflags} 55 | 56 | 57 | %install 58 | %make_install 59 | 60 | 61 | %files 62 | %{_libdir}/lib*.so.0* 63 | 64 | %files devel 65 | %{_libdir}/lib*.so 66 | %{_includedir}/*.h 67 | 68 | %files tools 69 | %{_bindir}/oscdecode.py 70 | %{_bindir}/oscmetrics.py 71 | 72 | %files static 73 | %{_libdir}/lib*.a 74 | 75 | 76 | %changelog 77 | * Sun Nov 25 2018 Yongkui Han PACKAGE_VERSION-1 78 | - Initial packaging. 79 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Define to 1 if you have the header file. */ 4 | #undef HAVE_DLFCN_H 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_INTTYPES_H 8 | 9 | /* Define to 1 if you have the `ciscosafec' library (-lciscosafec). */ 10 | #undef HAVE_LIBCISCOSAFEC 11 | 12 | /* Define to 1 if you have the `dl' library (-ldl). */ 13 | #undef HAVE_LIBDL 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_MEMORY_H 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #undef HAVE_SAFEC_SAFE_LIB_H 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #undef HAVE_SAFE_LIB_H 23 | 24 | /* Define to 1 if you have the header file. */ 25 | #undef HAVE_STDINT_H 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_STDLIB_H 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_STRINGS_H 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_STRING_H 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #undef HAVE_SYS_STAT_H 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_SYS_TYPES_H 41 | 42 | /* Define to 1 if you have the header file. */ 43 | #undef HAVE_UNISTD_H 44 | 45 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 46 | */ 47 | #undef LT_OBJDIR 48 | 49 | /* Define to 1 if your C compiler doesn't accept -c and -o together. */ 50 | #undef NO_MINUS_C_MINUS_O 51 | 52 | /* Name of package */ 53 | #undef PACKAGE 54 | 55 | /* Define to the address where bug reports for this package should be sent. */ 56 | #undef PACKAGE_BUGREPORT 57 | 58 | /* Define to the full name of this package. */ 59 | #undef PACKAGE_NAME 60 | 61 | /* Define to the full name and version of this package. */ 62 | #undef PACKAGE_STRING 63 | 64 | /* Define to the one symbol short name of this package. */ 65 | #undef PACKAGE_TARNAME 66 | 67 | /* Define to the home page for this package. */ 68 | #undef PACKAGE_URL 69 | 70 | /* Define to the version of this package. */ 71 | #undef PACKAGE_VERSION 72 | 73 | /* Define to 1 if you have the ANSI C header files. */ 74 | #undef STDC_HEADERS 75 | 76 | /* Version number of package */ 77 | #undef VERSION 78 | -------------------------------------------------------------------------------- /test/openosc_test_nomap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | //#include "../include/openosc.h" 12 | #include 13 | #include 14 | 15 | /* Testing for OpenOSC nomap functionality */ 16 | 17 | int openosc_test_memcpy(void) { 18 | int len = 8; 19 | char dst[5] = ""; 20 | char src[20] = "I am the source"; 21 | memcpy(dst, src, 4); /* case 1 */ 22 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 23 | /* Below code may cause SSP (Stack Smashing Protector) to abort the process */ 24 | #if 0 25 | memcpy(dst, src, 7); /* case 2 */ 26 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 27 | memcpy(dst, src, 8); /* case 2 */ 28 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 29 | #endif 30 | memcpy(dst, src, (dst[3]-dst[2])/20); /* case 3 */ 31 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 32 | memcpy(&len-1, src, 1); /* case 4 */ 33 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 34 | printf("End of testing memcpy!\n"); 35 | return 0; 36 | } 37 | 38 | int openosc_test_memset(void) { 39 | int len = 8; 40 | char dst[5]; 41 | char src[20] = "I am the source"; 42 | memset(dst, 0, 4); /* case 1 */ 43 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 44 | /* Below code may cause SSP (Stack Smashing Protector) to abort the process */ 45 | #if 0 46 | memset(dst, 0, 7); /* case 2 */ 47 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 48 | memset(dst, 0, 8); /* case 2 */ 49 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 50 | #endif 51 | memset(dst, src[0], (dst[3]-dst[2])/20); /* case 3 */ 52 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 53 | memset(&len-1, 0, 1); /* case 4 */ 54 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 55 | printf("End of testing memset!\n"); 56 | return 0; 57 | } 58 | 59 | int main(void) { 60 | openosc_test_memcpy(); 61 | return openosc_test_memset(); 62 | } 63 | 64 | 65 | -------------------------------------------------------------------------------- /include/openosc_extern.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_EXTERN_H__ 11 | #define __OPENOSC_EXTERN_H__ 12 | 13 | /* import size_t definition only */ 14 | #define __need_size_t 15 | #include 16 | 17 | /* Define va_list */ 18 | #ifndef _VA_LIST 19 | #define _VA_LIST 20 | typedef __builtin_va_list va_list; 21 | #endif 22 | 23 | #ifndef OSC_THROW 24 | #ifdef __cplusplus 25 | #define OSC_THROW __THROW 26 | #else 27 | #define OSC_THROW 28 | #endif 29 | #endif 30 | 31 | /* libC APIs */ 32 | extern void *memcpy(void *dst, const void *src, size_t len) OSC_THROW; 33 | extern void *memmove(void *dst, const void *src, size_t len) OSC_THROW; 34 | extern void *memset(void *dst, int c, size_t len) OSC_THROW; 35 | extern void bcopy(const void *src, void *dst, size_t len) OSC_THROW; 36 | extern void bzero(void *dst, size_t len) OSC_THROW; 37 | extern char *strcpy(char *dst, const char *src) OSC_THROW; 38 | extern char *strncpy(char *dst, const char *src, size_t len) OSC_THROW; 39 | extern char *strcat(char *dst, const char *src) OSC_THROW; 40 | extern char *strncat(char *dst, const char *src, size_t len) OSC_THROW; 41 | extern size_t strlen(const char *src) OSC_THROW; 42 | extern size_t strnlen(const char *src, size_t maxlen) OSC_THROW; 43 | extern int vsnprintf(char *str, size_t len, const char *fmt, va_list ap) OSC_THROW; 44 | 45 | /* safeC APIs */ 46 | #ifdef HAS_SAFEC 47 | 48 | /* Defining rsize_t type */ 49 | #ifndef rsize_t_type 50 | #define rsize_t_type 51 | typedef __typeof__ (sizeof 0) rsize_t; 52 | #endif 53 | 54 | #ifndef errno_t_type 55 | #define errno_t_type 56 | typedef int errno_t; 57 | #endif 58 | 59 | extern errno_t memcmp_s(const void *s1, rsize_t s1max, 60 | const void *s2, rsize_t n, int *diff); 61 | extern errno_t memcpy_s(void *dest, rsize_t dmax, 62 | const void * src, rsize_t n); 63 | extern errno_t strcat_s(char *dest, rsize_t dmax, const char *src); 64 | extern errno_t strcmp_s(const char *s1, rsize_t s1max, 65 | const char *s2, int *indicator); 66 | extern errno_t strcpy_s(char *dest, rsize_t dmax, const char *src); 67 | extern errno_t strncat_s(char *dest, rsize_t dmax, 68 | const char *src, rsize_t n); 69 | extern errno_t strncpy_s(char *dest, rsize_t dmax, 70 | const char *src, rsize_t n); 71 | extern size_t strnlen_s(const char *s, size_t maxsize); 72 | extern errno_t strstr_s(char *s1, rsize_t s1max, const char *s2, 73 | rsize_t s2max, char **substring); 74 | 75 | #endif /* HAS_SAFEC */ 76 | 77 | #endif /* __OPENOSC_EXTERN_H__ */ 78 | -------------------------------------------------------------------------------- /test/openosc_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | //#include "../include/openosc.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* Testing OpenOSC public header for all 4 mapping cases. */ 17 | 18 | int openosc_test_memcpy(char *buf) { 19 | /* volatile so the compiler can’t know the value */ 20 | volatile int len = 8; 21 | char dst[5]; 22 | char src[20] = "I am the source"; 23 | memcpy(dst, (void *)(&len+2), 4); /* case 1, actually src over-read CASE8 */ 24 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 25 | memcpy(dst, src, 4); /* case 1, actually src over-read CASE1 */ 26 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 27 | #if 0 28 | void *ret = memcpy(dst, src, 14); /* case 2 */ 29 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 30 | #endif 31 | len = time(NULL)%7; 32 | memcpy(dst, src, len); /* case 3 */ 33 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 34 | memcpy(buf, src, 10); /* case 4 */ 35 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, buf); 36 | memcpy(buf, src, 21); /* case 4, actually src over-read CASEb */ 37 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, buf); 38 | printf("End of testing memcpy!\n"); 39 | return 0; 40 | } 41 | 42 | int openosc_test_strncpy(char *buf) { 43 | /* volatile so the compiler can’t know the value */ 44 | volatile int len = 8; 45 | char dst[5]; 46 | char src[20] = "I am the source"; 47 | strncpy(dst, (void *)(&len+2), 4); /* case 1 */ 48 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 49 | strncpy(dst, src, 4); /* case 1, actually src over-read CASE1 */ 50 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 51 | #if 0 52 | strncpy(dst, src, 14); /* case 2 */ 53 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 54 | #endif 55 | len = time(NULL)%5; 56 | strncpy(dst, src, len); /* case 3 */ 57 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 58 | strncpy(buf, src, 21); /* case 4 */ 59 | printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, buf); 60 | printf("End of testing memcpy!\n"); 61 | return 0; 62 | } 63 | 64 | int main(void) { 65 | srand(time(NULL)); 66 | char *buf = malloc(25); 67 | (void)openosc_test_memcpy(buf); 68 | return openosc_test_strncpy(buf); 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/openosc_test_cpp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | #define OPENOSC_TEST_RAND_RANGE 20 18 | 19 | int openosc_test_memcpy(void) { 20 | int len = 8; 21 | char dst[5]; 22 | char src[20] = "I am the source"; 23 | memcpy(dst, src, 4); /* case 1 */ 24 | //printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 25 | cout << "Line " << __LINE__ << ", func " << __FUNCTION__ << ", dst is: " << dst << endl; 26 | #if 1 27 | /* comment out to avoid compile-time error */ 28 | memcpy(dst, src, 7); /* case 2 */ 29 | //printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 30 | memcpy(dst, src, 8); /* case 2 */ 31 | //printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 32 | #endif 33 | memcpy(dst, src, rand()%10); /* case 3 */ 34 | memcpy(dst, src, (dst[3]-dst[2])/20); /* case 3 */ 35 | //printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 36 | memcpy(dst, src, (dst[3]-dst[2])/5 + 5); /* case 3 */ 37 | //printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 38 | memcpy(&len+2, src, 1); /* case 4 */ 39 | //printf("Line %d, func %s, dst is: %s\n", __LINE__, __FUNCTION__, dst); 40 | memcpy((void *)((char *)&len - rand()%10), src, 2); /* case 4 */ 41 | cout << "End of testing memcpy!" << endl; 42 | return 0; 43 | } 44 | 45 | int openosc_test_mempcpy(void) { 46 | int mylen = 8; 47 | char dest[5 * sizeof(char)]; 48 | const char src[20] = "I am the source"; 49 | int n = 4; 50 | mempcpy(dest, src, n); /* case 1 */ 51 | #if 1 /* comment out to avoid compile-time error */ 52 | n = 7; 53 | mempcpy(dest, src, n); /* case 2 */ 54 | n = 15; 55 | mempcpy(dest, src, n); /* case 2 */ 56 | #endif 57 | //volatile int n2 = 9; 58 | mempcpy(dest, src, rand()%10); /* case 3 */ 59 | //n = (src[18]-dest[2])/20; 60 | //mempcpy(dest, src, n); /* case 3 */ 61 | //n = (*((char *)&mylen - src[18] * 8))/20; 62 | //mempcpy(dest, src, n); /* case 3 */ 63 | n = 1; 64 | mempcpy((void *)((char *)&mylen - dest[18] * 4), src, n); /* case 4 */ 65 | mempcpy((void *)((char *)&mylen - rand()%10), src, n); /* case 4 */ 66 | cout << "End of testing mempcpy" << endl; 67 | return 0; 68 | } 69 | 70 | int main(void) { 71 | srand(time(NULL)); 72 | (void)openosc_test_memcpy(); 73 | (void)openosc_test_mempcpy(); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /include/openosc_safec_nomap_metric.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_SAFEC_NOMAP_METRIC_H__ 11 | #define __OPENOSC_SAFEC_NOMAP_METRIC_H__ 12 | 13 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 14 | 15 | #if (RTD_OSC_METRIC_METHOD == RTD_ASM_LOC_METHOD) 16 | 17 | #define MEMCMP_S_NOMAP_MAGIC ".loc 1 8390032" 18 | #define MEMCPY_S_NOMAP_MAGIC ".loc 1 8390048" 19 | #define STRCAT_S_NOMAP_MAGIC ".loc 1 8390064" 20 | #define STRCMP_S_NOMAP_MAGIC ".loc 1 8390080" 21 | #define STRCPY_S_NOMAP_MAGIC ".loc 1 8390096" 22 | #define STRNCAT_S_NOMAP_MAGIC ".loc 1 8390112" 23 | #define STRNCPY_S_NOMAP_MAGIC ".loc 1 8390128" 24 | #define STRNLEN_S_NOMAP_MAGIC ".loc 1 8390144" 25 | #define STRSTR_S_NOMAP_MAGIC ".loc 1 8390160" 26 | 27 | #elif (RTD_OSC_METRIC_METHOD == RTD_ASM_BYTE_METHOD) 28 | 29 | #define MEMCMP_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x01, 0x00\n" OSC_JUMPLABEL 30 | #define MEMCPY_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x02, 0x00\n" OSC_JUMPLABEL 31 | #define STRCAT_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x03, 0x00\n" OSC_JUMPLABEL 32 | #define STRCMP_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x04, 0x00\n" OSC_JUMPLABEL 33 | #define STRCPY_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x05, 0x00\n" OSC_JUMPLABEL 34 | #define STRNCAT_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x06, 0x00\n" OSC_JUMPLABEL 35 | #define STRNCPY_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x07, 0x00\n" OSC_JUMPLABEL 36 | #define STRNLEN_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x08, 0x00\n" OSC_JUMPLABEL 37 | #define STRSTR_S_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x09, 0x00\n" OSC_JUMPLABEL 38 | 39 | #endif 40 | 41 | #define MEMCMP_S_NOMAP_CASE ({__asm__(MEMCMP_S_NOMAP_MAGIC);}), 42 | #define MEMCPY_S_NOMAP_CASE ({__asm__(MEMCPY_S_NOMAP_MAGIC);}), 43 | #define STRCAT_S_NOMAP_CASE ({__asm__(STRCAT_S_NOMAP_MAGIC);}), 44 | #define STRCMP_S_NOMAP_CASE ({__asm__(STRCMP_S_NOMAP_MAGIC);}), 45 | #define STRCPY_S_NOMAP_CASE ({__asm__(STRCPY_S_NOMAP_MAGIC);}), 46 | #define STRNCAT_S_NOMAP_CASE ({__asm__(STRNCAT_S_NOMAP_MAGIC);}), 47 | #define STRNCPY_S_NOMAP_CASE ({__asm__(STRNCPY_S_NOMAP_MAGIC);}), 48 | #define STRNLEN_S_NOMAP_CASE ({__asm__(STRNLEN_S_NOMAP_MAGIC);}), 49 | #define STRSTR_S_NOMAP_CASE ({__asm__(STRSTR_S_NOMAP_MAGIC);}), 50 | 51 | #else 52 | 53 | #define MEMCMP_S_NOMAP_CASE 54 | #define MEMCPY_S_NOMAP_CASE 55 | #define STRCAT_S_NOMAP_CASE 56 | #define STRCMP_S_NOMAP_CASE 57 | #define STRCPY_S_NOMAP_CASE 58 | #define STRNCAT_S_NOMAP_CASE 59 | #define STRNCPY_S_NOMAP_CASE 60 | #define STRNLEN_S_NOMAP_CASE 61 | #define STRSTR_S_NOMAP_CASE 62 | 63 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 64 | 65 | #endif /*__OPENOSC_SAFEC_NOMAP_METRIC_H__ */ 66 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | TESTS = openosc_test openosc_test_chk openosc_test_nomap openosc_test_asan openosc_test_msan 2 | # test_harness takes longer time to complete, and openosc_fortify_test/openosc_test_cpp sometimes causes segmentation fault. 3 | #TESTS = openosc_test openosc_test_chk openosc_test_nomap openosc_test_asan openosc_test_msan openosc_test_cpp test_harness openosc_fortify_test 4 | check_PROGRAMS = openosc_test openosc_test_chk openosc_test_nomap openosc_test_asan openosc_test_msan test_harness openosc_fortify_test openosc_fortify_nomap_test 5 | if OPENOSC_TEST_CXX_PROG 6 | check_PROGRAMS += openosc_test_cpp 7 | endif 8 | if OPENOSC_TEST_HARNESS_WANT_COMPILE_TIME_CHECK 9 | check_PROGRAMS += test_harness_break 10 | endif 11 | 12 | openosc_test_SOURCES = openosc_test.c 13 | openosc_test_nomap_SOURCES = openosc_test_nomap.c 14 | openosc_test_chk_SOURCES = openosc_test_chk.c 15 | openosc_test_asan_SOURCES = openosc_test_asan.c 16 | openosc_test_msan_SOURCES = openosc_test_msan.c 17 | openosc_fortify_test_SOURCES = openosc_fortify_test.c 18 | openosc_fortify_nomap_test_SOURCES = openosc_fortify_test.c 19 | openosc_test_cpp_SOURCES = openosc_test_cpp.cpp 20 | if HAS_SAFEC 21 | test_harness_SOURCES = test_harness_aux.c test_harness_bosc.c test_harness_bosc_safec.c test_harness_bosc_utils.c test_harness.c test_harness_aux.h test_harness_bosc.h test_harness_defs.h 22 | test_harness_break_SOURCES = test_harness_compile_check.c test_harness_compile_check_safec.c test_harness_aux.h test_harness_bosc.h test_harness_defs.h 23 | test_harness_CFLAGS = -DHAS_SAFEC $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) -DBOSC_TH_COMPILER_VERSION='"$(CC) CFLAGS=$(CFLAGS)"' 24 | test_harness_break_CFLAGS = -DHAS_SAFEC $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 25 | else 26 | test_harness_SOURCES = test_harness_aux.c test_harness_bosc.c test_harness_bosc_utils.c test_harness.c test_harness_aux.h test_harness_bosc.h test_harness_defs.h 27 | test_harness_break_SOURCES = test_harness_compile_check.c test_harness_aux.h test_harness_bosc.h test_harness_defs.h 28 | test_harness_CFLAGS = $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) -DBOSC_TH_COMPILER_VERSION='"$(CC) CFLAGS=$(CFLAGS)"' 29 | test_harness_break_CFLAGS = $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 30 | endif 31 | 32 | OPENOSCTEST_CFLAGS = -I../include -include ../include/openosc.h -DOPENOSC_OVERFLOW_ERROR_OUT_DISABLE 33 | openosc_test_nomap_CFLAGS = -fno-inline $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 34 | openosc_test_CFLAGS = $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 35 | openosc_test_chk_CFLAGS = $(OPENOSC_CFLAGS) 36 | openosc_test_asan_CFLAGS = $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 37 | #openosc_test_asan_CFLAGS = $(OPENOSC_CFLAGS) -D_FORTIFY_SOURCE=2 38 | #openosc_test_asan_CFLAGS = -fsanitize=address -D_FORTIFY_SOURCE=2 39 | #openosc_test_msan_CFLAGS = $(OPENOSC_CFLAGS) -fsanitize=memory -D_FORTIFY_SOURCE=2 40 | openosc_test_msan_CFLAGS = $(OPENOSC_CFLAGS) -D_FORTIFY_SOURCE=2 41 | #test_harness_CFLAGS = $(OPENOSC_CFLAGS) -include ../include/openosc.h 42 | openosc_fortify_test_CFLAGS = $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 43 | openosc_fortify_nomap_test_CFLAGS = -fno-inline $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 44 | openosc_test_cpp_CXXFLAGS = $(OPENOSC_CFLAGS) $(OPENOSCTEST_CFLAGS) 45 | 46 | openosc_fortify_test_LDFLAGS = -L../src/.libs -lopenosc 47 | openosc_fortify_nomap_test_LDFLAGS = -L../src/.libs -lopenosc 48 | openosc_test_LDFLAGS = -L../src/.libs -lopenosc 49 | openosc_test_nomap_LDFLAGS = -L../src/.libs -lopenosc 50 | openosc_test_chk_LDFLAGS = -L../src/.libs -lopenosc 51 | openosc_test_asan_LDFLAGS = -L../src/.libs -lopenosc 52 | openosc_test_msan_LDFLAGS = -L../src/.libs -lopenosc 53 | openosc_test_cpp_LDFLAGS = -L../src/.libs -lopenosc 54 | test_harness_LDFLAGS = -L../src/.libs -lopenosc -lpthread -rdynamic 55 | test_harness_break_LDFLAGS = -L../src/.libs -lopenosc -lpthread -rdynamic 56 | -------------------------------------------------------------------------------- /test/test_harness_bosc_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include "test_harness_defs.h" 14 | #include "test_harness_bosc.h" 15 | 16 | void 17 | bosc_th_print_test_conditions (char *testname, char *desc, 18 | int num_param, th_test_param params[], 19 | int expect_dcdi) 20 | { 21 | int i; 22 | 23 | printf("\n========================================\n"); 24 | printf("Test Name: %s \n", testname); 25 | printf("Test Description:\n %s\n", desc); 26 | printf("Test Parameters:\n"); 27 | for (i = 0; i < num_param; i++) 28 | printf(" %s = %i\n", params[i].name, params[i].value); 29 | printf("Expected Outcome:\n %sDCDI error message\n", 30 | expect_dcdi ? "" : "No "); 31 | } 32 | 33 | /* 34 | * bosc_th_setup_buffer 35 | * 36 | * Fill size bytes of buffer buf according to the fill_type 37 | * 38 | * Return FALSE on error, TRUE otherwise 39 | */ 40 | int 41 | bosc_th_setup_buffer (char *buf, int size, th_fill_type fill_type) 42 | { 43 | int i; 44 | 45 | if (!buf) 46 | return FALSE; 47 | 48 | switch (fill_type) { 49 | case TH_FILL_ZERO: 50 | bzero(buf, size); 51 | break; 52 | 53 | case TH_FILL_ONE: 54 | memset(buf, 0xff, size); 55 | break; 56 | 57 | case TH_FILL_SEQ: 58 | for (i = 0; i < size; i++) 59 | buf[i] = (unsigned char)(i + 1); 60 | break; 61 | 62 | case TH_FILL_STR: 63 | for (i = 0; i < size-1; i++) 64 | buf[i] = (unsigned char)(i + 'a'); 65 | buf[size-1] = '\0'; 66 | break; 67 | 68 | default: 69 | return FALSE; 70 | } 71 | 72 | return TRUE; 73 | } 74 | 75 | /* 76 | * bosc_th_print_mem 77 | * 78 | * print size bytes of buffer buf 79 | * 80 | * Return FALSE on error, TRUE otherwise 81 | */ 82 | int 83 | bosc_th_print_mem (char *buf, int size) 84 | { 85 | int i; 86 | 87 | if (!buf) 88 | return FALSE; 89 | 90 | printf(" "); 91 | for (i = 0; i < size; i++) { 92 | printf("0x%02x ", ((int)buf[i] != -1) ? buf[i] : 255); 93 | 94 | /* Print up to 16 bytes on a single line */ 95 | if (15 == (i % 16)) 96 | printf ("\n "); 97 | } 98 | printf("\n"); 99 | return TRUE; 100 | } 101 | 102 | /* 103 | * bosc_th_print_result 104 | * 105 | * Perform memory comparision between two given buffers for the 106 | * specified size and print the test result based on pass_if_equal 107 | * condition. If pass_if_equal is TRUE and buf1 is the same as buf2 108 | * then a pass message is printed. Otherwise, fail message is printed. 109 | * 110 | * Return FALSE on error, TRUE otherwise 111 | */ 112 | int 113 | bosc_th_print_result (const void *buf1, const void *buf2, size_t size, 114 | th_pass_criteria criteria) 115 | { 116 | int equal; 117 | 118 | equal = !memcmp(buf1, buf2, size); 119 | 120 | if ((criteria == TH_PASS_EQU && equal ) || (criteria == TH_PASS_EQU && !equal )) { 121 | printf("\nMemory Comparison Passed\n"); 122 | } else { 123 | printf("\nMemory Comparison Failed\n"); 124 | } 125 | return TRUE; 126 | } 127 | 128 | /* 129 | * bosc_th_print_result_safec 130 | * 131 | * This function will print the status of each function. safeC 132 | * API get passed, when expected outcome is No DCDI Error and 133 | * the respective safec returns as EOK. Otherwise failure case. 134 | */ 135 | 136 | void 137 | bosc_th_print_result_safec(int result, int criteria) 138 | { 139 | if (result == criteria) { 140 | printf ("safeC API Passed\n"); 141 | } else { 142 | printf ("safeC API Failed\n"); 143 | } 144 | } 145 | 146 | -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | What is the BOSC Test Harness? 2 | 3 | The BOSC Test Harness runs a series of tests to demonstrate the 4 | buffer-size measuring capabilities of a compiler's Built-in 5 | Object Size Check (BOSC). BOSC prevents standard functions from 6 | writing outside passed-in buffers by first determining the size 7 | of the buffer when possible. BOSC implementations vary on their 8 | ability to determine buffer size. The tests cover a variety of 9 | situations where buffers can be encountered. 10 | 11 | The test harness can be used to verify that new versions of 12 | compilers don't have regressions or to test for feature parity 13 | between a newly-created implementation and an existing 14 | implementation. 15 | 16 | Intended Product Family 17 | 18 | Any product that uses BOSC. 19 | 20 | Intended Audience 21 | 22 | Any engineer who works on the infrastructure of a product and wants 23 | to test the coverage of their BOSC implementation can use 24 | the BOSC test harness. An engineer may find understanding how the 25 | compiler interacts with the product to be helpful, but such 26 | knowledge is not necessary. 27 | 28 | Deliverables 29 | 30 | N/A 31 | 32 | How-to Guide 33 | 34 | The test harness is a collection of buffer size tests that is 35 | intended to be compiled with the target compiler. The test harness 36 | also test the effectiveness and correctness of BOSC remap header file 37 | for both compile time and runtime detection of buffer overflow. 38 | 39 | The test harness requires libc, libpthread, libciscoosc and libciscosafec 40 | so make sure these libraries are available in your build enviroment before 41 | building the test harness. Below are steps to get these libraries setup for 42 | building the test harness. 43 | 44 | libc and libpthread should be in standard tool chain locations. SYSROOT 45 | variable in ../pre.mk file can be set to point to tool chain specific 46 | location if needed. 47 | 48 | libciscoosc can be built by running make at the top level directory 49 | of the library source tree. The test harness' Makefile assumes 50 | libciscoosc.so is one level up in the directory structure. 51 | 52 | libciscosafec can be built from CSM source code located at: 53 | https://cisco.jiveon.com/groups/common-security-modules/projects/ciscosafec 54 | Header files and shared library for safeC, if not in standard locations, 55 | can be specified with SAFEC_INC_PATH and SAFEC_LIB_PATH in ../pre.mk file. 56 | BOSC checker for safeC can be disabled by setting HAS_SAFEC to FALSE in 57 | ../pre.mk 58 | 59 | To test a compiler, update CC and SYSROOT in ../pre.mk file. Then run 60 | "make all" from the top level directory of the library. This will build 61 | libciscoosc.so and placed it in the current directory and test_harness 62 | executable under test directory. 63 | 64 | Test harness can be ran manually by first setting LD_LIBRARY_PATH to 65 | point to the location of libciscoosc and libciscosafec and then execute 66 | test_harness binary. 67 | export LD_LIBRARY_PATH=../: 68 | ./test_harness > test_harness.result 2>&1 69 | 70 | Test harness can be also be built and ran automatically under test directory: 71 | make run_test_harness 72 | 73 | Test results are stored in test_harness.result. 74 | 75 | Run "make break" to test the compile time checking. Note that this 76 | should typically fail to build and, instead, print an error 77 | indicating that there will always be a buffer overflow. 78 | 79 | 80 | Limitations 81 | 82 | Not all these tests should carry equal weight when 83 | comparing BOSC implementations. For example, the test 84 | 'STRUCT_PTR_STRUCT_CHAR_SIZE' can account for a large number of 85 | instances in practice (see EDCS-865445.) 86 | 87 | Resources and Schedule Implications 88 | 89 | N/A 90 | 91 | Performance Characteristics 92 | 93 | N/A 94 | 95 | Deployments 96 | 97 | N/A 98 | 99 | References 100 | 101 | EDCS-636385 102 | - CSDL 4arg Implementation Guide 103 | EDCS-865445 104 | - BOSC vs. 4arg 105 | http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html 106 | - GCC object size checking 107 | -------------------------------------------------------------------------------- /include/openosc_safec_nomap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_SAFEC_NOMAP_H__ 11 | #define __OPENOSC_SAFEC_NOMAP_H__ 12 | 13 | /* osc_safec_map.h and osc_safec_nomap.h are mutually exclusive */ 14 | #ifndef __OPENOSC_SAFEC_MAP_H__ 15 | 16 | /* if OSC metric feature is disabled, we can completely exclude this header */ 17 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 18 | 19 | #include "openosc_safec_nomap_metric.h" 20 | #include "openosc_extern.h" 21 | 22 | /* Mapping for memcmp_s */ 23 | 24 | static inline __attribute__ ((always_inline)) errno_t 25 | openosc_memcmp_s (const void *s1, rsize_t s1max, 26 | const void *s2, rsize_t n, int *diff) 27 | { 28 | return (MEMCMP_S_NOMAP_CASE memcmp_s(s1, s1max, s2, n, diff)); 29 | } 30 | 31 | #undef memcmp_s 32 | #define memcmp_s(s1, s1max, s2, n, diff) \ 33 | openosc_memcmp_s (s1, s1max, s2, n, diff) 34 | 35 | /* Mapping for memcpy_s */ 36 | 37 | static inline __attribute__ ((always_inline)) errno_t 38 | openosc_memcpy_s (void *dest, rsize_t dmax, const void *src, rsize_t n) 39 | { 40 | return (MEMCPY_S_NOMAP_CASE memcpy_s(dest, dmax, src, n)); 41 | } 42 | 43 | #undef memcpy_s 44 | #define memcpy_s(dest, dmax, src, n) \ 45 | openosc_memcpy_s (dest, dmax, src, n) 46 | 47 | /* Mapping for strcat_s */ 48 | 49 | static inline __attribute__ ((always_inline)) errno_t 50 | openosc_strcat_s (char *dest, rsize_t dmax, const char *src) 51 | { 52 | return (STRCAT_S_NOMAP_CASE strcat_s(dest, dmax, src)); 53 | } 54 | 55 | #undef strcat_s 56 | #define strcat_s(dest, dmax, src) \ 57 | openosc_strcat_s (dest, dmax, src) 58 | 59 | /* Mapping for strcmp_s */ 60 | 61 | static inline __attribute__ ((always_inline)) errno_t 62 | openosc_strcmp_s (const char *s1, rsize_t s1max, 63 | const char *s2, int *indicator) 64 | { 65 | return (STRCMP_S_NOMAP_CASE strcmp_s(s1, s1max, s2, indicator)); 66 | } 67 | 68 | #undef strcmp_s 69 | #define strcmp_s(s1, slmax, s2, indicator) \ 70 | openosc_strcmp_s (s1, slmax, s2, indicator) 71 | 72 | /* Mapping for strcpy_s */ 73 | 74 | static inline __attribute__ ((always_inline)) errno_t 75 | openosc_strcpy_s (char *dest, rsize_t dmax, const char *src) 76 | { 77 | return (STRCPY_S_NOMAP_CASE strcpy_s(dest, dmax, src)); 78 | } 79 | 80 | #undef strcpy_s 81 | #define strcpy_s(dest, dmax, src) \ 82 | openosc_strcpy_s (dest, dmax, src) 83 | 84 | /* Mapping for strncat_s */ 85 | 86 | static inline __attribute__ ((always_inline)) errno_t 87 | openosc_strncat_s (char *dest, rsize_t dmax, const char *src, rsize_t n) 88 | { 89 | return (STRNCAT_S_NOMAP_CASE strncat_s(dest, dmax, src, n)); 90 | } 91 | 92 | #undef strncat_s 93 | #define strncat_s(dest, dmax, src, n) \ 94 | openosc_strncat_s (dest, dmax, src, n) 95 | 96 | /* Mapping for strncpy_s */ 97 | 98 | static inline __attribute__ ((always_inline)) errno_t 99 | openosc_strncpy_s (char *dest, rsize_t dmax, const char *src, rsize_t n) 100 | { 101 | return (STRNCPY_S_NOMAP_CASE strncpy_s(dest, dmax, src, n)); 102 | } 103 | 104 | #undef strncpy_s 105 | #define strncpy_s(dest, dmax, src, n) \ 106 | openosc_strncpy_s (dest, dmax, src, n) 107 | 108 | /* Mapping for strnlen_s */ 109 | 110 | static inline __attribute__ ((always_inline)) size_t 111 | openosc_strnlen_s (const char *s, size_t maxsize) 112 | { 113 | return (STRNLEN_S_NOMAP_CASE strnlen_s(s, maxsize)); 114 | } 115 | 116 | #undef strnlen_s 117 | #define strnlen_s(s, maxsize) \ 118 | openosc_strnlen_s (s, maxsize) 119 | 120 | /* Mapping for strstr_s */ 121 | 122 | static inline __attribute__ ((always_inline)) errno_t 123 | openosc_strstr_s (char *s1, rsize_t s1max, 124 | const char *s2, rsize_t s2max, char **substring) 125 | { 126 | return (STRSTR_S_NOMAP_CASE strstr_s(s1, s1max, s2, s2max, substring)); 127 | } 128 | 129 | #undef strstr_s 130 | #define strstr_s(s1, s1max, s2, s2max, substring) \ 131 | openosc_strstr_s (s1, s1max, s2, s2max, substring) 132 | 133 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 134 | 135 | #endif /* ifndef __OPENOSC_SAFEC_MAP_H__ */ 136 | 137 | #endif /* __OPENOSC_SAFEC_NOMAP_H__ */ 138 | 139 | -------------------------------------------------------------------------------- /test/test_harness_bosc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef _TEST_HARNESS_BOSC_H_ 11 | #define _TEST_HARNESS_BOSC_H_ 12 | 13 | #include "test_harness_defs.h" 14 | 15 | #ifndef FALSE 16 | #define FALSE 0 17 | #endif 18 | 19 | #ifndef TRUE 20 | #define TRUE (!FALSE) 21 | #endif 22 | 23 | /* Number of tests in th_testcase array */ 24 | #define TH_NUM_TEST 5 25 | #define TH_NUM_TEST_SAFEC 9 26 | 27 | /* Number of tests in th_strcat_test array */ 28 | #define TH_NUM_STRCAT_TEST 3 29 | 30 | #define TH_RESULT_NO_DCDI 0 31 | #define TH_RESULT_DCDI (!TH_RESULT_NO_DCDI) 32 | 33 | #define TH_TEST_START_STR "*** Begin Executing Test ***\n" 34 | #define TH_TEST_END_STR "*** Execution Complete ***\n" 35 | 36 | /* 37 | * Length of dst string including the terminating null used in strcat() 38 | * and strncat() test 39 | */ 40 | #define TH_STRCAT_DST_LEN 5 41 | 42 | typedef enum _th_fill_type { 43 | TH_FILL_ZERO, /* Fill buffer with all zero */ 44 | TH_FILL_ONE, /* Fill buffer with all one */ 45 | TH_FILL_SEQ, /* Fill buffer with increment values starting from 1 */ 46 | TH_FILL_STR /* Fill buffer with sequential character starting from 'a' 47 | * and terminate the last character of the string with NULL 48 | */ 49 | } th_fill_type; 50 | 51 | typedef enum _th_pass_criteria { 52 | TH_PASS_EQU, /* Test pass if 2 buffers are the same */ 53 | TH_PASS_NOT_EQU, /* Test pass if 2 buffers are NOT the same */ 54 | TH_PASS_EOK = 0, 55 | TH_PASS_NOT_EOK, 56 | } th_pass_criteria; 57 | 58 | /* Test parameters and expected results for each test case */ 59 | typedef struct _th_test_data { 60 | char *desc; /* Test description */ 61 | int size; /* Input size parameter for the remap API */ 62 | int expect_dcdi; /* Expect DCDI error msg or not */ 63 | th_pass_criteria criteria; /* Pass/fail criteria */ 64 | } th_test_data; 65 | 66 | /* Test parameters and expected results for each safec test cases */ 67 | typedef struct _th_test_safec_data { 68 | char *desc; /* Test description */ 69 | int dmax; /* Input size dmax parameter */ 70 | int slen; /* Input size slen parameter */ 71 | int expect_dcdi; /* Expect DCDI error msg or not */ 72 | th_pass_criteria criteria; /* Pass/fail criteria */ 73 | } th_test_safec_data; 74 | 75 | /* Test parameter description and value */ 76 | typedef struct _th_test_param { 77 | char *name; /* Parameter name */ 78 | int value; /* Parameter value */ 79 | } th_test_param; 80 | 81 | /* Macro to setup various test buffers */ 82 | #define TH_SETUP_ZERO_DST_BUF() \ 83 | bosc_th_setup_buffer(th_dst, STATIC_BUF_SIZE, TH_FILL_ZERO) 84 | #define TH_SETUP_ZERO_SRC_BUF() \ 85 | bosc_th_setup_buffer(th_src, STATIC_BUF_SIZE, TH_FILL_ZERO) 86 | #define TH_SETUP_ONE_DST_BUF() \ 87 | bosc_th_setup_buffer(th_dst, STATIC_BUF_SIZE, TH_FILL_ONE) 88 | #define TH_SETUP_ONE_SRC_BUF() \ 89 | bosc_th_setup_buffer(th_src, STATIC_BUF_SIZE, TH_FILL_ONE) 90 | #define TH_SETUP_SEQ_SRC_BUF() \ 91 | bosc_th_setup_buffer(th_src, STATIC_BUF_SIZE, TH_FILL_SEQ) 92 | #define TH_SETUP_STR_DST_BUF(n) \ 93 | bosc_th_setup_buffer(th_dst, n, TH_FILL_STR) 94 | #define TH_SETUP_STR_SRC_BUF(n) \ 95 | bosc_th_setup_buffer(th_src, n, TH_FILL_STR) 96 | 97 | /* Macro to print the entire th_dst and th_src buffer */ 98 | #define TH_PRINT_DST() ({ \ 99 | printf("Content of Destination buffer:\n"); \ 100 | bosc_th_print_mem(th_dst, STATIC_BUF_SIZE);}) 101 | #define TH_PRINT_SRC() ({ \ 102 | printf("Content of Source buffer:\n"); \ 103 | bosc_th_print_mem(th_src, STATIC_BUF_SIZE);}) 104 | 105 | /* Macro to print the first n bytes of th_dst and th_src buffer */ 106 | #define TH_PRINT_N_DST(n) ({ if (n) { \ 107 | printf("First %i bytes of Destination buffer:\n", n); \ 108 | bosc_th_print_mem(th_dst, n);}}) 109 | #define TH_PRINT_N_SRC(n) ({ if (n) { \ 110 | printf("First %i bytes of Source buffer:\n", n); \ 111 | bosc_th_print_mem(th_src, n);}}) 112 | 113 | /* test_harness_bosc_utils.c */ 114 | void bosc_th_print_test_conditions (char *api_name, char *desc, 115 | int num_param, th_test_param params[], 116 | int expect_dcdi); 117 | int bosc_th_setup_buffer (char *buf, int size, th_fill_type fill_type); 118 | int bosc_th_print_mem (char *buf, int size); 119 | int bosc_th_print_result (const void *buf1, const void *buf2, size_t size, 120 | th_pass_criteria criteria); 121 | void bosc_th_print_result_safec (int result, int criteria); 122 | 123 | /* test_harness_bosc.c */ 124 | void bosc_th_setup_3arg_test (char *api_name, int testcase_idx); 125 | 126 | #endif /* _TEST_HARNESS_BOSC_H_ */ 127 | -------------------------------------------------------------------------------- /include/openosc_redefine_nomap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_REDEFINE_NOMAP_H__ 11 | #define __OPENOSC_REDEFINE_NOMAP_H__ 12 | 13 | /* openosc_redefine_map.h and openosc_redefine_nomap.h are mutually exclusive */ 14 | #ifndef __OPENOSC_REDEFINE_MAP_H__ 15 | 16 | /* if OSC metric feature is disabled, we can completely exclude this osc_nomap.h header */ 17 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 18 | 19 | #ifdef __cplusplus 20 | #include 21 | extern "C" 22 | { 23 | #endif 24 | 25 | #include "openosc_extern.h" 26 | 27 | 28 | /* Mapping for memcpy */ 29 | 30 | static inline __attribute__ ((always_inline)) void * 31 | openosc_memcpy (void *dst, const void *src, size_t len) 32 | OSC_THROW 33 | { 34 | return (MEMCPY_NOMAP_CASE memcpy(dst, src, len)); 35 | } 36 | 37 | #undef memcpy 38 | #define memcpy(dest, src, len) \ 39 | openosc_memcpy(dest, src, len) 40 | 41 | /* Mapping for memmove */ 42 | 43 | static inline __attribute__ ((always_inline)) void * 44 | openosc_memmove (void *dst, const void *src, size_t len) 45 | OSC_THROW 46 | { 47 | return (MEMMOVE_NOMAP_CASE memmove(dst, src, len)); 48 | } 49 | 50 | #undef memmove 51 | #define memmove(dest, src, len) \ 52 | openosc_memmove(dest, src, len) 53 | 54 | /* Mapping for memset */ 55 | 56 | static inline __attribute__ ((always_inline)) void * 57 | openosc_memset (void *dst, int c, size_t len) 58 | OSC_THROW 59 | { 60 | return (MEMSET_NOMAP_CASE memset(dst, c, len)); 61 | } 62 | 63 | #undef memset 64 | #define memset(dst, c, len) \ 65 | openosc_memset(dst, c, len) 66 | 67 | /* Mapping for bcopy */ 68 | 69 | static inline __attribute__ ((always_inline)) void 70 | openosc_bcopy (const void *src, void *dst, size_t len) 71 | OSC_THROW 72 | { 73 | return (BCOPY_NOMAP_CASE bcopy(src, dst, len)); 74 | } 75 | 76 | #undef bcopy 77 | #define bcopy(src, dst, len) \ 78 | openosc_bcopy(src, dst, len) 79 | 80 | /* Mapping for bzero */ 81 | 82 | static inline __attribute__ ((always_inline)) void 83 | openosc_bzero (void *dst, size_t len) 84 | OSC_THROW 85 | { 86 | return (BZERO_NOMAP_CASE bzero(dst, len)); 87 | } 88 | 89 | #undef bzero 90 | #define bzero(dst, len) \ 91 | openosc_bzero(dst, len) 92 | 93 | /* Mapping for strcpy */ 94 | 95 | static inline __attribute__ ((always_inline)) char * 96 | openosc_strcpy (char *dst, const char *src) 97 | OSC_THROW 98 | { 99 | return (STRCPY_NOMAP_CASE strcpy(dst, src)); 100 | } 101 | 102 | #undef strcpy 103 | #define strcpy(dst, src) \ 104 | openosc_strcpy(dst, src) 105 | 106 | 107 | /* Mapping for strncpy */ 108 | #define _HAVE_STRING_ARCH_strncpy 1 109 | 110 | static inline __attribute__ ((always_inline)) char * 111 | openosc_strncpy (char *dst, const char *src, size_t len) 112 | OSC_THROW 113 | { 114 | return (STRNCPY_NOMAP_CASE strncpy(dst, src, len)); 115 | } 116 | 117 | #undef strncpy 118 | #define strncpy(dest, src, len) \ 119 | openosc_strncpy(dest, src, len) 120 | 121 | /* Mapping for strcat */ 122 | 123 | static inline __attribute__ ((always_inline)) char * 124 | openosc_strcat (char *dst, const char *src) 125 | OSC_THROW 126 | { 127 | return (STRCAT_NOMAP_CASE strcat(dst, src)); 128 | } 129 | 130 | #undef strcat 131 | #define strcat(dst, src) \ 132 | openosc_strcat(dst, src) 133 | 134 | /* Mapping for strncat */ 135 | #define _HAVE_STRING_ARCH_strncat 1 136 | 137 | static inline __attribute__ ((always_inline)) char * 138 | openosc_strncat (char *dst, const char *src, size_t len) 139 | OSC_THROW 140 | { 141 | return (STRNCAT_NOMAP_CASE strncat(dst, src, len)); 142 | } 143 | 144 | #undef strncat 145 | #define strncat(dst, src, len) \ 146 | openosc_strncat(dst, src, len) 147 | 148 | /* Mapping for strnlen */ 149 | 150 | #define HAVE_STRNLEN 1 151 | 152 | static inline __attribute__ ((always_inline)) size_t 153 | openosc_strnlen (const char *s, size_t maxlen) 154 | OSC_THROW 155 | { 156 | return (STRNLEN_NOMAP_CASE strnlen(s, maxlen)); 157 | } 158 | 159 | #undef strnlen 160 | #define strnlen(s, maxlen) \ 161 | openosc_strnlen(s, maxlen) 162 | 163 | #ifndef OPENOSC_VALIST_NOSUPPORT 164 | 165 | /* Mapping for vsnprintf */ 166 | 167 | static inline __attribute__ ((always_inline)) int 168 | openosc_vsnprintf (char *str, size_t len, 169 | const char *fmt, va_list ap) 170 | OSC_THROW 171 | { 172 | return (VSNPRINTF_NOMAP_CASE vsnprintf(str, len, fmt, ap)); 173 | } 174 | 175 | #undef vsnprintf 176 | #define vsnprintf(str, len, format, ap) \ 177 | openosc_vsnprintf(str, len, format, ap) 178 | 179 | /* avoid redefinition */ 180 | #define HAVE_VSNPRINTF 1 181 | 182 | #endif /* OPENOSC_VALIST_NOSUPPORT */ 183 | 184 | #ifdef HAS_SAFEC 185 | #include "openosc_safec_nomap.h" 186 | #endif 187 | 188 | #ifdef __cplusplus 189 | } 190 | #endif 191 | 192 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 193 | 194 | #endif /* ifndef __OPENOSC_REDEFINE_MAP_H__ */ 195 | 196 | #endif /* __OPENOSC_REDEFINE_NOMAP_H__ */ 197 | 198 | -------------------------------------------------------------------------------- /include/openosc_redirect_nomap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | #ifndef __OPENOSC_REDIRECT_NOMAP_H__ 12 | #define __OPENOSC_REDIRECT_NOMAP_H__ 13 | 14 | /* openosc_redirct_map.h and openosc_redirect_nomap.h are mutually exclusive */ 15 | #ifndef __OPENOSC_REDIRECT_MAP_H__ 16 | 17 | /* if OSC metric feature is disabled, we can completely exclude this osc_nomap.h header */ 18 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 19 | 20 | #ifdef __cplusplus 21 | #include 22 | extern "C" 23 | { 24 | #endif 25 | 26 | #include "openosc_extern.h" 27 | 28 | 29 | /* Mapping for memcpy */ 30 | 31 | extern void *__REDIRECT_NTH (__openosc_memcpy_alias, 32 | (void *dst, const void *src, size_t len), memcpy); 33 | 34 | __openosc_fortify_function void * 35 | __NTH (memcpy (void *__restrict dst, const void *__restrict src, size_t len)) 36 | { 37 | return (MEMCPY_NOMAP_CASE __openosc_memcpy_alias(dst, src, len)); 38 | } 39 | 40 | /* Mapping for memmove */ 41 | 42 | extern void *__REDIRECT_NTH (__openosc_memmove_alias, 43 | (void *dst, const void *src, size_t len), memmove); 44 | 45 | __openosc_fortify_function void * 46 | __NTH (memmove (void *__restrict dst, const void *__restrict src, size_t len)) 47 | { 48 | return (MEMMOVE_NOMAP_CASE __openosc_memmove_alias(dst, src, len)); 49 | } 50 | 51 | /* Mapping for memset */ 52 | 53 | extern void *__REDIRECT_NTH (__openosc_memset_alias, 54 | (void *dst, int c, size_t len), memset); 55 | 56 | __openosc_fortify_function void * 57 | __NTH (memset (void *__restrict dst, int c, size_t len)) 58 | { 59 | return (MEMSET_NOMAP_CASE __openosc_memset_alias(dst, c, len)); 60 | } 61 | 62 | /* Mapping for bcopy */ 63 | 64 | extern void __REDIRECT_NTH (__openosc_bcopy_alias, 65 | (const void *src, void *dst, size_t len), bcopy); 66 | 67 | __openosc_fortify_function void 68 | __NTH (bcopy (const void *__restrict src, void *__restrict dst, size_t len)) 69 | { 70 | (BCOPY_NOMAP_CASE __openosc_bcopy_alias(src, dst, len)); 71 | } 72 | 73 | /* Mapping for bzero */ 74 | 75 | extern void __REDIRECT_NTH (__openosc_bzero_alias, 76 | (void *dst, size_t len), bzero); 77 | 78 | __openosc_fortify_function void 79 | __NTH (bzero (void *__restrict dst, size_t len)) 80 | { 81 | (BZERO_NOMAP_CASE __openosc_bzero_alias(dst, len)); 82 | } 83 | 84 | /* Mapping for strcpy */ 85 | 86 | extern char *__REDIRECT_NTH (__openosc_strcpy_alias, 87 | (char *dst, const char *src), strcpy); 88 | 89 | __openosc_fortify_function char * 90 | __NTH (strcpy (char *__restrict dst, const char *__restrict src)) 91 | { 92 | return (STRCPY_NOMAP_CASE __openosc_strcpy_alias(dst, src)); 93 | } 94 | 95 | /* Mapping for strncpy */ 96 | 97 | extern char *__REDIRECT_NTH (__openosc_strncpy_alias, 98 | (char *dst, const char *src, size_t len), strncpy); 99 | 100 | __openosc_fortify_function char * 101 | __NTH (strncpy (char *__restrict dst, const char *__restrict src, size_t len)) 102 | { 103 | return (STRNCPY_NOMAP_CASE __openosc_strncpy_alias(dst, src, len)); 104 | } 105 | 106 | /* Mapping for strcat */ 107 | 108 | extern char *__REDIRECT_NTH (__openosc_strcat_alias, 109 | (char *dst, const char *src), strcat); 110 | 111 | __openosc_fortify_function char * 112 | __NTH (strcat (char *__restrict dst, const char *__restrict src)) 113 | { 114 | return (STRCAT_NOMAP_CASE __openosc_strcat_alias(dst, src)); 115 | } 116 | 117 | /* Mapping for strncat */ 118 | 119 | extern char *__REDIRECT_NTH (__openosc_strncat_alias, 120 | (char *dst, const char *src, size_t len), strncat); 121 | 122 | __openosc_fortify_function char * 123 | __NTH (strncat (char *__restrict dst, const char *__restrict src, size_t len)) 124 | { 125 | return (STRNCAT_NOMAP_CASE __openosc_strncat_alias(dst, src, len)); 126 | } 127 | 128 | /* Mapping for strnlen */ 129 | 130 | extern size_t __REDIRECT_NTH (__openosc_strnlen_alias, 131 | (const char *s, size_t maxlen), strnlen); 132 | 133 | __openosc_fortify_function size_t 134 | __NTH (strnlen (const char *__restrict s, size_t maxlen)) 135 | { 136 | return (STRNLEN_NOMAP_CASE __openosc_strnlen_alias(s, maxlen)); 137 | } 138 | 139 | #ifndef OPENOSC_VALIST_NOSUPPORT 140 | 141 | /* Mapping for vsnprintf */ 142 | 143 | extern int __REDIRECT_NTH (__openosc_vsnprintf_alias, 144 | (char *str, size_t len, const char *fmt, va_list ap), vsnprintf); 145 | 146 | __openosc_fortify_function int 147 | __NTH (vsnprintf (char *__restrict str, size_t len, const char *__restrict fmt, va_list ap)) 148 | { 149 | return (VSNPRINTF_NOMAP_CASE __openosc_vsnprintf_alias(str, len, fmt, ap)); 150 | } 151 | 152 | #endif /* OPENOSC_VALIST_NOSUPPORT */ 153 | 154 | #ifdef HAS_SAFEC 155 | #include "openosc_safec_nomap.h" 156 | #endif 157 | 158 | #ifdef __cplusplus 159 | } 160 | #endif 161 | 162 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 163 | 164 | #endif /* ifndef __OPENOSC_REDIRECT_MAP_H__ */ 165 | 166 | #endif /* __OPENOSC_REDIRECT_NOMAP_H__ */ 167 | 168 | -------------------------------------------------------------------------------- /include/openosc_header_metric.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_HEADER_METRIC_H__ 11 | #define __OPENOSC_HEADER_METRIC_H__ 12 | 13 | /* OSC is not applicable to assembly language .S files */ 14 | #ifndef __ASSEMBLER__ 15 | 16 | /* 17 | * !!!WARNING!!! 18 | * Uncommenting the below line will turn on OSC-METRIC feature. 19 | * This feature inserts magic words into binary files for OSC function calls. 20 | * Make sure you understand the impact before enabling this feature. 21 | */ 22 | /* #define OPENOSC_METRIC_FEATURE_ENABLED */ 23 | 24 | /* 25 | * !!!WARNING!!! 26 | * Uncommenting the below line will turn on OSC-METRIC-ONLY mode. 27 | * This will insert magic words without any real OSC function remappings. 28 | * This mode helps quick image build on a new platform to get OSC Metrics. 29 | */ 30 | /* #define OPENOSC_METRIC_ONLY_MODE */ 31 | #ifdef OPENOSC_METRIC_ONLY_MODE 32 | #define OPENOSC_METRIC_FEATURE_ENABLED 33 | #endif 34 | 35 | /* Always enable OSC Header Metric unless explicitly disabled */ 36 | #ifndef OPENOSC_HEADER_METRIC_FEATURE_DISABLE 37 | #define OPENOSC_HEADER_METRIC_FEATURE_ENABLED 38 | #endif 39 | 40 | #ifdef OPENOSC_HEADER_METRIC_FEATURE_ENABLED 41 | /* 42 | * There are two OSC metric methods: 43 | * 1. ASM(".byte 0x80 0x81") approach. this is also called embedded watermarks. 44 | * 2. ASM(".loc 1 0x8081") approach. this uses DWARF debugging. 45 | * The DWARF .loc method is the default. 46 | * New OSC-METRICS method can be added in future as necessary. 47 | */ 48 | #define RTD_ASM_BYTE_METHOD 1 49 | #define RTD_ASM_LOC_METHOD 2 50 | 51 | /* -DOPENOSC_METRIC_METHOD=x can be used by a component to pick the method */ 52 | /* #define OPENOSC_METRIC_METHOD RTD_ASM_BYTE_METHOD */ 53 | #ifdef OPENOSC_METRIC_METHOD 54 | #define RTD_OSC_METRIC_METHOD OPENOSC_METRIC_METHOD 55 | #else 56 | #define RTD_OSC_METRIC_METHOD RTD_ASM_LOC_METHOD 57 | #endif 58 | 59 | #if (RTD_OSC_METRIC_METHOD == RTD_ASM_BYTE_METHOD) 60 | 61 | /* Automatically set appropriate architecture based on predefined flags */ 62 | #if defined __x86_64__ || defined __i386__ || defined __amd64__ || defined __X86__ || defined __X86_64__ 63 | #define OSC_ARCH_X86 64 | #elif defined __arm__ || defined __aarch64__ || defined __arm || defined _M_ARM 65 | #define OSC_ARCH_ARM 66 | #elif defined __mips__ || defined mips || defined __MIPS__ || defined __mips 67 | #define OSC_ARCH_MIPS 68 | #elif defined __ppc__ || defined __PPC__ || defined __PPC || defined _ARCH_PPC || defined __powerpc__ || defined __ppc64__ || defined __powerpc64__ 69 | #define OSC_ARCH_PPC 70 | #endif 71 | 72 | /* OSC_ARCH_* needs to be defined to get working binary file */ 73 | 74 | #ifdef OSC_ARCH_X86 75 | /* for x86 32bit and 64bit arch */ 76 | #define OSC_JUMPOVER "jmp 0f\n" 77 | #define OSC_JUMPLABEL "0:\n" 78 | #elif defined(OSC_ARCH_X86_32) 79 | /* for x86 32bit arch */ 80 | #define OSC_JUMPOVER ".byte 0xeb, 0x08\n" 81 | #define OSC_JUMPLABEL 82 | #elif defined(OSC_ARCH_ARM) 83 | /* for ARM 32bit and 64bit arch */ 84 | #define OSC_JUMPOVER "b 0f\n" 85 | #define OSC_JUMPLABEL "0:\n" 86 | #elif defined(OSC_ARCH_MIPS) 87 | /* for MIPS 32bit and 64bit arch */ 88 | #define OSC_JUMPOVER "b 0f\n" 89 | #define OSC_JUMPLABEL "0:\n" 90 | #elif defined(OSC_ARCH_PPC) 91 | /* for PowerPC 32bit and 64bit arch */ 92 | #define OSC_JUMPOVER "b 0f\n" 93 | #define OSC_JUMPLABEL "0:\n" 94 | #else 95 | /* for unknown arch or unsupported arch */ 96 | #define OSC_JUMPOVER 97 | #define OSC_JUMPLABEL 98 | #endif 99 | 100 | #endif /* RTD_OSC_METRIC_METHOD == RTD_ASM_BYTE_METHOD */ 101 | 102 | 103 | /* always insert a magic word if osc_header.h is included */ 104 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 105 | #define MAGIC_OSC_HEADER_H_INCLUDED 0x80818d8e80818d8e 106 | #else 107 | #define MAGIC_OSC_HEADER_H_INCLUDED 0x8e8d81808e8d8180 108 | #endif 109 | long long int __attribute__((weak)) rtd_osc_header_h_included_int = MAGIC_OSC_HEADER_H_INCLUDED; 110 | 111 | /* 112 | * The below useful info can be inserted into binary file. 113 | * If you don't need them or concerned with file size, then you can comment the below. 114 | */ 115 | #ifndef OPENOSC_METRIC_USEFUL_INFO_DISABLE 116 | #define OPENOSC_METRIC_USEFUL_INFO 117 | #endif 118 | 119 | #ifdef OPENOSC_METRIC_USEFUL_INFO 120 | 121 | #if defined __ICC 122 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 123 | #define MAGIC_OSC_COMPILER 0x97cfa25a9fb39d01 124 | #else 125 | #define MAGIC_OSC_COMPILER 0x019db39f5aa2cf97 126 | #endif 127 | #elif defined __clang__ 128 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 129 | #define MAGIC_OSC_COMPILER 0x97cfa25a9fb39d02 130 | #else 131 | #define MAGIC_OSC_COMPILER 0x029db39f5aa2cf97 132 | #endif 133 | #elif defined __GNUC__ 134 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 135 | #define MAGIC_OSC_COMPILER 0x97cfa25a9fb39d03 136 | #else 137 | #define MAGIC_OSC_COMPILER 0x039db39f5aa2cf97 138 | #endif 139 | #else 140 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 141 | #define MAGIC_OSC_COMPILER 0x97cfa25a9fb39d04 142 | #else 143 | #define MAGIC_OSC_COMPILER 0x049db39f5aa2cf97 144 | #endif 145 | #endif 146 | 147 | /* Which compiler gcc/icc/clang, etc */ 148 | long long int __attribute__((weak)) rtd_osc_compiler_int = MAGIC_OSC_COMPILER; 149 | 150 | #ifdef OPENOSC_METRIC_COMPILER_CCVERSION 151 | /* Compiler version can be very useful */ 152 | const char __attribute__((weak)) *rtd_osc_metric_cc_ver = "OSCMETRIC_CCVER_BEG:" __VERSION__ ":OSCMETRIC_CCVER_END" ; 153 | #endif 154 | 155 | #endif /* OPENOSC_METRIC_USEFUL_INFO */ 156 | 157 | #endif /* OPENOSC_HEADER_METRIC_FEATURE_ENABLED */ 158 | 159 | #endif /* __ASSEMBLER__ */ 160 | 161 | #endif /* __OPENOSC_HEADER_METRIC_H__ */ 162 | -------------------------------------------------------------------------------- /include/openosc_nomap_metric.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_NOMAP_METRIC_H__ 11 | #define __OPENOSC_NOMAP_METRIC_H__ 12 | 13 | #ifdef OPENOSC_HEADER_METRIC_FEATURE_ENABLED 14 | 15 | /* always insert a magic word if osc_nomap.h is included */ 16 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 17 | #define MAGIC_OSC_NOMAP_H_INCLUDED 0x80818d8e80818d8f 18 | #else 19 | #define MAGIC_OSC_NOMAP_H_INCLUDED 0x8f8d81808e8d8180 20 | #endif 21 | long long int __attribute__((weak)) rtd_osc_nomap_h_included_int = MAGIC_OSC_NOMAP_H_INCLUDED; 22 | 23 | #if !defined __OPTIMIZE__ 24 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 25 | #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d01 26 | #else 27 | #define MAGIC_OSC_NOMAP_H_REASON 0x018d81808e8d8180 28 | #endif 29 | #elif defined __NO_INLINE__ 30 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 31 | #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d02 32 | #else 33 | #define MAGIC_OSC_NOMAP_H_REASON 0x028d81808e8d8180 34 | #endif 35 | #elif defined _FORTIFY_SOURCE 36 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 37 | #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d03 38 | #else 39 | #define MAGIC_OSC_NOMAP_H_REASON 0x038d81808e8d8180 40 | #endif 41 | #elif defined OPENOSC_METRIC_ONLY_MODE 42 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 43 | #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d06 44 | #else 45 | #define MAGIC_OSC_NOMAP_H_REASON 0x068d81808e8d8180 46 | #endif 47 | #elif defined OSC_ASM 48 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 49 | #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d04 50 | #else 51 | #define MAGIC_OSC_NOMAP_H_REASON 0x048d81808e8d8180 52 | #endif 53 | #elif defined __STRICT_ANSI__ 54 | #if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 55 | #define MAGIC_OSC_NOMAP_H_REASON 0x80818d8e80818d05 56 | #else 57 | #define MAGIC_OSC_NOMAP_H_REASON 0x058d81808e8d8180 58 | #endif 59 | #endif /* !defined __OPTIMIZE__ */ 60 | /* identify the specific reason of including osc_nomap.h */ 61 | long long int __attribute__((weak)) rtd_osc_nomap_h_reason_int = MAGIC_OSC_NOMAP_H_REASON; 62 | 63 | #endif /* OPENOSC_HEADER_METRIC_FEATURE_ENABLED */ 64 | 65 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 66 | 67 | #if (RTD_OSC_METRIC_METHOD == RTD_ASM_LOC_METHOD) 68 | 69 | #define MEMCPY_NOMAP_MAGIC ".loc 1 8388864" 70 | #define MEMMOVE_NOMAP_MAGIC ".loc 1 8388880" 71 | #define MEMSET_NOMAP_MAGIC ".loc 1 8388896" 72 | #define BCOPY_NOMAP_MAGIC ".loc 1 8388912" 73 | #define BZERO_NOMAP_MAGIC ".loc 1 8388928" 74 | #define STRCPY_NOMAP_MAGIC ".loc 1 8388944" 75 | #define STRNCPY_NOMAP_MAGIC ".loc 1 8388960" 76 | #define STRCAT_NOMAP_MAGIC ".loc 1 8388976" 77 | #define STRNCAT_NOMAP_MAGIC ".loc 1 8388992" 78 | #define STRNLEN_NOMAP_MAGIC ".loc 1 8389008" 79 | #define VSNPRINTF_NOMAP_MAGIC ".loc 1 8389024" 80 | 81 | #elif (RTD_OSC_METRIC_METHOD == RTD_ASM_BYTE_METHOD) 82 | 83 | #define MEMCPY_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0xaa, 0x00\n" OSC_JUMPLABEL 84 | #define MEMMOVE_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x00, 0x00\n" OSC_JUMPLABEL 85 | #define MEMSET_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x11, 0x00\n" OSC_JUMPLABEL 86 | #define BCOPY_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x22, 0x00\n" OSC_JUMPLABEL 87 | #define BZERO_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x33, 0x00\n" OSC_JUMPLABEL 88 | #define STRCPY_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x44, 0x00\n" OSC_JUMPLABEL 89 | #define STRNCPY_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x55, 0x00\n" OSC_JUMPLABEL 90 | #define STRCAT_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x66, 0x00\n" OSC_JUMPLABEL 91 | #define STRNCAT_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x77, 0x00\n" OSC_JUMPLABEL 92 | #define STRNLEN_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x88, 0x00\n" OSC_JUMPLABEL 93 | #define VSNPRINTF_NOMAP_MAGIC OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd0, 0x99, 0x00\n" OSC_JUMPLABEL 94 | 95 | #endif 96 | 97 | #define MEMCPY_NOMAP_CASE ({__asm__(MEMCPY_NOMAP_MAGIC);}), 98 | #define MEMMOVE_NOMAP_CASE ({__asm__(MEMMOVE_NOMAP_MAGIC);}), 99 | #define MEMSET_NOMAP_CASE ({__asm__(MEMSET_NOMAP_MAGIC);}), 100 | #define BCOPY_NOMAP_CASE ({__asm__(BCOPY_NOMAP_MAGIC);}), 101 | #define BZERO_NOMAP_CASE ({__asm__(BZERO_NOMAP_MAGIC);}), 102 | #define STRCPY_NOMAP_CASE ({__asm__(STRCPY_NOMAP_MAGIC);}), 103 | #define STRNCPY_NOMAP_CASE ({__asm__(STRNCPY_NOMAP_MAGIC);}), 104 | #define STRCAT_NOMAP_CASE ({__asm__(STRCAT_NOMAP_MAGIC);}), 105 | #define STRNCAT_NOMAP_CASE ({__asm__(STRNCAT_NOMAP_MAGIC);}), 106 | #define STRNLEN_NOMAP_CASE ({__asm__(STRNLEN_NOMAP_MAGIC);}), 107 | #define VSNPRINTF_NOMAP_CASE ({__asm__(VSNPRINTF_NOMAP_MAGIC);}), 108 | 109 | #else 110 | 111 | #define MEMCPY_NOMAP_CASE 112 | #define MEMMOVE_NOMAP_CASE 113 | #define MEMSET_NOMAP_CASE 114 | #define BCOPY_NOMAP_CASE 115 | #define BZERO_NOMAP_CASE 116 | #define STRCPY_NOMAP_CASE 117 | #define STRNCPY_NOMAP_CASE 118 | #define STRCAT_NOMAP_CASE 119 | #define STRNCAT_NOMAP_CASE 120 | #define STRNLEN_NOMAP_CASE 121 | #define VSNPRINTF_NOMAP_CASE 122 | 123 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 124 | 125 | #endif /*__OPENOSC_NOMAP_METRIC_H__ */ 126 | -------------------------------------------------------------------------------- /test/test_harness_compile_check_safec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | #include 10 | #include 11 | #include "test_harness_bosc.h" 12 | 13 | extern char th_dst[STATIC_BUF_SIZE]; /* Destination buffer */ 14 | extern char th_src[STATIC_BUF_SIZE]; /* Source buffer */ 15 | 16 | /* For memcmp_s () */ 17 | void 18 | test_memcmp_s_dst_size_minus_1_NO_compile_error (void) 19 | { 20 | int diff; 21 | 22 | /* Expect no compile time error */ 23 | memcmp_s(th_dst, STATIC_BUF_SIZE - 1, th_src, STATIC_BUF_SIZE, &diff); 24 | } 25 | 26 | void 27 | test_memcmp_s_dst_size_NO_compile_error (void) 28 | { 29 | int diff; 30 | 31 | /* Expect no compile time error */ 32 | memcmp_s(th_dst, STATIC_BUF_SIZE, th_src, STATIC_BUF_SIZE, &diff); 33 | } 34 | 35 | void 36 | test_memcmp_s_dst_size_plus_1_compile_error (void) 37 | { 38 | int diff; 39 | 40 | /* Expect compile time error */ 41 | memcmp_s(th_dst, STATIC_BUF_SIZE + 1, th_src, STATIC_BUF_SIZE , &diff); 42 | } 43 | 44 | /* For memcpy_s () */ 45 | void 46 | test_memcpy_s_dst_size_minus_1_NO_compile_error (void) 47 | { 48 | 49 | /* Expect no compile time error */ 50 | memcpy_s(th_dst, STATIC_BUF_SIZE - 1, th_src, STATIC_BUF_SIZE); 51 | } 52 | 53 | void 54 | test_memcpy_s_dst_size_NO_compile_error (void) 55 | { 56 | 57 | /* Expect no compile time error */ 58 | memcpy_s(th_dst, STATIC_BUF_SIZE, th_src, STATIC_BUF_SIZE); 59 | } 60 | 61 | void 62 | test_memcpy_s_dst_size_plus_1_compile_error (void) 63 | { 64 | 65 | /* Expect compile time error */ 66 | memcpy_s(th_dst, STATIC_BUF_SIZE + 1, th_src, STATIC_BUF_SIZE); 67 | } 68 | 69 | /* For strcat_s () */ 70 | void 71 | test_strcat_s_dst_size_minus_1_NO_compile_error (void) 72 | { 73 | int indicator; 74 | 75 | /* Expect no compile time error */ 76 | strcat_s(th_dst, STATIC_BUF_SIZE - 1, th_src); 77 | } 78 | 79 | void 80 | test_strcat_s_dst_size_NO_compile_error (void) 81 | { 82 | int indicator; 83 | 84 | /* Expect no compile time error */ 85 | strcat_s(th_dst, STATIC_BUF_SIZE, th_src); 86 | } 87 | 88 | void 89 | test_strcat_s_dst_size_plus_1_compile_error (void) 90 | { 91 | int indicator; 92 | 93 | /* Expect no compile time error */ 94 | strcat_s(th_dst, STATIC_BUF_SIZE + 1, th_src); 95 | } 96 | 97 | /* For strcmp_s () */ 98 | void 99 | test_strcmp_s_dst_size_minus_1_NO_compile_error (void) 100 | { 101 | int indicator; 102 | 103 | /* Expect no compile time error */ 104 | strcmp_s(th_dst, STATIC_BUF_SIZE - 1, th_src, &indicator); 105 | } 106 | 107 | void 108 | test_strcmp_s_dst_size_NO_compile_error (void) 109 | { 110 | int indicator; 111 | 112 | /* Expect no compile time error */ 113 | strcmp_s(th_dst, STATIC_BUF_SIZE, th_src, &indicator); 114 | } 115 | 116 | void 117 | test_strcmp_s_dst_size_plus_1_compile_error (void) 118 | { 119 | int indicator; 120 | 121 | /* Expect no compile time error */ 122 | strcmp_s(th_dst, STATIC_BUF_SIZE + 1, th_src, &indicator); 123 | } 124 | 125 | /* For strcpy_s () */ 126 | void 127 | test_strcpy_s_dst_size_minus_1_NO_compile_error (void) 128 | { 129 | 130 | /* Expect no compile time error */ 131 | strcpy_s(th_dst, STATIC_BUF_SIZE - 1, th_src); 132 | } 133 | 134 | void 135 | test_strcpy_s_dst_size_NO_compile_error (void) 136 | { 137 | 138 | /* Expect no compile time error */ 139 | strcpy_s(th_dst, STATIC_BUF_SIZE, th_src); 140 | } 141 | 142 | void 143 | test_strcpy_s_dst_size_plus_1_compile_error (void) 144 | { 145 | 146 | /* Expect no compile time error */ 147 | strcpy_s(th_dst, STATIC_BUF_SIZE + 1, th_src); 148 | } 149 | 150 | /* For strncat_s () */ 151 | void 152 | test_strncat_s_dst_size_minus_1_NO_compile_error (void) 153 | { 154 | 155 | /* Expect no compile time error */ 156 | strncat_s(th_dst, STATIC_BUF_SIZE - 1, th_src, STATIC_BUF_SIZE); 157 | } 158 | 159 | void 160 | test_strncat_s_dst_size_NO_compile_error (void) 161 | { 162 | 163 | /* Expect no compile time error */ 164 | strncat_s(th_dst, STATIC_BUF_SIZE, th_src, STATIC_BUF_SIZE); 165 | } 166 | 167 | void 168 | test_strncat_s_dst_size_plus_1_compile_error (void) 169 | { 170 | 171 | /* Expect compile time error */ 172 | strncat_s(th_dst, STATIC_BUF_SIZE + 1, th_src, STATIC_BUF_SIZE); 173 | } 174 | 175 | void 176 | test_strncat_s_slen_plus_1_compile_error (void) 177 | { 178 | 179 | /* Expect compile time error */ 180 | strncat_s(th_dst, STATIC_BUF_SIZE , th_src, STATIC_BUF_SIZE + 1); 181 | } 182 | 183 | /* For strncpy () */ 184 | void 185 | test_strncpy_s_dst_size_minus_1_NO_compile_error (void) 186 | { 187 | 188 | /* Expect no compile time error */ 189 | strncpy_s(th_dst, STATIC_BUF_SIZE - 1, th_src, STATIC_BUF_SIZE - 2); 190 | } 191 | 192 | void 193 | test_strncpy_s_slen_same_as_dest_bufsize_compile_error (void) 194 | { 195 | 196 | /* Expect compile time error to the below cases */ 197 | // strncpy_s(th_dst, STATIC_BUF_SIZE, th_src, STATIC_BUF_SIZE); 198 | strncpy_s(th_dst, STATIC_BUF_SIZE - 1, th_src, STATIC_BUF_SIZE); 199 | } 200 | 201 | void 202 | test_strncpy_s_dst_size_NO_compile_error (void) 203 | { 204 | 205 | /* Expect no compile time error */ 206 | strncpy_s(th_dst, STATIC_BUF_SIZE, th_src, STATIC_BUF_SIZE - 1); 207 | } 208 | 209 | void 210 | test_strncpy_s_dst_size_plus_1_compile_error (void) 211 | { 212 | 213 | /* Expect compile time error */ 214 | strncpy_s(th_dst, STATIC_BUF_SIZE + 1, th_src, STATIC_BUF_SIZE - 1); 215 | } 216 | 217 | 218 | /* For strnlen_s () */ 219 | void 220 | test_strnlen_s_src_size_minus_1_NO_compile_error (void) 221 | { 222 | /* Expect compile time error */ 223 | strnlen_s(th_src, STATIC_BUF_SIZE - 1); 224 | } 225 | 226 | void 227 | test_strnlen_s_src_size_NO_compile_error (void) 228 | { 229 | /* Expect compile time error */ 230 | strnlen_s(th_src, STATIC_BUF_SIZE); 231 | } 232 | 233 | void 234 | test_strnlen_s_src_size_plus_1_compile_error (void) 235 | { 236 | 237 | /* Expect compile time error */ 238 | strnlen_s(th_src, STATIC_BUF_SIZE + 1); 239 | } 240 | 241 | /* For strstr_s () */ 242 | void 243 | test_strstr_s_dst_size_minus_1_NO_compile_error (void) 244 | { 245 | char *substr; 246 | 247 | /* Expect no compile time error */ 248 | strstr_s(th_dst, STATIC_BUF_SIZE - 1, th_src, STATIC_BUF_SIZE, &substr); 249 | } 250 | 251 | void 252 | test_strstr_s_dst_size_NO_compile_error (void) 253 | { 254 | char *substr = NULL; 255 | 256 | /* Expect no compile time error */ 257 | strstr_s(th_dst, STATIC_BUF_SIZE, th_src, STATIC_BUF_SIZE, &substr); 258 | } 259 | 260 | void 261 | test_strstr_s_dst_size_plus_1_compile_error (void) 262 | { 263 | char *substr = NULL; 264 | 265 | /* Expect compile time error */ 266 | strstr_s(th_dst, STATIC_BUF_SIZE + 1, th_src, STATIC_BUF_SIZE, &substr); 267 | } 268 | -------------------------------------------------------------------------------- /include/openosc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | 11 | #ifndef __OPENOSC_H__ 12 | #define __OPENOSC_H__ 13 | 14 | #include "openosc_header_metric.h" 15 | 16 | /* define the object size checking type in builtin function */ 17 | #define OSC_OBJECT_SIZE_CHECK_0 0 18 | #define OSC_OBJECT_SIZE_CHECK_1 1 19 | 20 | #ifndef NULL 21 | #define NULL ((void *)0) 22 | #endif 23 | 24 | /* Source over-read is enabled by default, but can be disabled */ 25 | #ifndef OPENOSC_SRC_OVERREAD_DISABLE 26 | #define _OPENOSC_SRC_OVERREAD_ENABLED 27 | #endif 28 | 29 | /* 30 | * There are two methods to remap a function to openosc_* function: 31 | * 1. The function redirect via ASM-label mechanism. 32 | * 2. The function macro redefine method. 33 | * The ASM-label redirect method is the default. 34 | * New mapping method can be added in future as necessary. 35 | */ 36 | #define OPENOSC_ASM_LABEL_REDIRECT_METHOD 1 37 | #define OPENOSC_FUNC_MACRO_REDEFINE_METHOD 2 38 | 39 | /* -DOPENOSC_MM=x can be used by a component to pick the mapping method */ 40 | /* #define OPENOSC_MM OPENOSC_FUNC_MACRO_REDEFINE_METHOD */ 41 | #ifdef OPENOSC_MM 42 | #define OPENOSC_MAPPING_METHOD OPENOSC_MM 43 | #else 44 | #define OPENOSC_MAPPING_METHOD OPENOSC_ASM_LABEL_REDIRECT_METHOD 45 | #endif 46 | 47 | /** 48 | * If the below flag is defined, then all function remapping code will be disabled. 49 | * However, file-level magic words in openosc_header_metric.h and openosc_nomap_metric.h are kept. 50 | */ 51 | #ifdef OPENOSC_FUNCTION_MAPPING_DISABLE 52 | #undef OPENOSC_METRIC_FEATURE_ENABLED 53 | #define NO_OBJECT_SIZE_CHECKING 54 | #endif 55 | 56 | #ifdef OPENOSC_SKIP_CSTRING_HEADER 57 | #ifdef __cplusplus 58 | #if OPENOSC_MAPPING_METHOD == OPENOSC_FUNC_MACRO_REDEFINE_METHOD || defined OPENOSC_METRIC_ONLY_MODE 59 | /* define the below macro to avoid including header, which #undef >10 memcpy/strcpy functions */ 60 | #ifndef _GLIBCXX_CSTRING 61 | #define _GLIBCXX_CSTRING 2 62 | #endif 63 | #endif 64 | #endif 65 | #endif 66 | 67 | 68 | #ifdef NO_OBJECT_SIZE_CHECKING 69 | #pragma message ("OSC-WARN-DISABLED: OpenOSC disabled due to NO_OBJECT_SIZE_CHECKING, contact OpenOSC package owner for guidance") 70 | #elif defined __ASSEMBLER__ 71 | #pragma message ("OSC-WARN-ASM: OpenOSC disabled due to __ASSEMBLER__, contact OpenOSC package owner for guidance") 72 | #elif defined OPENOSC_METRIC_ONLY_MODE 73 | #pragma message ("OSC-WARN-METRICONLY: OpenOSC disabled due to METRIC_ONLY_MODE, contact OpenOSC package owner for guidance") 74 | #include "openosc_metric_only.h" 75 | #elif !defined __OPTIMIZE__ 76 | /* #error "OSC-ERR-NOOPT: OpenOSC disabled due to NO OPTIMIZATION, contact OpenOSC package owner for guidance" */ 77 | #pragma message ("OSC-ERR-NOOPT: OpenOSC disabled due to NO OPTIMIZATION, contact OpenOSC package owner for guidance") 78 | #include "openosc_nomap.h" 79 | #elif defined __NO_INLINE__ 80 | #pragma message ("OSC-WARN-NOINLINE: OpenOSC disabled due to __NO_INLINE__, contact OpenOSC package owner for guidance") 81 | #include "openosc_nomap.h" 82 | #elif defined _FORTIFY_SOURCE && !defined OPENOSC_FORTIFY_SOURCE_FORCE_OFF 83 | #pragma message ("OSC-WARN-FORTIFY: OpenOSC disabled due to _FORTIFY_SOURCE, contact OpenOSC package owner for guidance") 84 | #include "openosc_nomap.h" 85 | #elif defined OSC_ASM 86 | #pragma message ("OSC-WARN-ASM: OpenOSC disabled due to OSC_ASM, contact OpenOSC package owner for guidance") 87 | #include "openosc_nomap.h" 88 | #elif defined __STRICT_ANSI__ && !defined OPENOSC_STRICT_ANSI_FORCE_ON 89 | #pragma message ("OSC-WARN-ANSI: OpenOSC disabled due to __STRICT_ANSI__, contact OpenOSC package owner for guidance") 90 | #include "openosc_nomap.h" 91 | #else 92 | 93 | #if defined _FORTIFY_SOURCE && defined OPENOSC_FORTIFY_SOURCE_FORCE_OFF 94 | #undef _FORTIFY_SOURCE 95 | #ifndef _OPENOSC_FORCEENABLE_EMIT_WARNING_DISABLE 96 | #pragma message ("OSC-WARN-FORTIFY: OpenOSC is forced to be enabled and _FORTIFY_SOURCE is disabled when _FORTIFY_SOURCE is defined, contact OpenOSC package owner for guidance") 97 | #endif 98 | #endif 99 | 100 | #if defined __STRICT_ANSI__ && defined OPENOSC_STRICT_ANSI_FORCE_ON 101 | #ifndef _OPENOSC_FORCEENABLE_EMIT_WARNING_DISABLE 102 | #pragma message ("OSC-WARN-ANSI: OpenOSC is forced to be enabled when __STRICT_ANSI__ is defined, contact OpenOSC package owner for guidance") 103 | #endif 104 | #endif 105 | 106 | /* This define shows OSC enabled */ 107 | #define OSC_OBJECT_SIZE_CHECK 1 108 | 109 | /* 110 | * Flags to select compile-time check method 111 | * 112 | * Different compilers support different way to report error at compiling time. 113 | * OSC_ASSERT_USE_ERR_ATTR: 114 | * Use __attribute__ error to report error 115 | * OSC_ASSERT_USE_BUILTIN: 116 | * Use __builtin___xxx_chk to report error. This method MUST not be used in 117 | * final production code as it introduce abort() call into the code. It can 118 | * be used for the initial finding of static buffer overflow if the compiler 119 | * doesn't support OSC_ASSERT_USE_ERR_ATTR 120 | * OSC_ASSERT_USE_RUNTIME_CHK: 121 | * Use runtime check for buffer overflow only. This method will NOT catch 122 | * any static buffer overflow at compile time. 123 | * OSC_ASSERT_USE_NONE: 124 | * Use the original libc/safec functions. This method will NOT catch 125 | * any static buffer overflow at compile time. 126 | */ 127 | #define OSC_ASSERT_USE_ERR_ATTR 0 128 | #define OSC_ASSERT_USE_BUILTIN 1 /* DO NOT use in production */ 129 | #define OSC_ASSERT_USE_RUNTIME_CHK 2 130 | #define OSC_ASSERT_USE_NONE 3 /* DO NOT use in production */ 131 | 132 | /* 133 | * Flags to select run-time check method 134 | */ 135 | #define OSC_RUNTIME_USE_LIBOSC 0 /* Default Runtime check */ 136 | #define OSC_RUNTIME_NO_LIBOSC 1 /* Use libc/safec when libosc is unavailable */ 137 | 138 | /********************************************************************************** 139 | ********************************************************************************** 140 | * DO NOT CHANGE OSC_COMPILE_CHK OR OSC_RUNTIME_CHK flags 141 | * Please contact csdl-rtd-dev@cisco.com for any questions regarding these settings 142 | **********************************************************************************/ 143 | /* 144 | * OPENOSC_METRIC_ONLY_MODE is a special mode which disables OSC remapping. 145 | */ 146 | #ifdef OPENOSC_METRIC_ONLY_MODE 147 | 148 | #define OSC_COMPILE_CHK OSC_ASSERT_USE_NONE 149 | #define OSC_RUNTIME_CHK OSC_RUNTIME_NO_LIBOSC 150 | 151 | #else 152 | 153 | /* 154 | * Detect the compiler and select the best compile-time check method. 155 | */ 156 | #if defined __ICC 157 | #define OSC_COMPILE_CHK OSC_ASSERT_USE_RUNTIME_CHK 158 | #elif defined __clang__ 159 | #define OSC_COMPILE_CHK OSC_ASSERT_USE_ERR_ATTR 160 | #elif defined __GNUC__ 161 | #define OSC_COMPILE_CHK OSC_ASSERT_USE_ERR_ATTR 162 | #else 163 | #error "Unsupported compiler detected, contact OpenOSC package owner for guidance" 164 | #endif 165 | 166 | /* 167 | * Runtime check should always be using libosc 168 | */ 169 | #define OSC_RUNTIME_CHK OSC_RUNTIME_USE_LIBOSC 170 | 171 | #endif /* OPENOSC_METRIC_ONLY_MODE */ 172 | 173 | /********************************************************************************** 174 | * DO NOT CHANGE OSC_COMPILE_CHK OR OSC_RUNTIME_CHK flags 175 | * Please contact csdl-rtd-dev@cisco.com for any questions regarding these settings 176 | ********************************************************************************** 177 | **********************************************************************************/ 178 | 179 | #include "openosc_map.h" 180 | 181 | #ifdef HAS_SAFEC 182 | #include "openosc_safec_map.h" 183 | #endif 184 | 185 | #endif /* NO_OBJECT_SIZE_CHECKING */ 186 | 187 | /* 188 | * Let's pretend that we never include features.h header 189 | * so that users can still define their features by themselves. 190 | */ 191 | #undef _FEATURES_H 192 | 193 | #endif /* __OPEOSC_H__ */ 194 | -------------------------------------------------------------------------------- /include/openosc_fortify_extern.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_FORTIFY_EXTERN_H__ 11 | #define __OPENOSC_FORTIFY_EXTERN_H__ 12 | 13 | /* for __WORDSIZE */ 14 | #include 15 | 16 | /* Define va_list */ 17 | #ifndef _VA_LIST 18 | #define _VA_LIST 19 | typedef __builtin_va_list va_list; 20 | #endif 21 | 22 | #ifndef OSC_THROW 23 | #ifdef __cplusplus 24 | #define OSC_THROW __THROW 25 | #else 26 | #define OSC_THROW 27 | #endif 28 | #endif 29 | 30 | 31 | /* The below data type forward declarations are required */ 32 | #if __WORDSIZE == 32 33 | typedef int __ssize_t; 34 | #else 35 | typedef long int __ssize_t; 36 | #endif 37 | typedef __ssize_t ssize_t; 38 | typedef unsigned int __socklen_t; 39 | typedef unsigned int __gid_t; 40 | typedef __socklen_t socklen_t; 41 | typedef __gid_t gid_t; 42 | struct _IO_FILE; 43 | typedef struct _IO_FILE FILE; 44 | typedef unsigned long int nfds_t; 45 | struct pollfd; 46 | struct timespec; 47 | struct sockaddr; 48 | /* import size_t and wchar_t definition only */ 49 | #define __need_size_t 50 | #define __need_wchar_t 51 | #include 52 | 53 | /* 54 | * Anonymous struct like __sigset_t or __mbstate_t cannot be forward-declared. 55 | * OpenOSC is forced to define the exact same struct as the system header, and 56 | * define the *_defined flag to prevent later redefinition in system header. 57 | * The below _openosc_* type must be the exact same definition as what is 58 | * in openosc_fortify_map.c file, where static assertion is checked. 59 | */ 60 | 61 | #ifndef ____sigset_t_defined 62 | #define ____sigset_t_defined 63 | 64 | #ifndef _SIGSET_H_types 65 | # define _SIGSET_H_types 1 66 | #endif 67 | 68 | typedef int __sig_atomic_t; 69 | 70 | /* A `sigset_t' has a bit for each signal. */ 71 | 72 | # define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) 73 | typedef struct 74 | { 75 | unsigned long int __val[_SIGSET_NWORDS]; 76 | } __sigset_t; 77 | 78 | #endif 79 | 80 | #ifndef __sigset_t_defined 81 | #define __sigset_t_defined 82 | typedef __sigset_t sigset_t; 83 | #endif 84 | 85 | #ifndef ____mbstate_t_defined 86 | #define ____mbstate_t_defined 1 87 | 88 | /* Integral type unchanged by default argument promotions that can 89 | hold any value corresponding to members of the extended character 90 | set, as well as at least one value that does not correspond to any 91 | member of the extended character set. */ 92 | #ifndef __WINT_TYPE__ 93 | # define __WINT_TYPE__ unsigned int 94 | #endif 95 | 96 | /* Conversion state information. */ 97 | typedef struct 98 | { 99 | int __count; 100 | union 101 | { 102 | __WINT_TYPE__ __wch; 103 | char __wchb[4]; 104 | } __value; /* Value so far. */ 105 | } __mbstate_t; 106 | 107 | #endif 108 | 109 | #ifndef __mbstate_t_defined 110 | #define __mbstate_t_defined 1 111 | typedef __mbstate_t mbstate_t; 112 | #endif 113 | 114 | /* Need to disable vprintf because it is defined as a macro in stdio.h */ 115 | #define OPENOSC_VPRINTF_DISABLE 116 | 117 | extern size_t confstr(int name, char *buf, size_t len) __THROW ; 118 | extern char *fgets(char *s, int size, FILE *stream); 119 | extern char *fgets_unlocked(char *s, int n, FILE *stream); 120 | extern wchar_t *fgetws(wchar_t *ws, int n, FILE *stream); 121 | extern wchar_t *fgetws_unlocked(wchar_t *ws, int n, FILE *stream); 122 | extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 123 | #ifndef fread_unlocked 124 | extern size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *stream); 125 | #endif 126 | #ifndef OPENOSC_GETCWD_DISABLE 127 | extern char *getcwd(char *buf, size_t size) __THROW ; 128 | #endif 129 | extern int getdomainname(char *name, size_t len) __THROW ; 130 | extern int getgroups(int size, gid_t list[]) __THROW ; 131 | extern int gethostname(char *name, size_t len) __THROW ; 132 | extern char *gets(char *s); 133 | extern char *getwd(char *buf) __THROW ; 134 | extern size_t mbsnrtowcs(wchar_t *dest, const char **src, size_t nms, size_t len, mbstate_t *ps) __THROW ; 135 | extern size_t mbsrtowcs(wchar_t *dest, const char **src, size_t len, mbstate_t *ps) __THROW ; 136 | extern size_t mbstowcs(wchar_t *dest, const char *src, size_t n) __THROW ; 137 | extern void *mempcpy(void *dest, const void *src, size_t n) __THROW ; 138 | #ifndef OPENOSC_POLL_DISABLE 139 | extern int poll(struct pollfd *fds, nfds_t nfds, int timeout) ; 140 | #endif 141 | #ifndef OPENOSC_PPOLL_DISABLE 142 | extern int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask) ; 143 | #endif 144 | #ifndef OPENOSC_PREAD_DISABLE 145 | typedef long int __off_t; 146 | typedef __off_t off_t; 147 | extern ssize_t pread(int fd, void *buf, size_t count, off_t offset) ; 148 | #endif 149 | #ifndef OPENOSC_READ_DISABLE 150 | extern ssize_t read(int fd, void *buf, size_t count) ; 151 | #endif 152 | extern ssize_t readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) __THROW ; 153 | extern ssize_t readlink(const char *path, char *buf, size_t bufsiz) __THROW ; 154 | extern char *realpath(const char *path, char *resolved_path) __THROW ; 155 | #ifndef OPENOSC_RECV_DISABLE 156 | extern ssize_t recv(int sockfd, void *buf, size_t len, int flags) ; 157 | #endif 158 | #ifndef OPENOSC_RECVFROM_DISABLE 159 | extern ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) ; 160 | #endif 161 | extern char *stpcpy(char *dest, const char *src) __THROW ; 162 | extern char *stpncpy(char *dest, const char *src, size_t n) __THROW ; 163 | extern int ttyname_r(int fd, char *buf, size_t buflen) __THROW ; 164 | extern int vasprintf(char **strp, const char *fmt, va_list ap) __THROWNL; 165 | extern int vdprintf(int fd, const char *format, va_list ap); 166 | extern int vfprintf(FILE *stream, const char *format, va_list ap); 167 | extern int vfwprintf(FILE *stream, const wchar_t *format, va_list args); 168 | #ifndef OPENOSC_VPRINTF_DISABLE 169 | extern int vprintf(const char *format, va_list ap); 170 | #endif 171 | extern int vsprintf(char *str, const char *format, va_list ap) __THROWNL; 172 | extern int vswprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args) __THROW ; 173 | extern int vwprintf(const wchar_t *format, va_list args); 174 | extern wchar_t *wcpcpy(wchar_t *dest, const wchar_t *src) __THROW ; 175 | extern wchar_t *wcpncpy(wchar_t *dest, const wchar_t *src, size_t n) __THROW ; 176 | extern size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps) __THROW ; 177 | extern wchar_t *wcscat(wchar_t *dest, const wchar_t *src) __THROW ; 178 | extern wchar_t *wcscpy(wchar_t *dest, const wchar_t *src) __THROW ; 179 | extern wchar_t *wcsncat(wchar_t *dest, const wchar_t *src, size_t n) __THROW ; 180 | extern wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t n) __THROW ; 181 | extern size_t wcsnrtombs(char *dest, const wchar_t **src, size_t nwc, size_t len, mbstate_t *ps) __THROW ; 182 | extern size_t wcsrtombs(char *dest, const wchar_t **src, size_t len, mbstate_t *ps) __THROW ; 183 | extern size_t wcstombs(char *dest, const wchar_t *src, size_t n) __THROW ; 184 | extern int wctomb(char *s, wchar_t wc) __THROW ; 185 | extern wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t n) __THROW ; 186 | extern wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t n) __THROW ; 187 | extern wchar_t *wmempcpy(wchar_t *dest, const wchar_t *src, size_t n) __THROW ; 188 | extern wchar_t *wmemset(wchar_t *wcs, wchar_t wc, size_t n) __THROW ; 189 | 190 | #ifndef OPENOSC_ASPRINTF_DISABLE 191 | extern int asprintf(char **strp, const char *fmt, ...) __THROWNL ; 192 | #endif 193 | extern int dprintf(int fd, const char *format, ...); 194 | extern int fprintf(FILE *stream, const char *format, ...); 195 | extern int fwprintf(FILE *stream, const wchar_t *format, ...); 196 | extern int printf(const char *format, ...); 197 | extern int snprintf(char *str, size_t size, const char *format, ...) __THROWNL; 198 | extern int sprintf(char *str, const char *format, ...) __THROWNL ; 199 | extern int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...) __THROW ; 200 | extern int wprintf(const wchar_t *format, ...); 201 | 202 | 203 | #endif /* __OPENOSC_FORTIFY_EXTERN_H__ */ 204 | -------------------------------------------------------------------------------- /src/openosc_safec_map.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #include 11 | #include "config.h" 12 | #ifdef HAVE_SAFEC_SAFE_LIB_H 13 | #include 14 | #else 15 | #include 16 | #endif 17 | #include "openosc_common.h" 18 | 19 | extern size_t strlen (__const char *__s); 20 | 21 | /* Mapping for memcmp_s */ 22 | 23 | errno_t 24 | __openosc_memcmp_s_to_buf (size_t s1_len, 25 | const void *s1, rsize_t s1max, 26 | const void *s2, rsize_t n, int *diff) 27 | { 28 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 29 | 30 | if (s1max > s1_len) { 31 | if (openosc_log) { 32 | openosc_danger_error("memcmp_s s1max", s1_len, s1max); 33 | } 34 | openosc_get_config(&openosc_abort); 35 | if (openosc_abort) { 36 | abort(); 37 | } 38 | if (openosc_truncate) { 39 | s1max = s1_len; 40 | } 41 | } 42 | if (n > s1_len) { 43 | if (openosc_log) { 44 | openosc_danger_error("memcmp_s n", s1_len, n); 45 | } 46 | openosc_get_config(&openosc_abort); 47 | if (openosc_abort) { 48 | abort(); 49 | } 50 | if (openosc_truncate) { 51 | n = s1_len; 52 | } 53 | } 54 | #undef memcmp_s 55 | return (memcmp_s(s1, s1max, s2, n, diff)); 56 | } 57 | 58 | /* Mapping for memcpy_s */ 59 | 60 | errno_t 61 | __openosc_memcpy_s_to_buf (size_t dest_len, 62 | void *dest, rsize_t dmax, const void *src, rsize_t n) 63 | { 64 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 65 | 66 | if (dmax > dest_len) { 67 | if (openosc_log) { 68 | openosc_danger_error("memcpy_s dmax", dest_len, dmax); 69 | } 70 | openosc_get_config(&openosc_abort); 71 | if (openosc_abort) { 72 | abort(); 73 | } 74 | if (openosc_truncate) { 75 | dmax = dest_len; 76 | } 77 | } 78 | if (n > dest_len) { 79 | if (openosc_log) { 80 | openosc_danger_error("memcpy_s n", dest_len, dmax); 81 | } 82 | openosc_get_config(&openosc_abort); 83 | if (openosc_abort) { 84 | abort(); 85 | } 86 | if (openosc_truncate) { 87 | n = dest_len; 88 | } 89 | } 90 | #undef memcpy_s 91 | return (memcpy_s(dest, dmax, src, n)); 92 | } 93 | 94 | /* Mapping for strcat_s */ 95 | 96 | errno_t 97 | __openosc_strcat_s_to_buf (size_t dest_len, 98 | char *dest, rsize_t dmax, const char *src) 99 | { 100 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 101 | size_t len = strlen(src); 102 | size_t dest_len_to_null = strlen(dest); 103 | 104 | if (dmax > dest_len) { 105 | if (openosc_log) { 106 | openosc_danger_error("strcat_s dest", dest_len, dmax); 107 | } 108 | openosc_get_config(&openosc_abort); 109 | if (openosc_abort) { 110 | abort(); 111 | } 112 | if (openosc_truncate) { 113 | dmax = dest_len; 114 | } 115 | } 116 | if (dest_len < (len + dest_len_to_null + 1)) { 117 | if (openosc_log) { 118 | openosc_danger_error("strcat_s", dest_len, (len + dest_len_to_null + 1)); 119 | } 120 | openosc_get_config(&openosc_abort); 121 | if (openosc_abort) { 122 | abort(); 123 | } 124 | if (openosc_truncate) { 125 | dmax = dest_len; 126 | } 127 | } 128 | #undef strcat_s 129 | return (strcat_s(dest, dmax, src)); 130 | } 131 | 132 | /* Mapping for strcmp_s */ 133 | 134 | errno_t 135 | __openosc_strcmp_s_to_buf (size_t s1_len, 136 | const char *s1, rsize_t s1max, 137 | const char *s2, int *indicator) 138 | { 139 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 140 | 141 | if (s1max > s1_len) { 142 | if (openosc_log) { 143 | openosc_danger_error("strcmp_s", s1_len, s1max); 144 | } 145 | openosc_get_config(&openosc_abort); 146 | if (openosc_abort) { 147 | abort(); 148 | } 149 | if (openosc_truncate) { 150 | s1max = s1_len; 151 | } 152 | } 153 | /* 154 | * may add later for checking 155 | * if (dmax > src buffer size) causes src reading overflow 156 | */ 157 | #undef strcmp_s 158 | return (strcmp_s(s1, s1max, s2, indicator)); 159 | } 160 | 161 | /* Mapping for strcpy_s */ 162 | 163 | errno_t 164 | __openosc_strcpy_s_to_buf (size_t dest_len, 165 | char *dest, rsize_t dmax, const char *src) 166 | { 167 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 168 | 169 | if (dmax > dest_len) { 170 | if (openosc_log) { 171 | openosc_danger_error("strcpy_s", dest_len, dmax); 172 | } 173 | openosc_get_config(&openosc_abort); 174 | if (openosc_abort) { 175 | abort(); 176 | } 177 | if (openosc_truncate) { 178 | dmax = dest_len; 179 | } 180 | } 181 | #undef strcpy_s 182 | return (strcpy_s(dest, dmax, src)); 183 | } 184 | 185 | /* Mapping for strncat_s */ 186 | 187 | errno_t 188 | __openosc_strncat_s_to_buf (size_t dest_len, 189 | char *dest, rsize_t dmax, const char *src, rsize_t n) 190 | { 191 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 192 | size_t dest_len_to_null = strlen(dest); 193 | if (dmax > dest_len) { 194 | if (openosc_log) { 195 | openosc_danger_error("strncat_s dest", dest_len, dmax); 196 | } 197 | openosc_get_config(&openosc_abort); 198 | if (openosc_abort) { 199 | abort(); 200 | } 201 | if (openosc_truncate) { 202 | dmax = dest_len; 203 | } 204 | } 205 | if ((dest_len_to_null + n + 1) > dest_len) { 206 | if (openosc_log) { 207 | openosc_danger_error("strncat_s src", dest_len, (dest_len_to_null + n + 1)); 208 | } 209 | openosc_get_config(&openosc_abort); 210 | if (openosc_abort) { 211 | abort(); 212 | } 213 | if (openosc_truncate) { 214 | n = dest_len - dest_len_to_null - 1; 215 | } 216 | } 217 | #undef strncat_s 218 | return (strncat_s(dest, dmax, src, n)); 219 | } 220 | 221 | /* Mapping for strncpy_s */ 222 | 223 | errno_t 224 | __openosc_strncpy_s_to_buf (size_t dest_len, 225 | char *dest, rsize_t dmax, const char *src, rsize_t slen) 226 | { 227 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 228 | 229 | if (dmax > dest_len) { 230 | if (openosc_log) { 231 | openosc_danger_error("strncpy_s dest", dest_len, dmax); 232 | } 233 | openosc_get_config(&openosc_abort); 234 | if (openosc_abort) { 235 | abort(); 236 | } 237 | if (openosc_truncate) { 238 | dmax = dest_len; 239 | } 240 | } 241 | if (slen > dest_len) { 242 | if (openosc_log) { 243 | openosc_danger_error("strncpy_s src", dest_len, slen); 244 | } 245 | openosc_get_config(&openosc_abort); 246 | if (openosc_abort) { 247 | abort(); 248 | } 249 | if (openosc_truncate) { 250 | slen = dest_len; 251 | } 252 | } 253 | #undef strncpy_s 254 | return (strncpy_s(dest, dmax, src, slen)); 255 | } 256 | 257 | /* Mapping for strnlen_s */ 258 | 259 | size_t 260 | __openosc_strnlen_s_to_buf (size_t s_len, 261 | const char *s, size_t maxsize) 262 | { 263 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 264 | 265 | if (maxsize > s_len) { 266 | if (openosc_log) { 267 | openosc_danger_error("strnlen_s", s_len, maxsize); 268 | } 269 | openosc_get_config(&openosc_abort); 270 | if (openosc_abort) { 271 | abort(); 272 | } 273 | if (openosc_truncate) { 274 | maxsize = s_len; 275 | } 276 | } 277 | #undef strnlen_s 278 | return (strnlen_s(s, maxsize)); 279 | } 280 | 281 | /* Mapping for strstr_s */ 282 | 283 | errno_t 284 | __openosc_strstr_s_to_buf (size_t s1_len, 285 | char *s1, rsize_t s1max, 286 | const char *s2, rsize_t s2max, char **substring) 287 | { 288 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 289 | 290 | if (s1max > s1_len) { 291 | if (openosc_log) { 292 | openosc_danger_error("strstr_s", s1_len, s1max); 293 | } 294 | openosc_get_config(&openosc_abort); 295 | if (openosc_abort) { 296 | abort(); 297 | } 298 | if (openosc_truncate) { 299 | s1max = s1_len; 300 | } 301 | } 302 | #undef strstr_s 303 | return (strstr_s(s1, s1max, s2, s2max, substring)); 304 | } 305 | -------------------------------------------------------------------------------- /src/openosc_support.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | /* 11 | * Needed early so that we can get Dl_info. 12 | */ 13 | #ifndef _GNU_SOURCE 14 | #define _GNU_SOURCE 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "openosc_support_priv.h" 28 | #include "openosc_common.h" 29 | 30 | #define OPENOSC_PACKAGE_STR openosc_get_package_string() 31 | #define OPENOSC_VERSION openosc_get_package_version() 32 | 33 | #ifdef OSC_FINAL 34 | /* 35 | * openosc_get_process_name 36 | * 37 | * Get the process name 38 | * name: buffer to hold the process name 39 | * name_len: maximum number of characters the name buffer can hold 40 | * 41 | * Return Value 42 | * TRUE on success 43 | * FALSE on failure and content of name is unknown 44 | */ 45 | static int 46 | openosc_get_process_name(char *name, int name_len) 47 | { 48 | char path[OSC_PROC_PATH_MAX]; 49 | FILE* fd; 50 | 51 | if (!name) 52 | return FALSE; 53 | 54 | snprintf(path, OSC_PROC_PATH_MAX, "/proc/%d/cmdline", getpid()); 55 | fd = fopen(path, "r"); 56 | if (fd != NULL) { 57 | size_t size = fread((void *)name, sizeof(char), name_len, fd); 58 | if (size > 0) { 59 | name[size-1]='\0'; 60 | } 61 | fclose(fd); 62 | return TRUE; 63 | } 64 | return FALSE; 65 | } 66 | 67 | /* 68 | * openosc_bt2str_offset 69 | * 70 | * ### This implementation is for RELEASE image only ### 71 | * 72 | * Convert array of backtrace addresses to a string of 73 | * library name + offset from base address. 74 | * bt: array of addresses 75 | * frames: number of addresses in bt 76 | * bt_str: pointer to the memory to write the backtrace string to 77 | * bt_str_max: max bytes in bt_str 78 | * 79 | * Return Value 80 | * TRUE on success 81 | * FALSE on failure and content of bt_str is unknown 82 | */ 83 | static int 84 | openosc_bt2str_offset (void *bt[], int frames, char *bt_str, 85 | unsigned int bt_str_max) 86 | { 87 | Dl_info info; 88 | char *bname; 89 | int f; 90 | unsigned int s; 91 | char process_name[OSC_BT_STR_MAX]; 92 | 93 | /* 94 | * Need a minimum of 2 bytes in case we don't have enough room, 95 | * we can write "*" and NULL character to indicate the backtrace 96 | * string was truncated 97 | */ 98 | if ((!bt_str) || (bt_str_max < 2)) 99 | return FALSE; 100 | 101 | /* Get process name */ 102 | if (FALSE == openosc_get_process_name(bt_str, bt_str_max)) { 103 | return FALSE; 104 | } 105 | 106 | strncpy(process_name, bt_str, OSC_BT_STR_MAX - 1); 107 | process_name[OSC_BT_STR_MAX - 1] = '\0'; 108 | 109 | /* Add a space after process name */ 110 | if (strlen(bt_str) < (bt_str_max - 1)) 111 | strcat(bt_str, " "); 112 | 113 | s = strlen(bt_str); 114 | 115 | for(f = 0; f < frames; f++) { 116 | if (dladdr(bt[f], &info)) { 117 | /* 118 | * Make sure we have enough space 119 | */ 120 | if (s >= bt_str_max ) { 121 | bt_str[bt_str_max - 2] = '*'; 122 | bt_str[bt_str_max - 1] = '\0'; 123 | break; 124 | } 125 | if (strcmp(info.dli_fname, process_name) == 0) { 126 | /* 127 | * If the symbol is in us, just print the offset 128 | */ 129 | s += snprintf(&bt_str[s], (bt_str_max - s), "+%p ", 130 | (void *)((char *)bt[f] - (char *)info.dli_fbase)); 131 | } else { 132 | bname = basename(info.dli_fname); 133 | /* 134 | * Otherwise print library+offset 135 | */ 136 | s += snprintf(&bt_str[s], (bt_str_max - s), "%s+%p ", 137 | bname, (void *)((char *)bt[f] - (char *)info.dli_fbase)); 138 | } 139 | } 140 | } 141 | 142 | if (s >= bt_str_max) { 143 | bt_str[bt_str_max - 2] = '*'; 144 | bt_str[bt_str_max - 1] = '\0'; 145 | } 146 | 147 | return TRUE; 148 | } 149 | #else 150 | /* 151 | * openosc_bt2str_symbol 152 | * 153 | * ### This implementation is for NON-RELEASE image only ### 154 | * 155 | * Convert array of backtrace addresses to a string of 156 | * function names. 157 | * bt: array of addresses 158 | * frames: number of addresses in bt 159 | * bt_str: pointer to the memory to write the backtrace string to 160 | * bt_str_max: max bytes in bt_str 161 | * 162 | * Return Value 163 | * TRUE on success 164 | * FALSE on failure and content of bt_str is unknown 165 | */ 166 | static int 167 | openosc_bt2str_symbol (void *bt[], int frames, char *bt_str, 168 | unsigned int bt_str_max) 169 | { 170 | int i, buf_bytes, snp_bytes; 171 | char **name_arr = NULL; 172 | 173 | if ((!bt_str) || (!bt_str_max)) 174 | return FALSE; 175 | 176 | /* Convert array of backtrace addresses to function names */ 177 | name_arr = backtrace_symbols(bt, frames); 178 | if (NULL == name_arr) { 179 | return FALSE; 180 | } 181 | 182 | buf_bytes = 0; 183 | for (i = 0; i < frames; i++) { 184 | snp_bytes = snprintf(&bt_str[buf_bytes], bt_str_max - buf_bytes, 185 | " %s", name_arr[i]); 186 | /* 187 | * If not enough room and the output was truncated, removed 188 | * the last write and discard the rest of the backtrace 189 | */ 190 | if (buf_bytes + snp_bytes >= bt_str_max) { 191 | bt_str[buf_bytes] = '\0'; 192 | break; 193 | } 194 | buf_bytes += snp_bytes; 195 | } 196 | 197 | free(name_arr); 198 | 199 | return TRUE; 200 | } 201 | #endif /* OSC_FINAL */ 202 | 203 | /* 204 | * openosc_get_backtrace 205 | * 206 | * Description 207 | * Return a pointer to a NULL terminated backtrace string in backtrace_str. 208 | * The string should be freed by calling osc_free_backtrace() API. 209 | * 210 | * Return Value 211 | * 1 for success getting a backtrace 212 | * 0 for failure, backtrace_str set to NULL 213 | */ 214 | static int openosc_get_backtrace (char **backtrace_str) 215 | { 216 | void *bt[OSC_BT_FRAMES]; 217 | int frames, status; 218 | 219 | if (!backtrace_str) 220 | return FALSE; 221 | 222 | /* Allocate buffer to hold the backtrace string */ 223 | *backtrace_str = malloc(OSC_BT_STR_MAX); 224 | if (NULL == *backtrace_str) 225 | return FALSE; 226 | 227 | /* Get the backtrace */ 228 | frames = backtrace(bt, OSC_BT_FRAMES); 229 | if (frames <= OSC_FRAMES_TO_SKIP) { 230 | free(*backtrace_str); 231 | *backtrace_str = NULL; 232 | return FALSE; 233 | } 234 | 235 | /* 236 | * Convert backtrace frames to string 237 | * 238 | * Skip first OSC_FRAMES_TO_SKIP frames to get to the real function 239 | * that cause the overflow. Don't want to see this function and its 240 | * caller in every backtrace. 241 | */ 242 | status = OPENOSC_BT_TO_STR(&bt[OSC_FRAMES_TO_SKIP], 243 | frames - OSC_FRAMES_TO_SKIP, 244 | *backtrace_str, OSC_BT_STR_MAX); 245 | 246 | if (FALSE == status) { 247 | free(*backtrace_str); 248 | *backtrace_str = NULL; 249 | } 250 | 251 | return status; 252 | } 253 | 254 | /* 255 | * osc_free_backtrace 256 | * 257 | * Description 258 | * Free the backtrace string memory allocated by osc_get_backtrace() 259 | */ 260 | static void openosc_free_backtrace (char *backtrace_str) 261 | { 262 | if (backtrace_str) 263 | free(backtrace_str); 264 | } 265 | 266 | /* 267 | * openosc_danger_error 268 | * 269 | * Description 270 | * Output a data corruption, data inconsistency syslog message 271 | */ 272 | void openosc_danger_error (const char *func, size_t true_len, size_t len) 273 | { 274 | char *backtrace_str; 275 | 276 | /* Get backtrace string */ 277 | if (openosc_get_backtrace(&backtrace_str) != TRUE) { 278 | syslog(LOG_CRIT, "LIB-OPENOSC: Error getting backtrace\n"); 279 | return; 280 | } 281 | 282 | #ifdef OSC_FINAL 283 | syslog(LOG_CRIT, "DATACORRUPTION-DATAINCONSISTENCY: %s " 284 | "Copy error -Traceback= %s\n", OPENOSC_PACKAGE_STR, backtrace_str); 285 | #else 286 | syslog(LOG_CRIT, "DATACORRUPTION-DATAINCONSISTENCY: %s " 287 | "Attempt to %s %zu bytes should have been %zu bytes, -Traceback= %s\n", 288 | OPENOSC_PACKAGE_STR, func, len, true_len, backtrace_str); 289 | #endif 290 | 291 | /* Free the backtrace string */ 292 | openosc_free_backtrace(backtrace_str); 293 | } 294 | 295 | -------------------------------------------------------------------------------- /src/openosc_map.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #define _GNU_SOURCE 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "openosc_common.h" 16 | 17 | /* Mapping for memcpy */ 18 | 19 | void * 20 | __openosc_memcpy_to_buf(size_t dest_len, size_t src_len, void *dst, const void *src, size_t len) 21 | { 22 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 23 | 24 | if ((dest_len != (size_t) -1) && (dest_len != 0) && (len > dest_len)) { 25 | if (openosc_log) { 26 | openosc_danger_error("memcpy destination", dest_len, len); 27 | } 28 | openosc_get_config(&openosc_abort); 29 | if (openosc_abort) { 30 | abort(); 31 | } 32 | if (openosc_truncate) { 33 | len = dest_len; 34 | } 35 | } 36 | 37 | if ((src_len != (size_t) -1) && (src_len != 0) && (len > src_len)) { 38 | if (openosc_log) { 39 | openosc_danger_error("memcpy source", src_len, len); 40 | } 41 | openosc_get_config(&openosc_abort); 42 | if (openosc_abort) { 43 | abort(); 44 | } 45 | if (openosc_truncate) { 46 | if ((dest_len == (size_t) -1) || (dest_len == 0)) { 47 | len = src_len; 48 | } else { 49 | len = MIN(src_len, dest_len); 50 | } 51 | } 52 | } 53 | 54 | #undef memcpy 55 | return (memcpy(dst, src, len)); 56 | } 57 | 58 | /* Mapping for memmove */ 59 | 60 | void * 61 | __openosc_memmove_to_buf(size_t dest_len, size_t src_len, void *dst, const void *src, size_t len) 62 | { 63 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 64 | 65 | if ((dest_len != (size_t) -1) && (dest_len != 0) && (len > dest_len)) { 66 | if (openosc_log) { 67 | openosc_danger_error("memmove destination", dest_len, len); 68 | } 69 | openosc_get_config(&openosc_abort); 70 | if (openosc_abort) { 71 | abort(); 72 | } 73 | if (openosc_truncate) { 74 | len = dest_len; 75 | } 76 | } 77 | 78 | if ((src_len != (size_t) -1) && (src_len != 0) && (len > src_len)) { 79 | if (openosc_log) { 80 | openosc_danger_error("memmove source", src_len, len); 81 | } 82 | openosc_get_config(&openosc_abort); 83 | if (openosc_abort) { 84 | abort(); 85 | } 86 | if (openosc_truncate) { 87 | if ((dest_len == (size_t) -1) || (dest_len == 0)) { 88 | len = src_len; 89 | } else { 90 | len = MIN(src_len, dest_len); 91 | } 92 | } 93 | } 94 | 95 | #undef memmove 96 | return (memmove(dst, src, len)); 97 | } 98 | 99 | /* Mapping for memset */ 100 | 101 | void * 102 | __openosc_memset_to_buf(size_t dest_len, void *dst, int c, size_t len) 103 | { 104 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 105 | 106 | if (len > dest_len) { 107 | if (openosc_log) { 108 | openosc_danger_error("memset", dest_len, len); 109 | } 110 | openosc_get_config(&openosc_abort); 111 | if (openosc_abort) { 112 | abort(); 113 | } 114 | if (openosc_truncate) { 115 | len = dest_len; 116 | } 117 | } 118 | #undef memset 119 | return (memset(dst, c, len)); 120 | } 121 | 122 | /* Mapping for bcopy */ 123 | 124 | void 125 | __openosc_bcopy_to_buf(size_t dest_len, size_t src_len, const void *src, void *dst, size_t len) 126 | { 127 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 128 | 129 | if ((dest_len != (size_t) -1) && (dest_len != 0) && (len > dest_len)) { 130 | if (openosc_log) { 131 | openosc_danger_error("bcopy destination", dest_len, len); 132 | } 133 | openosc_get_config(&openosc_abort); 134 | if (openosc_abort) { 135 | abort(); 136 | } 137 | if (openosc_truncate) { 138 | len = dest_len; 139 | } 140 | } 141 | 142 | if ((src_len != (size_t) -1) && (src_len != 0) && (len > src_len)) { 143 | if (openosc_log) { 144 | openosc_danger_error("bcopy source", src_len, len); 145 | } 146 | openosc_get_config(&openosc_abort); 147 | if (openosc_abort) { 148 | abort(); 149 | } 150 | if (openosc_truncate) { 151 | if ((dest_len == (size_t) -1) || (dest_len == 0)) { 152 | len = src_len; 153 | } else { 154 | len = MIN(src_len, dest_len); 155 | } 156 | } 157 | } 158 | 159 | #undef bcopy 160 | bcopy(src, dst, len); 161 | } 162 | 163 | /* Mapping for bzero */ 164 | 165 | void 166 | __openosc_bzero_to_buf(size_t dest_len, void *dst, size_t len) 167 | { 168 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 169 | 170 | if (len > dest_len) { 171 | if (openosc_log) { 172 | openosc_danger_error("bzero", dest_len, len); 173 | } 174 | openosc_get_config(&openosc_abort); 175 | if (openosc_abort) { 176 | abort(); 177 | } 178 | if (openosc_truncate) { 179 | len = dest_len; 180 | } 181 | } 182 | #undef bzero 183 | bzero(dst, len); 184 | } 185 | 186 | /* Mapping for strcpy */ 187 | 188 | char * 189 | __openosc_strcpy_to_buf (size_t dest_len, char *dst, const char *src) 190 | { 191 | size_t len = strlen(src); 192 | char *rstr; 193 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 194 | 195 | if ((len + 1) > dest_len) { 196 | if (openosc_log) { 197 | openosc_danger_error("strcpy", dest_len, len); 198 | } 199 | openosc_get_config(&openosc_abort); 200 | if (openosc_abort) { 201 | abort(); 202 | } 203 | if (openosc_truncate) { 204 | len = dest_len - 1; 205 | } 206 | } 207 | #undef strncpy 208 | rstr = strncpy(dst, src, len); 209 | *(rstr + len) = '\0'; 210 | return (rstr); 211 | } 212 | 213 | /* Mapping for strncpy */ 214 | 215 | char * 216 | __openosc_strncpy_to_buf (size_t dest_len, char *dst, 217 | const char *src, size_t len) 218 | { 219 | char *rstr; 220 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 221 | 222 | if (len > dest_len) { 223 | if (openosc_log) { 224 | openosc_danger_error("strncpy", dest_len, len); 225 | } 226 | openosc_get_config(&openosc_abort); 227 | if (openosc_abort) { 228 | abort(); 229 | } 230 | if (openosc_truncate) { 231 | rstr = strncpy(dst, src, dest_len); 232 | dst[dest_len - 1] = '\0'; 233 | return (rstr); 234 | } 235 | } 236 | #undef strncpy 237 | rstr = strncpy(dst, src, len); 238 | return (rstr); 239 | } 240 | 241 | /* Mapping for strcat */ 242 | 243 | char * 244 | __openosc_strcat_to_buf (size_t dest_len, char *dst, const char *src) 245 | { 246 | size_t len = strlen(src); 247 | size_t dst_len_to_null = strlen(dst); 248 | char *rstr; 249 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 250 | 251 | if (dest_len < (len + dst_len_to_null + 1)) { 252 | if (openosc_log) { 253 | openosc_danger_error("strcat", dest_len, len); 254 | } 255 | if ((dst_len_to_null + 1) >= dest_len) { 256 | return (dst); 257 | } 258 | openosc_get_config(&openosc_abort); 259 | if (openosc_abort) { 260 | abort(); 261 | } 262 | if (openosc_truncate) { 263 | len = dest_len - dst_len_to_null - 1; 264 | } 265 | } 266 | #undef strncat 267 | rstr = strncat(dst, src, len); 268 | return (rstr); 269 | } 270 | 271 | /* Mapping for strncat */ 272 | 273 | char * 274 | __openosc_strncat_to_buf (size_t dest_len, char *dst, 275 | const char *src, size_t len) 276 | { 277 | size_t dst_len_to_null = strlen(dst); 278 | char *rstr; 279 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 280 | 281 | if (dest_len < (MIN(strlen(src), len) + dst_len_to_null + 1)) { 282 | if (openosc_log) { 283 | openosc_danger_error("strncat", dest_len, len); 284 | } 285 | if ((dst_len_to_null + 1) >= dest_len) { 286 | return (dst); 287 | } 288 | openosc_get_config(&openosc_abort); 289 | if (openosc_abort) { 290 | abort(); 291 | } 292 | if (openosc_truncate) { 293 | len = dest_len - dst_len_to_null - 1; 294 | } 295 | } 296 | #undef strncat 297 | rstr = strncat(dst, src, len); 298 | return (rstr); 299 | } 300 | 301 | /* Mapping for strnlen */ 302 | 303 | size_t 304 | __openosc_strnlen_from_buf(size_t len, const char *src, size_t maxlen) 305 | { 306 | if (maxlen > len) { 307 | if (openosc_log) { 308 | openosc_danger_error("strnlen", len, maxlen); 309 | } 310 | } 311 | #undef strnlen 312 | return strnlen(src, maxlen); 313 | } 314 | 315 | /* Mapping for vsnprintf */ 316 | 317 | int 318 | __openosc_vsnprintf_to_buf (size_t dest_len, char *str, size_t len, 319 | const char *fmt, va_list ap) 320 | { 321 | unsigned int openosc_abort = OPENOSC_DEF_ABORT_STATE; 322 | 323 | if (len > dest_len) { 324 | if (openosc_log) { 325 | openosc_danger_error("vsnprintf", dest_len, len); 326 | } 327 | openosc_get_config(&openosc_abort); 328 | if (openosc_abort) { 329 | abort(); 330 | } 331 | if (openosc_truncate) { 332 | len = dest_len; 333 | } 334 | } 335 | #undef vsnprintf 336 | return (vsnprintf(str, len, fmt, ap)); 337 | } 338 | -------------------------------------------------------------------------------- /test/test_harness_bosc_safec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #include 11 | #include "test_harness_bosc.h" 12 | #include "openosc_safec_map.h" 13 | 14 | extern char th_dst[STATIC_BUF_SIZE]; /* Destination buffer */ 15 | extern char th_src[STATIC_BUF_SIZE]; /* Source buffer */ 16 | extern th_test_data th_testcase[TH_NUM_TEST]; 17 | 18 | /* 19 | * Different sizes used as test input parameter into the remap safeC 20 | * APIs and the expected result 21 | */ 22 | th_test_safec_data th_safec_testcase[TH_NUM_TEST_SAFEC] = { 23 | /* Test Description 24 | * dmax, slen, expect_dcdi, criteria */ 25 | { "'dmax' is -1 and 'slen' is equal to dest buffer size", -1, 26 | STATIC_BUF_SIZE, TH_RESULT_DCDI, TH_PASS_NOT_EOK }, 27 | { "'dmax' is 0 and 'slen' is equal to dest buffer size", 0, 28 | STATIC_BUF_SIZE, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 29 | { "'dmax' is 1 less than dest buffer's size and 'slen' is equal to dest buffer size ", 30 | STATIC_BUF_SIZE - 1, STATIC_BUF_SIZE, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 31 | { "'dmax' is equal to dest buffer's size and 'slen' is equal to dest buffer size", 32 | STATIC_BUF_SIZE, STATIC_BUF_SIZE, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 33 | { "'dmax' is 1 more than dest buffer size and 'slen' is equal to dest buffer size", 34 | STATIC_BUF_SIZE + 1, STATIC_BUF_SIZE, TH_RESULT_DCDI, TH_PASS_NOT_EOK }, 35 | { "'dmax' is equal to dest buffer size and 'slen' is 1 less than dest buffer size", 36 | STATIC_BUF_SIZE, STATIC_BUF_SIZE - 1, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 37 | { "'dmax' is equal to dest buffer size and 'slen' is 1 more than dest buffer size", 38 | STATIC_BUF_SIZE, STATIC_BUF_SIZE + 1, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 39 | { "'dmax' is equal to dest buffer size and 'slen' is 0", 40 | STATIC_BUF_SIZE, 0, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 41 | { "'dmax' is equal to dest buffer size and 'slen' is -1", 42 | STATIC_BUF_SIZE, -1, TH_RESULT_NO_DCDI, TH_PASS_EOK }, 43 | }; 44 | 45 | /* 46 | * bosc_th_setup_safec_test 47 | * 48 | * Common setup function to test safec functions. This function will 49 | * initialize the global th_dst and th_src to well known values and 50 | * print out the pre-test information 51 | */ 52 | 53 | void 54 | bosc_th_setup_safec_test (char *api_name, int testcase_idx) 55 | { 56 | char testname[80]; 57 | th_test_param params[] = {{"dest size", STATIC_BUF_SIZE}, {"dmax", 0}, 58 | {"src size", STATIC_BUF_SIZE}, {"slen", 0}}; 59 | 60 | /* Create testname from test api and testcase index */ 61 | sprintf(testname, "%s_test_case_%d", api_name, testcase_idx); 62 | 63 | /* Initalize dest and src buffers */ 64 | TH_SETUP_ZERO_DST_BUF(); 65 | TH_SETUP_SEQ_SRC_BUF(); 66 | 67 | params[1].value = th_safec_testcase[testcase_idx].dmax; 68 | params[3].value = th_safec_testcase[testcase_idx].slen; 69 | /* Display Pre-test conditions */ 70 | bosc_th_print_test_conditions(testname, th_safec_testcase[testcase_idx].desc, 4, 71 | params, th_safec_testcase[testcase_idx].expect_dcdi); 72 | TH_PRINT_DST(); 73 | TH_PRINT_SRC(); 74 | printf("\n"); 75 | } 76 | 77 | 78 | void 79 | bosc_th_test_osc_memcmp_s (void) 80 | { 81 | int i, diff, res; 82 | 83 | for (i = 0; i < TH_NUM_TEST_SAFEC; i++) { 84 | 85 | /* Setup and display Pre-test conditions */ 86 | bosc_th_setup_safec_test("memcmp_s", i); 87 | 88 | /* Start test */ 89 | printf(TH_TEST_START_STR); 90 | res = memcmp_s (th_dst, th_safec_testcase[i].dmax, th_src, 91 | th_safec_testcase[i].slen, &diff); 92 | printf(TH_TEST_END_STR"\n"); 93 | 94 | /* print the result */ 95 | bosc_th_print_result_safec(res, th_safec_testcase[i].criteria); 96 | } 97 | } 98 | 99 | void 100 | bosc_th_test_osc_memcpy_s (void) 101 | { 102 | int i, res; 103 | 104 | for (i = 0; i < TH_NUM_TEST_SAFEC; i++) { 105 | 106 | /* Setup and display Pre-test conditions */ 107 | bosc_th_setup_safec_test("memcpy_s", i); 108 | 109 | /* Start test */ 110 | printf(TH_TEST_START_STR); 111 | res = memcpy_s (th_dst, th_safec_testcase[i].dmax, 112 | th_src, th_safec_testcase[i].slen); 113 | printf(TH_TEST_END_STR"\n"); 114 | 115 | /* print the result */ 116 | bosc_th_print_result_safec(res, th_safec_testcase[i].criteria); 117 | } 118 | } 119 | 120 | void 121 | bosc_th_test_osc_strcat_s (void) 122 | { 123 | int i, res; 124 | 125 | for (i = 0; i < TH_NUM_TEST; i++) { 126 | if (i != 4) { 127 | th_testcase[i].expect_dcdi = TH_RESULT_DCDI; 128 | th_testcase[i].criteria = TH_PASS_NOT_EQU; 129 | } 130 | 131 | /* Setup and display Pre-test conditions */ 132 | bosc_th_setup_3arg_test("strcat_s", i); 133 | 134 | /* Start test */ 135 | printf(TH_TEST_START_STR); 136 | res = strcat_s (th_dst, th_testcase[i].size, th_src); 137 | printf(TH_TEST_END_STR"\n"); 138 | 139 | /* print the result */ 140 | bosc_th_print_result_safec(res, th_testcase[i].criteria); 141 | /* revert back to the original */ 142 | if (i != 4) { 143 | th_testcase[i].expect_dcdi = TH_RESULT_NO_DCDI; 144 | th_testcase[i].criteria = TH_PASS_EQU; 145 | } 146 | } 147 | } 148 | 149 | void 150 | bosc_th_test_osc_strcmp_s (void) 151 | { 152 | int i, diff, res; 153 | 154 | for (i = 0; i < TH_NUM_TEST; i++) { 155 | 156 | /* Setup and display Pre-test conditions */ 157 | bosc_th_setup_3arg_test("strcmp_s", i); 158 | 159 | /* Start test */ 160 | printf(TH_TEST_START_STR); 161 | res = strcmp_s (th_dst, th_testcase[i].size, th_src, &diff); 162 | printf(TH_TEST_END_STR"\n"); 163 | 164 | /* print the result */ 165 | bosc_th_print_result_safec(res, th_testcase[i].criteria); 166 | } 167 | } 168 | 169 | void bosc_th_test_osc_strcpy_s (void) 170 | { 171 | int i, res; 172 | 173 | for (i = 0; i < TH_NUM_TEST; i++) { 174 | 175 | /* Setup and display Pre-test conditions */ 176 | bosc_th_setup_3arg_test("strcpy_s", i); 177 | 178 | /* Start test */ 179 | printf(TH_TEST_START_STR); 180 | res = strcpy_s (th_dst, th_testcase[i].size, th_src); 181 | printf(TH_TEST_END_STR"\n"); 182 | 183 | /* print the result */ 184 | bosc_th_print_result_safec(res, th_testcase[i].criteria); 185 | } 186 | } 187 | 188 | void 189 | bosc_th_test_osc_strncat_s (void) 190 | { 191 | int i, res; 192 | 193 | for (i = 0; i < TH_NUM_TEST_SAFEC; i++) { 194 | 195 | /* except the below cases, the 'slen' is equal to dest 196 | * buffer's size. So will get DCDI error (because dest 197 | * buffer should accomodate the existing content of dest 198 | * and no. of char(s) to concatenate into dest with null). 199 | */ 200 | if (i == 1 || i == 2 || i == 3 || i == 6) { 201 | th_safec_testcase[i].expect_dcdi = TH_RESULT_DCDI; 202 | th_safec_testcase[i].criteria = TH_PASS_NOT_EOK; 203 | } 204 | 205 | /* Setup and display Pre-test conditions */ 206 | bosc_th_setup_safec_test("strncat_s", i); 207 | 208 | /* Start test */ 209 | printf(TH_TEST_START_STR); 210 | res = strncat_s (th_dst, th_safec_testcase[i].dmax, 211 | th_src, th_safec_testcase[i].slen); 212 | printf(TH_TEST_END_STR"\n"); 213 | 214 | /* print the result */ 215 | bosc_th_print_result_safec(res, th_safec_testcase[i].criteria); 216 | 217 | /* revert back */ 218 | if (i == 1 || i == 2 || i == 3 || i == 6) { 219 | th_safec_testcase[i].expect_dcdi = TH_RESULT_NO_DCDI; 220 | th_safec_testcase[i].criteria = TH_PASS_EOK; 221 | } 222 | } 223 | } 224 | 225 | void 226 | bosc_th_test_osc_strncpy_s (void) 227 | { 228 | int i, res; 229 | 230 | for (i = 0; i < TH_NUM_TEST_SAFEC; i++) { 231 | 232 | /* 'slen' should be less than or equal to dest buffer size */ 233 | if (i == 6 || i == 8) { 234 | th_safec_testcase[i].expect_dcdi = TH_RESULT_DCDI; 235 | th_safec_testcase[i].criteria = TH_PASS_NOT_EOK; 236 | } 237 | 238 | /* Setup and display Pre-test conditions */ 239 | bosc_th_setup_safec_test("strncpy_s", i); 240 | 241 | /* Start test */ 242 | printf(TH_TEST_START_STR); 243 | res = strncpy_s (th_dst, th_safec_testcase[i].dmax, 244 | th_src, th_safec_testcase[i].slen); 245 | printf(TH_TEST_END_STR"\n"); 246 | 247 | /* print the result */ 248 | bosc_th_print_result_safec(res, th_safec_testcase[i].criteria); 249 | 250 | /* revert back */ 251 | if (i == 6 || i == 8) { 252 | th_safec_testcase[i].expect_dcdi = TH_RESULT_NO_DCDI; 253 | th_safec_testcase[i].criteria = TH_PASS_EOK; 254 | } 255 | } 256 | } 257 | 258 | void bosc_th_test_osc_strnlen_s (void) 259 | { 260 | int i, res; 261 | 262 | for (i = 0; i < TH_NUM_TEST; i++) { 263 | 264 | /* Setup and display Pre-test conditions */ 265 | bosc_th_setup_3arg_test("strnlen_s", i); 266 | 267 | /* Start test */ 268 | printf(TH_TEST_START_STR); 269 | res = strnlen_s (th_src, th_testcase[i].size); 270 | printf(TH_TEST_END_STR"\n"); 271 | 272 | /* print the result */ 273 | bosc_th_print_result_safec(res, th_testcase[i].criteria); 274 | } 275 | } 276 | 277 | void 278 | bosc_th_test_osc_strstr_s (void) 279 | { 280 | int i, res; 281 | char *substr = NULL; 282 | char testname[80]; 283 | 284 | for (i = 0; i < TH_NUM_TEST_SAFEC; i++) { 285 | /* Get testname for each case */ 286 | sprintf(testname, "strstr_s-test_case-%d", i); 287 | /* Setup and display Pre-test conditions */ 288 | bosc_th_setup_safec_test("strstr_s", i); 289 | 290 | /* Start test */ 291 | printf(TH_TEST_START_STR); 292 | res = strstr_s (th_dst, th_safec_testcase[i].dmax, 293 | th_src, th_safec_testcase[i].slen, &substr); 294 | printf(TH_TEST_END_STR"\n"); 295 | 296 | /* print the result */ 297 | bosc_th_print_result_safec(res, th_safec_testcase[i].criteria); 298 | } 299 | } 300 | 301 | /* 302 | * series of tests for some safec APIs 303 | */ 304 | 305 | void 306 | bosc_th_test_osc_safec_remap (void) 307 | { 308 | printf("\n\n BOSC Remap API Tests for safeC\n"); 309 | 310 | bosc_th_test_osc_strcat_s (); 311 | bosc_th_test_osc_memcmp_s (); 312 | bosc_th_test_osc_memcpy_s (); 313 | // bosc_th_test_osc_strcat_s (); 314 | bosc_th_test_osc_strcmp_s (); 315 | bosc_th_test_osc_strcpy_s (); 316 | bosc_th_test_osc_strncat_s (); 317 | bosc_th_test_osc_strncpy_s (); 318 | bosc_th_test_osc_strnlen_s (); 319 | bosc_th_test_osc_strstr_s (); 320 | 321 | } 322 | 323 | -------------------------------------------------------------------------------- /test/test_harness_compile_check.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | #include 10 | #include 11 | #include "test_harness_bosc.h" 12 | 13 | char th_dst[STATIC_BUF_SIZE]; /* Destination buffer */ 14 | char th_src[STATIC_BUF_SIZE]; /* Source buffer */ 15 | char th_src_one_less[STATIC_BUF_SIZE-1]; /* Smaller than dest buffer */ 16 | char th_src_one_more[STATIC_BUF_SIZE+1]; /* Larger than dest buffer */ 17 | 18 | 19 | /* 20 | * This file should cause compilation to fail. Build with make break. 21 | * OSC remap compilation testing 22 | */ 23 | void 24 | test_memcpy_dst_size_minus_1_NO_compile_error (void) 25 | { 26 | 27 | /* Expect no compile time error */ 28 | memcpy(th_dst, th_src, STATIC_BUF_SIZE - 1); 29 | } 30 | 31 | void 32 | test_memcpy_dst_size_NO_compile_error (void) 33 | { 34 | 35 | /* Expect no compile time error */ 36 | memcpy(th_dst, th_src, STATIC_BUF_SIZE); 37 | } 38 | 39 | void 40 | test_memcpy_dst_size_plus_1_compile_error (void) 41 | { 42 | 43 | /* Expect compile time error */ 44 | memcpy(th_dst, th_src, STATIC_BUF_SIZE + 1); 45 | } 46 | 47 | // memmove checker functions added below 48 | void 49 | test_memmove_dst_size_minus_1_NO_compile_error (void) 50 | { 51 | 52 | /* Expect no compile time error */ 53 | memmove(th_dst, th_src, STATIC_BUF_SIZE - 1); 54 | } 55 | 56 | void 57 | test_memmove_dst_size_NO_compile_error (void) 58 | { 59 | 60 | /* Expect no compile time error */ 61 | memmove(th_dst, th_src, STATIC_BUF_SIZE); 62 | } 63 | 64 | void 65 | test_memmove_dst_size_plus_1_compile_error (void) 66 | { 67 | 68 | /* Expect compile time error */ 69 | memmove(th_dst, th_src, STATIC_BUF_SIZE + 1); 70 | } 71 | 72 | // memset checker functions added below 73 | void 74 | test_memset_dst_size_minus_1_NO_compile_error (void) 75 | { 76 | /* Expect no compile time error */ 77 | memset(th_dst, '\0', STATIC_BUF_SIZE - 1); 78 | } 79 | 80 | void 81 | test_memset_dst_size_NO_compile_error (void) 82 | { 83 | 84 | /* Expect no compile time error */ 85 | memset(th_dst, '\0', STATIC_BUF_SIZE); 86 | } 87 | 88 | void 89 | test_memset_dst_size_plus_1_compile_error (void) 90 | { 91 | 92 | /* Expect compile time error */ 93 | memset(th_dst, '\0', STATIC_BUF_SIZE+1); 94 | } 95 | 96 | //bcopy checker functions added below 97 | void 98 | test_bcopy_dst_size_minus_1_NO_compile_error (void) 99 | { 100 | 101 | /* Expect no compile time error */ 102 | bcopy(th_src, th_dst, STATIC_BUF_SIZE - 1); 103 | } 104 | 105 | void 106 | test_bcopy_dst_size_NO_compile_error (void) 107 | { 108 | 109 | /* Expect no compile time error */ 110 | bcopy(th_src, th_dst, STATIC_BUF_SIZE); 111 | } 112 | 113 | void 114 | test_bcopy_dst_size_plus_1_compile_error (void) 115 | { 116 | 117 | /* Expect compile time error */ 118 | bcopy(th_src, th_dst, STATIC_BUF_SIZE + 1); 119 | } 120 | 121 | //bzero checker functions added below 122 | void 123 | test_bzero_dst_size_minus_1_NO_compile_error (void) 124 | { 125 | 126 | /* Expect no compile time error */ 127 | bzero(th_dst, STATIC_BUF_SIZE - 1); 128 | } 129 | 130 | void 131 | test_bzero_dst_size_NO_compile_error (void) 132 | { 133 | 134 | /* Expect no compile time error */ 135 | bzero(th_dst, STATIC_BUF_SIZE); 136 | } 137 | 138 | void 139 | test_bzero_dst_size_plus_1_compile_error (void) 140 | { 141 | 142 | /* Expect compile time error */ 143 | bzero(th_dst, STATIC_BUF_SIZE + 1); 144 | } 145 | 146 | //strcpy checker functions added below 147 | void 148 | test_strcpy_dst_size_minus_1_NO_compile_error (void) 149 | { 150 | 151 | /* Expect no compile time error */ 152 | strcpy(th_dst, th_src_one_less); 153 | } 154 | 155 | void 156 | test_strcpy_dst_size_NO_compile_error (void) 157 | { 158 | 159 | /* Expect no compile time error */ 160 | strcpy(th_dst, th_src); 161 | } 162 | 163 | void 164 | test_strcpy_dst_size_plus_1_compile_error (void) 165 | { 166 | char dst[6] = "Hello"; 167 | char src[12] = "Hello World"; 168 | 169 | /* Expect compile time error */ 170 | strcpy(dst, src); 171 | } 172 | 173 | //strncpy checker functions added below 174 | void 175 | test_strncpy_dst_size_minus_1_NO_compile_error (void) 176 | { 177 | 178 | /* Expect no compile time error */ 179 | strncpy(th_dst, th_src, STATIC_BUF_SIZE - 1); 180 | } 181 | 182 | void 183 | test_strncpy_dst_size_NO_compile_error (void) 184 | { 185 | 186 | /* Expect no compile time error */ 187 | strncpy(th_dst, th_src, STATIC_BUF_SIZE); 188 | } 189 | 190 | void 191 | test_strncpy_dst_size_plus_1_compile_error (void) 192 | { 193 | 194 | /* Expect compile time error, dst is less than the src */ 195 | strncpy(th_dst, th_src_one_more, STATIC_BUF_SIZE + 1); 196 | } 197 | 198 | void 199 | test_strncpy_beyond_src_size_compile_error (void) 200 | { 201 | 202 | /* Expect compile time error, copying data beyond the 203 | limit of src */ 204 | strncpy(th_dst, th_src, STATIC_BUF_SIZE + 1); 205 | } 206 | 207 | //strcat checker functions added below 208 | void 209 | test_strcat_dst_size_minus_1_NO_compile_error (void) 210 | { 211 | char dst[13] = "Hello"; 212 | char src[7] = " world"; 213 | 214 | /* Expect no compile time error */ 215 | strcat(dst, src); 216 | } 217 | 218 | void 219 | test_strcat_dst_size_NO_compile_error (void) 220 | { 221 | char dst[12] = "Hello"; 222 | char src[7] = " world"; 223 | 224 | /* Expect no compile time error */ 225 | strcat(dst, src); 226 | } 227 | 228 | void 229 | test_strcat_dst_size_plus_1_compile_error (void) 230 | { 231 | char dst[11] = "Hello"; 232 | char src[7] = " world"; 233 | 234 | /* Expect compile time error, not enough 235 | space to store '\0' character*/ 236 | strcat(dst, src); 237 | } 238 | 239 | //strncat checker functions added below 240 | void 241 | test_strncat_dst_size_minus_1_NO_compile_error (void) 242 | { 243 | char dst[13] = "Hello"; 244 | char src[7] = " world"; 245 | 246 | /* Expect no compile time error */ 247 | strncat(dst, src, 7); 248 | } 249 | 250 | void 251 | test_strncat_dst_size_NO_compile_error (void) 252 | { 253 | char dst[12] = "Hello"; 254 | char src[7] = " world"; 255 | 256 | /* Expect no compile time error */ 257 | strncat(dst, src, 7); 258 | } 259 | 260 | void 261 | test_strncat_dst_size_plus_1_compile_error (void) 262 | { 263 | char dst[11] = "Hello"; 264 | char src[7] = " world"; 265 | 266 | /* Expect compile time error, due to concatenating 267 | src size is greater than dst*/ 268 | strncat(dst, src, 12); 269 | } 270 | 271 | void 272 | test_strncat_src_not_null_terminated_compile_error (void) 273 | { 274 | char dst[12] = "Hello"; 275 | char src[6] = " world"; 276 | 277 | /* Expect compile time error, no '\0' character 278 | in first 6 bytes of src*/ 279 | strncat(dst, src, 6); 280 | } 281 | 282 | //strlen checker functions added below 283 | int 284 | test_strlen_dst_size_minus_1_NO_compile_error (void) 285 | { 286 | char dst[13] = "Hello World"; 287 | 288 | /* Expect no compile time error */ 289 | return strlen(dst); 290 | } 291 | 292 | int 293 | test_strlen_dst_size_NO_compile_error (void) 294 | { 295 | char dst[12] = "Hello World"; 296 | 297 | /* Expect no compile time error */ 298 | return strlen(dst); 299 | } 300 | 301 | int 302 | test_strlen_dst_size_plus_1_compile_error (void) 303 | { 304 | char dst[12] = "Hello World."; 305 | 306 | /* Expect compile time error, no space to 307 | store null character */ 308 | return strlen(dst); 309 | } 310 | 311 | //strnlen checker functions added below 312 | int 313 | test_strnlen_dst_size_minus_1_NO_compile_error (void) 314 | { 315 | char dst[13] = "Hello World"; 316 | 317 | /* Expect no compile time error */ 318 | return strnlen(dst, 13); 319 | } 320 | 321 | int 322 | test_strnlen_dst_size_NO_compile_error (void) 323 | { 324 | char dst[12] = "Hello World"; 325 | 326 | /* Expect no compile time error */ 327 | return strnlen(dst, 12); 328 | } 329 | 330 | int 331 | test_strnlen_dst_size_plus_1_compile_error (void) 332 | { 333 | char dst[12] = "Hello World."; 334 | 335 | /* Expect compile time error, no space to 336 | store null character */ 337 | return strnlen(dst, 12); 338 | } 339 | 340 | // Global buffer to fill by vsprint anf vsnprintf functions 341 | char buffer[STATIC_BUF_SIZE]; 342 | 343 | // Generic driver function for vsprintf 344 | int 345 | vsdriver_func(char *format, ...) 346 | { 347 | va_list vptr; 348 | int ret; 349 | 350 | va_start(vptr, format); 351 | /* write the content to buffer */ 352 | ret = vsprintf(buffer, format, vptr); 353 | va_end(vptr); 354 | 355 | return ret; 356 | } 357 | 358 | // vsprintf checker functions added below 359 | void 360 | test_vsprintf_dst_size_minus_1_NO_compile_error(void) 361 | { 362 | char str[STATIC_BUF_SIZE-1] = "ABCDEFGH"; 363 | 364 | /* Expect NO compile time error */ 365 | vsdriver_func("%s", str); 366 | } 367 | 368 | void 369 | test_vsprintf_dst_size_NO_compile_error(void) 370 | { 371 | char str[STATIC_BUF_SIZE] = "ABCDEFGHI"; 372 | 373 | /* Expect NO compile time error */ 374 | vsdriver_func("%s", str); 375 | } 376 | 377 | void 378 | test_vsprintf_dst_size_plus_1_compile_error(void) 379 | { 380 | char str[STATIC_BUF_SIZE+1] = "ABCDEFGHIJ"; 381 | 382 | /* Expect compile time error */ 383 | vsdriver_func("%s", str); 384 | } 385 | 386 | // Generic driver function for vsnprintf 387 | int 388 | vsndriver_func(size_t size, char *format, ...) 389 | { 390 | va_list vptr; 391 | int ret; 392 | 393 | va_start(vptr, format); 394 | /* write the content to buffer */ 395 | ret = vsnprintf(buffer, size, format, vptr); 396 | va_end(vptr); 397 | 398 | return ret; 399 | } 400 | 401 | // vsnprintf checker functions added below 402 | void 403 | test_vsnprintf_dst_size_minus_1_NO_compile_error(void) 404 | { 405 | char str[STATIC_BUF_SIZE-1] = "ABCDEFGH"; 406 | 407 | /* Expect NO compile time error */ 408 | vsndriver_func(STATIC_BUF_SIZE, "%s", str); 409 | } 410 | 411 | void 412 | test_vsnprintf_dst_size_NO_compile_error(void) 413 | { 414 | char str[STATIC_BUF_SIZE] = "ABCDEFGHI"; 415 | 416 | /* Expect NO compile time error */ 417 | vsndriver_func(STATIC_BUF_SIZE, "%s", str); 418 | } 419 | 420 | void 421 | test_vsnprintf_dst_size_plus_1_compile_error(void) 422 | { 423 | char str[STATIC_BUF_SIZE+1] = "ABCDEFGHIJ"; 424 | 425 | /* Expect compile time error */ 426 | vsndriver_func(STATIC_BUF_SIZE, "%s", str); 427 | } 428 | 429 | void 430 | test_vsnprintf_dst_size_beyond_compile_error(void) 431 | { 432 | char str[STATIC_BUF_SIZE+1] = "ABCDEFGHIJ"; 433 | 434 | /* Expect compile time error */ 435 | vsndriver_func(STATIC_BUF_SIZE + 4, "%s", str); 436 | } 437 | 438 | /* 439 | * This main function is here to allow "make break" to work in 440 | * the case OSC_COMPILE_CHK is set to OSC_ASSERT_USE_RUNTIME_CHK 441 | */ 442 | int main(void) 443 | { 444 | /* No op */ 445 | return 1; 446 | } 447 | -------------------------------------------------------------------------------- /test/test_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | #include 10 | #include 11 | #include "test_harness_defs.h" 12 | #include "test_harness_aux.h" 13 | 14 | int is_large_size = 1; 15 | 16 | /* 17 | * The entry point to run all of the test harness's functions (defined below) 18 | */ 19 | void 20 | bosc_th_run_tests (void) 21 | { 22 | printf("BOSC_TH_VERSION %.2f\n", (float)BOSC_TH_VERSION); 23 | printf("COMPILER_VERSION: %s\n\n", BOSC_TH_COMPILER_VERSION); 24 | 25 | bosc_th_test_char(); 26 | bosc_th_call_aux_fns(); 27 | 28 | /* Extra OSC remap testing */ 29 | bosc_th_test_osc_remap(); 30 | #ifdef HAS_SAFEC 31 | bosc_th_test_osc_safec_remap(); 32 | #endif 33 | /* OSC logging testing */ 34 | bosc_th_test_osc_logging(); 35 | 36 | /* OSC truncation testing */ 37 | bosc_th_test_osc_truncation(); 38 | 39 | /* OSC thread safe testing */ 40 | bosc_th_test_osc_thread_safe(); 41 | } 42 | 43 | /* 44 | * This function tests how object size checkers deal with objects whose size can 45 | * vary between fixed values at run-time. 46 | */ 47 | static size_t 48 | static_bosc_th_test_flow_char (int flag) 49 | { 50 | char *cptr; 51 | char char_buf1[STATIC_BUF_SIZE]; 52 | char char_buf2[LARGER_BUF_SIZE]; 53 | if (flag) { 54 | cptr = char_buf1; 55 | } else { 56 | cptr = char_buf2; 57 | } 58 | return __builtin_object_size(cptr, TH_SIZE_CHECK_1); 59 | } 60 | 61 | /* 62 | * For outputting results 63 | */ 64 | void 65 | bosc_th_show_result (const char *test_name, int size, int correct_size) 66 | { 67 | printf("%32s: Expected size %2d Detected %2d %s\n", 68 | test_name, correct_size, size, 69 | (correct_size == size) ? "" : "(FAILED)"); 70 | } 71 | 72 | void * 73 | bosc_th_malloc_fn (size_t size) 74 | { 75 | if (is_large_size) { 76 | return (malloc(size)); 77 | } else { 78 | return NULL; 79 | } 80 | } 81 | 82 | void * 83 | bosc_th_malloc (size_t size) 84 | { 85 | return (bosc_th_malloc_fn(size)); 86 | } 87 | 88 | /* 89 | * A series of tests on buffers 90 | */ 91 | void 92 | bosc_th_test_char (void) 93 | { 94 | int i; 95 | int test_size, intvar; 96 | void *vptr; 97 | char charvar, *cptr; 98 | char char_buf[STATIC_BUF_SIZE]; 99 | char char_2d_array[NUMBER_OF_BUFS][STATIC_BUF_SIZE]; 100 | char **cptrptr; 101 | short short_buf[STATIC_BUF_SIZE], shortvar; 102 | int int_buf[STATIC_BUF_SIZE]; 103 | struct1 s1; 104 | struct1 *s4; 105 | struct3 s3; 106 | union1 u1; 107 | 108 | /* Basic tests with type short */ 109 | test_size = __builtin_object_size(&shortvar, TH_SIZE_CHECK_1); 110 | bosc_th_show_result("SHORT_ADDR_SIZE", test_size, sizeof(short)); 111 | test_size = __builtin_object_size(short_buf, TH_SIZE_CHECK_1); 112 | bosc_th_show_result("STATIC_SIZE_SHORT", test_size, sizeof(short_buf)); 113 | test_size = __builtin_object_size(short_buf + 5, TH_SIZE_CHECK_1); 114 | bosc_th_show_result("STATIC_SIZE_SHORT_OFFSET", test_size, 115 | sizeof(short_buf) - 5 * sizeof(short)); 116 | 117 | /* Basic tests with type int */ 118 | test_size = __builtin_object_size(&intvar, TH_SIZE_CHECK_1); 119 | bosc_th_show_result("INT_ADDR_SIZE", test_size, sizeof(int)); 120 | test_size = __builtin_object_size(int_buf, TH_SIZE_CHECK_1); 121 | bosc_th_show_result("STATIC_SIZE_INT", test_size, sizeof(int_buf)); 122 | test_size = __builtin_object_size(int_buf + 5, TH_SIZE_CHECK_1); 123 | bosc_th_show_result("STATIC_SIZE_INT_OFFSET", test_size, 124 | sizeof(int_buf) - 5 * sizeof(int)); 125 | 126 | /* Basic tests with type char */ 127 | test_size = __builtin_object_size(&charvar, TH_SIZE_CHECK_1); 128 | bosc_th_show_result("CHAR_ADDR_SIZE", test_size, sizeof(char)); 129 | test_size = __builtin_object_size(char_buf, TH_SIZE_CHECK_1); 130 | bosc_th_show_result("STATIC_SIZE_CHAR", test_size, STATIC_BUF_SIZE); 131 | test_size = __builtin_object_size(char_buf + 5, TH_SIZE_CHECK_1); 132 | bosc_th_show_result("STATIC_SIZE_CHAR_OFFSET", test_size, 133 | STATIC_BUF_SIZE - 5); 134 | 135 | /* Basic tests with type void * */ 136 | test_size = __builtin_object_size(&charvar, TH_SIZE_CHECK_1); 137 | bosc_th_show_result("VOID_ADDR_SIZE", test_size, sizeof(char)); 138 | test_size = __builtin_object_size(char_buf, TH_SIZE_CHECK_1); 139 | bosc_th_show_result("STATIC_SIZE_VOID", test_size, STATIC_BUF_SIZE); 140 | test_size = __builtin_object_size(char_buf + 5, TH_SIZE_CHECK_1); 141 | bosc_th_show_result("STATIC_SIZE_VOID_OFFSET", test_size, 142 | STATIC_BUF_SIZE - 5); 143 | 144 | /* 2D array tests */ 145 | test_size = __builtin_object_size(char_2d_array, TH_SIZE_CHECK_1); 146 | bosc_th_show_result("CHAR_2D_ARRAY_TOTAL", test_size, 147 | sizeof(char_2d_array)); 148 | test_size = __builtin_object_size(char_2d_array[0], TH_SIZE_CHECK_1); 149 | bosc_th_show_result("CHAR_2D_ARRAY_FIRST", test_size, 150 | sizeof(char_2d_array[0])); 151 | test_size = __builtin_object_size(char_2d_array[1], TH_SIZE_CHECK_1); 152 | bosc_th_show_result("CHAR_2D_ARRAY_SECOND", test_size, 153 | sizeof(char_2d_array[1])); 154 | test_size = __builtin_object_size(char_2d_array[NUMBER_OF_BUFS - 1], 155 | TH_SIZE_CHECK_1); 156 | bosc_th_show_result("CHAR_2D_ARRAY_LAST", test_size, 157 | sizeof(char_2d_array[NUMBER_OF_BUFS - 1])); 158 | /* char ** tests */ 159 | cptrptr = (char **) malloc(sizeof(char *) * NUMBER_OF_BUFS); 160 | for (i = 0; i < NUMBER_OF_BUFS; i++) { 161 | cptrptr[i] = (char *) malloc(sizeof(char) * STATIC_BUF_SIZE); 162 | } 163 | test_size = __builtin_object_size(cptrptr, TH_SIZE_CHECK_1); 164 | bosc_th_show_result("CHAR_PTR_PTR_TOTAL", test_size, 165 | sizeof(char *) * NUMBER_OF_BUFS); 166 | test_size = __builtin_object_size(cptrptr[0], TH_SIZE_CHECK_1); 167 | bosc_th_show_result("CHAR_PTR_PTR_FIRST", test_size, 168 | STATIC_BUF_SIZE); 169 | test_size = __builtin_object_size(cptrptr[1], TH_SIZE_CHECK_1); 170 | bosc_th_show_result("CHAR_PTR_PTR_SECOND", test_size, 171 | STATIC_BUF_SIZE); 172 | test_size = __builtin_object_size(cptrptr[NUMBER_OF_BUFS - 1], TH_SIZE_CHECK_1); 173 | bosc_th_show_result("CHAR_PTR_PTR_LAST", test_size, 174 | STATIC_BUF_SIZE); 175 | 176 | /* Pointer assignment of fixed sized buffer */ 177 | vptr = char_buf; 178 | test_size = __builtin_object_size(vptr, TH_SIZE_CHECK_1); 179 | bosc_th_show_result("STATIC_SIZE_CHAR_CAST_VOID", test_size, 180 | STATIC_BUF_SIZE); 181 | cptr = char_buf; 182 | test_size = __builtin_object_size(cptr, TH_SIZE_CHECK_1); 183 | bosc_th_show_result("STATIC_SIZE_CHAR_CAST_PTR", test_size, 184 | STATIC_BUF_SIZE); 185 | cptr = char_buf; 186 | test_size = __builtin_object_size(cptr + 5, TH_SIZE_CHECK_1); 187 | bosc_th_show_result("STATIC_SIZE_CHAR_CAST_PTR_OFFSET", test_size, 188 | STATIC_BUF_SIZE - 5); 189 | 190 | 191 | /* Tests with malloc'ed buffer, size known at compile time */ 192 | cptr = malloc(sizeof(char) * MALLOC_BUF_SIZE); 193 | test_size = __builtin_object_size(cptr, TH_SIZE_CHECK_1); 194 | bosc_th_show_result("SIZE_ONCE_REMOVED_CHAR", test_size, MALLOC_BUF_SIZE); 195 | test_size = __builtin_object_size(cptr + 5, TH_SIZE_CHECK_1); 196 | bosc_th_show_result("SIZE_ONCE_REMOVED_CHAR_OFFSET", test_size, 197 | MALLOC_BUF_SIZE - 5); 198 | test_size = (int)__builtin_object_size(++cptr, TH_SIZE_CHECK_1); 199 | bosc_th_show_result("SIZE_ONCE_REMOVED_CHAR_INCR", test_size, 200 | MALLOC_BUF_SIZE - 1); 201 | 202 | /* Allocation of known structure size */ 203 | s4 = malloc(sizeof(struct1)); 204 | test_size = __builtin_object_size(s4, TH_SIZE_CHECK_1); 205 | bosc_th_show_result("ALLOCATED_STRUCT_SIZE", test_size, 206 | sizeof(struct1)); 207 | s4 = bosc_th_malloc(sizeof(struct1)); 208 | test_size = __builtin_object_size(s4, TH_SIZE_CHECK_1); 209 | bosc_th_show_result("INDIRECTLY_ALLOCATED_STRUCT_SIZE", test_size, 210 | sizeof(struct1)); 211 | 212 | /* Pointer assignment with malloc'ed buffer, size known at compile time */ 213 | cptr--; 214 | vptr = cptr; 215 | test_size = __builtin_object_size(vptr, TH_SIZE_CHECK_1); 216 | bosc_th_show_result("CHAR_PTR_CAST_VOID", test_size, MALLOC_BUF_SIZE); 217 | 218 | /* Tests with struct types, buffers in structs */ 219 | test_size = __builtin_object_size(&s1, TH_SIZE_CHECK_1); 220 | bosc_th_show_result("STATIC_STRUCT_SIZE", test_size, sizeof(struct1)); 221 | test_size = __builtin_object_size(&s1, TH_SIZE_CHECK_1); 222 | bosc_th_show_result("STATIC_STRUCT_SIZE_VOID", test_size, sizeof(struct1)); 223 | test_size = __builtin_object_size(s1.char_buf_first, TH_SIZE_CHECK_1); 224 | bosc_th_show_result("STRUCT_STATIC_CHAR_FIRST_SIZE", test_size, 225 | STATIC_BUF_SIZE); 226 | test_size = __builtin_object_size(s1.char_buf_mid, TH_SIZE_CHECK_1); 227 | bosc_th_show_result("STRUCT_STATIC_CHAR_MID_SIZE", test_size, 228 | STATIC_BUF_SIZE); 229 | test_size = __builtin_object_size(s1.char_buf_last, TH_SIZE_CHECK_1); 230 | bosc_th_show_result("STRUCT_STATIC_CHAR_LAST_SIZE", test_size, 231 | STATIC_BUF_SIZE); 232 | test_size = __builtin_object_size(s3.s1.char_buf_mid, TH_SIZE_CHECK_1); 233 | bosc_th_show_result("NESTED_STRUCT_CHAR_SIZE", test_size, STATIC_BUF_SIZE); 234 | 235 | /* Tests with union types of structs and buffers */ 236 | test_size = __builtin_object_size(&u1, TH_SIZE_CHECK_1); 237 | bosc_th_show_result("STATIC_UNION_SIZE", test_size, sizeof(union1)); 238 | test_size = __builtin_object_size(&u1.structvar, TH_SIZE_CHECK_1); 239 | bosc_th_show_result("UNION_STATIC_CHAR_SIZE", test_size, sizeof(struct1)); 240 | test_size = __builtin_object_size(u1.char_buf, TH_SIZE_CHECK_1); 241 | bosc_th_show_result("UNION_STATIC_CHAR_SIZE", test_size, 242 | STATIC_BUF_SIZE * 2); 243 | 244 | /* Size varying check within file */ 245 | test_size = static_bosc_th_test_flow_char(0); 246 | bosc_th_show_result("STATIC_FLOW_CHAR_FALSE", test_size, LARGER_BUF_SIZE); 247 | test_size = static_bosc_th_test_flow_char(1); 248 | bosc_th_show_result("STATIC_FLOW_CHAR_TRUE", test_size, STATIC_BUF_SIZE); 249 | } 250 | 251 | /* 252 | * A series of tests across object file boundaries 253 | */ 254 | void 255 | bosc_th_call_aux_fns (void) 256 | { 257 | int test_size; 258 | char char_buf[STATIC_BUF_SIZE]; 259 | struct1 s1; 260 | struct2 s2; 261 | 262 | /* Basic buffer size test across boundary */ 263 | test_size = bosc_th_test_aux_char(char_buf); 264 | bosc_th_show_result("STATIC_SIZE_CHAR_AUX", test_size, STATIC_BUF_SIZE); 265 | 266 | /* Size varying check across boundary */ 267 | test_size = bosc_th_test_aux_flow_char(0); 268 | bosc_th_show_result("FLOW_CHAR_AUX_FALSE", test_size, LARGER_BUF_SIZE); 269 | test_size = bosc_th_test_aux_flow_char(1); 270 | bosc_th_show_result("FLOW_CHAR_AUX_TRUE", test_size, STATIC_BUF_SIZE); 271 | 272 | /* Basic struct size test across boundary */ 273 | s2.s1ptr = &s1; 274 | test_size = bosc_th_test_aux_struct_ptr(&s2); 275 | bosc_th_show_result("STRUCT_PTR_STRUCT_CHAR_SIZE", test_size, 276 | STATIC_BUF_SIZE); 277 | } 278 | 279 | int 280 | main (int argc, char *argv[]) 281 | { 282 | bosc_th_run_tests(); 283 | return 0; 284 | } 285 | -------------------------------------------------------------------------------- /include/openosc_fortify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_FORTIFY_H__ 11 | #define __OPENOSC_FORTIFY_H__ 12 | 13 | /* The below macro is copied from include/features.h */ 14 | /* Convenience macro to test the version of gcc. 15 | Use like this: 16 | #if __GNUC_PREREQ (2,8) 17 | ... code requiring gcc 2.8 or later ... 18 | #endif 19 | Note: only works for GCC 2.0 and later, because __GNUC_MINOR__ was 20 | added in 2.0. */ 21 | #if defined __GNUC__ && defined __GNUC_MINOR__ 22 | # define __GNUC_PREREQ(maj, min) \ 23 | ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 24 | #else 25 | # define __GNUC_PREREQ(maj, min) 0 26 | #endif 27 | 28 | /* All the below macros are copied from misc/sys/cdefs.h */ 29 | #ifdef __GNUC__ 30 | 31 | /* All functions, except those with callbacks or those that 32 | synchronize memory, are leaf functions. */ 33 | # if __GNUC_PREREQ (4, 6) && !defined _LIBC 34 | # define __LEAF , __leaf__ 35 | # define __LEAF_ATTR __attribute__ ((__leaf__)) 36 | # else 37 | # define __LEAF 38 | # define __LEAF_ATTR 39 | # endif 40 | 41 | /* GCC can always grok prototypes. For C++ programs we add throw() 42 | to help it optimize the function calls. But this works only with 43 | gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions 44 | as non-throwing using a function attribute since programs can use 45 | the -fexceptions options for C code as well. */ 46 | # if !defined __cplusplus && __GNUC_PREREQ (3, 3) 47 | # define __THROW __attribute__ ((__nothrow__ __LEAF)) 48 | # define __THROWNL __attribute__ ((__nothrow__)) 49 | # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct 50 | # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct 51 | # else 52 | # if defined __cplusplus && __GNUC_PREREQ (2,8) 53 | # define __THROW throw () 54 | # define __THROWNL throw () 55 | # define __NTH(fct) __LEAF_ATTR fct throw () 56 | # define __NTHNL(fct) fct throw () 57 | # else 58 | # define __THROW 59 | # define __THROWNL 60 | # define __NTH(fct) fct 61 | # define __NTHNL(fct) fct 62 | # endif 63 | # endif 64 | 65 | #else /* Not GCC. */ 66 | 67 | # if (defined __cplusplus \ 68 | || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) 69 | # define __inline inline 70 | # else 71 | # define __inline /* No inline functions. */ 72 | # endif 73 | 74 | # define __THROW 75 | # define __THROWNL 76 | # define __NTH(fct) fct 77 | 78 | #endif /* GCC. */ 79 | 80 | #define __CONCAT(x,y) x ## y 81 | #define __STRING(x) #x 82 | 83 | #if __GNUC_PREREQ (4,3) 84 | # define __warndecl(name, msg) \ 85 | extern void name (void) __attribute__((__warning__ (msg))) 86 | # define __warnattr(msg) __attribute__((__warning__ (msg))) 87 | # define __errorattr(msg) __attribute__((__error__ (msg))) 88 | # define __errordecl(name, msg) \ 89 | extern void name (void) __attribute__((__error__ (msg))) 90 | #else 91 | # define __warndecl(name, msg) extern void name (void) 92 | # define __warnattr(msg) 93 | # define __errorattr(msg) 94 | # define __errordecl(name, msg) extern void name (void) 95 | #endif 96 | 97 | 98 | /* __asm__ ("xyz") is used throughout the headers to rename functions 99 | at the assembly language level. This is wrapped by the __REDIRECT 100 | macro, in order to support compilers that can do this some other 101 | way. When compilers don't support asm-names at all, we have to do 102 | preprocessor tricks instead (which don't have exactly the right 103 | semantics, but it's the best we can do). 104 | 105 | Example: 106 | int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */ 107 | 108 | #if defined __GNUC__ && __GNUC__ >= 2 109 | 110 | # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias)) 111 | # ifdef __cplusplus 112 | # define __REDIRECT_NTH(name, proto, alias) \ 113 | name proto __THROW __asm__ (__ASMNAME (#alias)) 114 | # define __REDIRECT_NTHNL(name, proto, alias) \ 115 | name proto __THROWNL __asm__ (__ASMNAME (#alias)) 116 | # else 117 | # define __REDIRECT_NTH(name, proto, alias) \ 118 | name proto __asm__ (__ASMNAME (#alias)) __THROW 119 | # define __REDIRECT_NTHNL(name, proto, alias) \ 120 | name proto __asm__ (__ASMNAME (#alias)) __THROWNL 121 | # endif 122 | # define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname) 123 | # define __ASMNAME2(prefix, cname) __STRING (prefix) cname 124 | 125 | /* 126 | #elif __SOME_OTHER_COMPILER__ 127 | 128 | # define __REDIRECT(name, proto, alias) name proto; \ 129 | _Pragma("let " #name " = " #alias) 130 | */ 131 | #endif 132 | 133 | /* The nonull function attribute allows to mark pointer parameters which 134 | must not be NULL. */ 135 | #if __GNUC_PREREQ (3,3) 136 | # define __nonnull(params) __attribute__ ((__nonnull__ params)) 137 | #else 138 | # define __nonnull(params) 139 | #endif 140 | 141 | /* If fortification mode, we warn about unused results of certain 142 | function calls which can lead to problems. */ 143 | #if __GNUC_PREREQ (3,4) 144 | # define __attribute_warn_unused_result__ \ 145 | __attribute__ ((__warn_unused_result__)) 146 | # if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 147 | # define __wur __attribute_warn_unused_result__ 148 | # endif 149 | #else 150 | # define __attribute_warn_unused_result__ /* empty */ 151 | #endif 152 | #ifndef __wur 153 | # define __wur /* Ignore */ 154 | #endif 155 | 156 | /* Forces a function to be always inlined. */ 157 | #if __GNUC_PREREQ (3,2) 158 | /* The Linux kernel defines __always_inline in stddef.h (283d7573), and 159 | it conflicts with this definition. Therefore undefine it first to 160 | allow either header to be included first. */ 161 | # undef __always_inline 162 | # define __always_inline __inline __attribute__ ((__always_inline__)) 163 | #else 164 | # undef __always_inline 165 | # define __always_inline __inline 166 | #endif 167 | 168 | /* Associate error messages with the source location of the call site rather 169 | than with the source location inside the function. */ 170 | #if __GNUC_PREREQ (4,3) 171 | # define __attribute_artificial__ __attribute__ ((__artificial__)) 172 | #else 173 | # define __attribute_artificial__ /* Ignore */ 174 | #endif 175 | 176 | /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 177 | inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__ 178 | or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions 179 | older than 4.3 may define these macros and still not guarantee GNU inlining 180 | semantics. 181 | 182 | clang++ identifies itself as gcc-4.2, but has support for GNU inlining 183 | semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and 184 | __GNUC_GNU_INLINE__ macro definitions. */ 185 | #if (!defined __cplusplus || __GNUC_PREREQ (4,3) \ 186 | || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \ 187 | || defined __GNUC_GNU_INLINE__))) 188 | # if defined __GNUC_STDC_INLINE__ || defined __cplusplus 189 | # define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) 190 | # define __extern_always_inline \ 191 | extern __always_inline __attribute__ ((__gnu_inline__)) 192 | # else 193 | # define __extern_inline extern __inline 194 | # define __extern_always_inline extern __always_inline 195 | # endif 196 | #endif 197 | 198 | #ifdef __extern_always_inline 199 | # define __fortify_function __extern_always_inline __attribute_artificial__ 200 | #endif 201 | 202 | /* GCC 4.3 and above allow passing all anonymous arguments of an 203 | __extern_always_inline function to some other vararg function. */ 204 | #if __GNUC_PREREQ (4,3) 205 | # define __va_arg_pack() __builtin_va_arg_pack () 206 | # define __va_arg_pack_len() __builtin_va_arg_pack_len () 207 | #endif 208 | 209 | 210 | /* Errors are reported at compile-time unless you disable it explicitly */ 211 | #ifndef OPENOSC_OVERFLOW_ERROR_OUT_DISABLE 212 | /* Do we want to error out at compile-time when detecting overflow/overread */ 213 | /* Also fow now, this flag only affects the ASM-redirect method */ 214 | #define OPENOSC_ERROR_OUT_ON_COMPILE_TIME_DETECTION_OVERFLOW 215 | #endif 216 | 217 | #define __dst_overflow_msg(func) func " caller with bigger length than size of destination buffer" 218 | #define __src_overread_msg(func) func " caller with bigger length than size of source buffer, will cause src overread" 219 | 220 | #define __OPENOSC_CLANG_CC 0 221 | 222 | /* For clang compiler support */ 223 | #if defined __clang__ 224 | 225 | #define __bos0(ptr) __builtin_object_size (ptr, 0) 226 | #define __bos1(ptr) __builtin_object_size (ptr, 1) 227 | #define __size_too_small(bos, dest, len) \ 228 | (bos (dest) != (size_t) -1 && bos (dest) != (size_t) 0 && bos (dest) < len) 229 | 230 | #define __always_enabled __attribute__ ((enable_if (1, ""))) 231 | #define __attribute_overloadable__ __attribute__((overloadable)) 232 | 233 | /* No support if clang version is less than 5.0 */ 234 | #if __clang_major__ < 5 235 | #define __clang_error_if(c, m) 236 | #define __clang_warning_if(c, m) 237 | #define __pass_objsize0 238 | #define __pass_objsize1 239 | #define __openosc_fortify_function __fortify_function 240 | #else 241 | #undef __OPENOSC_CLANG_CC 242 | #define __OPENOSC_CLANG_CC 1 243 | #define __clang_error_if(c, m) __attribute__ ((__diagnose_if__ ((c), (m), "error"))) 244 | #define __clang_warning_if(c, m) __attribute__ ((__diagnose_if__ ((c), (m), "warning"))) 245 | #define __pass_objsize0 const __attribute__((pass_object_size(0))) 246 | #define __pass_objsize1 const __attribute__((pass_object_size(1))) 247 | #define __openosc_fortify_function static __always_inline __attribute_artificial__ __always_enabled __attribute_overloadable__ 248 | #endif 249 | 250 | #ifdef _OPENOSC_EMIT_NOTHING_ON_COMPILE_TIME_DETECTION_OVERFLOW 251 | #define __warn_or_error_attr(m) 252 | #define __clang_warn_or_error_if(c, m) 253 | #else 254 | 255 | #if defined(OPENOSC_ERROR_OUT_ON_COMPILE_TIME_DETECTION_OVERFLOW) \ 256 | && __has_attribute(error) 257 | #define __warn_or_error_attr(m) __attribute__((__error__ (m))) 258 | #elif __has_attribute(warning) 259 | #define __warn_or_error_attr(m) __attribute__((__warning__ (m))) 260 | #else 261 | #define __warn_or_error_attr(m) 262 | #endif 263 | 264 | #ifdef OPENOSC_ERROR_OUT_ON_COMPILE_TIME_DETECTION_OVERFLOW 265 | #if __has_attribute(error) 266 | /* Avoid duplicate error message if function error attribute is available */ 267 | #define __clang_warn_or_error_if(c, m) 268 | #else 269 | #define __clang_warn_or_error_if(c, m) __clang_error_if(c, m) 270 | #endif 271 | #else 272 | #if __has_attribute(warning) 273 | /* Avoid duplicate warn message if function warning attribute is available */ 274 | #define __clang_warn_or_error_if(c, m) 275 | #else 276 | #define __clang_warn_or_error_if(c, m) __clang_warning_if(c, m) 277 | #endif 278 | #endif 279 | 280 | #endif /* _OPENOSC_EMIT_NOTHING_ON_COMPILE_TIME_DETECTION_OVERFLOW */ 281 | 282 | #else /* not clang compiler */ 283 | 284 | #define __pass_objsize0 285 | #define __pass_objsize1 286 | #define __openosc_fortify_function __fortify_function 287 | 288 | #define __clang_warn_or_error_if(c, m) 289 | #ifdef _OPENOSC_EMIT_NOTHING_ON_COMPILE_TIME_DETECTION_OVERFLOW 290 | #define __warn_or_error_attr(m) 291 | #else 292 | #ifdef OPENOSC_ERROR_OUT_ON_COMPILE_TIME_DETECTION_OVERFLOW 293 | #define __warn_or_error_attr(m) __errorattr(m) 294 | #else 295 | #define __warn_or_error_attr(m) __warnattr(m) 296 | #endif 297 | #endif 298 | 299 | #endif /* __clang__ */ 300 | 301 | #endif /* __OPENOSC_FORTIFY_H__ */ 302 | 303 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /include/openosc_safec_map_metric.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_SAFEC_MAP_METRIC_H__ 11 | #define __OPENOSC_SAFEC_MAP_METRIC_H__ 12 | 13 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 14 | 15 | #include "openosc_metric_objsize.h" 16 | 17 | #if (RTD_OSC_METRIC_METHOD == RTD_ASM_LOC_METHOD) 18 | 19 | #define MEMCMP_S_MAGIC1 ".loc 1 8390033" 20 | #define MEMCMP_S_MAGIC2 ".loc 1 8390034" 21 | #define MEMCMP_S_MAGIC3 ".loc 1 8390035" 22 | #define MEMCMP_S_MAGIC4 ".loc 1 8390036" 23 | 24 | #define MEMCPY_S_MAGIC1 ".loc 1 8390049" 25 | #define MEMCPY_S_MAGIC2 ".loc 1 8390050" 26 | #define MEMCPY_S_MAGIC3 ".loc 1 8390051" 27 | #define MEMCPY_S_MAGIC4 ".loc 1 8390052" 28 | 29 | #define STRCAT_S_MAGIC1 ".loc 1 8390065" 30 | #define STRCAT_S_MAGIC2 ".loc 1 8390066" 31 | #define STRCAT_S_MAGIC3 ".loc 1 8390067" 32 | #define STRCAT_S_MAGIC4 ".loc 1 8390068" 33 | 34 | #define STRCMP_S_MAGIC1 ".loc 1 8390081" 35 | #define STRCMP_S_MAGIC2 ".loc 1 8390082" 36 | #define STRCMP_S_MAGIC3 ".loc 1 8390083" 37 | #define STRCMP_S_MAGIC4 ".loc 1 8390084" 38 | 39 | #define STRCPY_S_MAGIC1 ".loc 1 8390097" 40 | #define STRCPY_S_MAGIC2 ".loc 1 8390098" 41 | #define STRCPY_S_MAGIC3 ".loc 1 8390099" 42 | #define STRCPY_S_MAGIC4 ".loc 1 8390100" 43 | 44 | #define STRNCAT_S_MAGIC1 ".loc 1 8390113" 45 | #define STRNCAT_S_MAGIC2 ".loc 1 8390114" 46 | #define STRNCAT_S_MAGIC3 ".loc 1 8390115" 47 | #define STRNCAT_S_MAGIC4 ".loc 1 8390116" 48 | #define STRNCAT_S_MAGIC_SAFECequal ".loc 1 8390117" 49 | #define STRNCAT_S_MAGIC_SAFECless ".loc 1 8390118" 50 | 51 | #define STRNCPY_S_MAGIC1 ".loc 1 8390129" 52 | #define STRNCPY_S_MAGIC2 ".loc 1 8390130" 53 | #define STRNCPY_S_MAGIC3 ".loc 1 8390131" 54 | #define STRNCPY_S_MAGIC4 ".loc 1 8390132" 55 | #define STRNCPY_S_MAGIC_SAFECequal ".loc 1 8390133" 56 | #define STRNCPY_S_MAGIC_SAFECless ".loc 1 8390134" 57 | 58 | #define STRNLEN_S_MAGIC1 ".loc 1 8390145" 59 | #define STRNLEN_S_MAGIC2 ".loc 1 8390146" 60 | #define STRNLEN_S_MAGIC3 ".loc 1 8390147" 61 | #define STRNLEN_S_MAGIC4 ".loc 1 8390148" 62 | 63 | #define STRSTR_S_MAGIC1 ".loc 1 8390161" 64 | #define STRSTR_S_MAGIC2 ".loc 1 8390162" 65 | #define STRSTR_S_MAGIC3 ".loc 1 8390163" 66 | #define STRSTR_S_MAGIC4 ".loc 1 8390164" 67 | 68 | #elif (RTD_OSC_METRIC_METHOD == RTD_ASM_BYTE_METHOD) 69 | 70 | #define MEMCMP_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x88, 0x11\n" OSC_JUMPLABEL 71 | #define MEMCMP_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x88, 0x22\n" OSC_JUMPLABEL 72 | #define MEMCMP_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x88, 0x33\n" OSC_JUMPLABEL 73 | #define MEMCMP_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x88, 0x44\n" OSC_JUMPLABEL 74 | 75 | #define MEMCPY_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x00, 0x11\n" OSC_JUMPLABEL 76 | #define MEMCPY_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x00, 0x22\n" OSC_JUMPLABEL 77 | #define MEMCPY_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x00, 0x33\n" OSC_JUMPLABEL 78 | #define MEMCPY_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x00, 0x44\n" OSC_JUMPLABEL 79 | 80 | #define STRCAT_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x11, 0x11\n" OSC_JUMPLABEL 81 | #define STRCAT_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x11, 0x22\n" OSC_JUMPLABEL 82 | #define STRCAT_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x11, 0x33\n" OSC_JUMPLABEL 83 | #define STRCAT_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x11, 0x44\n" OSC_JUMPLABEL 84 | 85 | #define STRCMP_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x22, 0x11\n" OSC_JUMPLABEL 86 | #define STRCMP_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x22, 0x22\n" OSC_JUMPLABEL 87 | #define STRCMP_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x22, 0x33\n" OSC_JUMPLABEL 88 | #define STRCMP_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x22, 0x44\n" OSC_JUMPLABEL 89 | 90 | #define STRCPY_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x33, 0x11\n" OSC_JUMPLABEL 91 | #define STRCPY_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x33, 0x22\n" OSC_JUMPLABEL 92 | #define STRCPY_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x33, 0x33\n" OSC_JUMPLABEL 93 | #define STRCPY_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x33, 0x44\n" OSC_JUMPLABEL 94 | 95 | #define STRNCAT_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x44, 0x11\n" OSC_JUMPLABEL 96 | #define STRNCAT_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x44, 0x22\n" OSC_JUMPLABEL 97 | #define STRNCAT_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x44, 0x33\n" OSC_JUMPLABEL 98 | #define STRNCAT_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x44, 0x44\n" OSC_JUMPLABEL 99 | #define STRNCAT_S_MAGIC_SAFECequal OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x44, 0x45\n" OSC_JUMPLABEL 100 | #define STRNCAT_S_MAGIC_SAFECless OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x44, 0x46\n" OSC_JUMPLABEL 101 | 102 | #define STRNCPY_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x55, 0x11\n" OSC_JUMPLABEL 103 | #define STRNCPY_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x55, 0x22\n" OSC_JUMPLABEL 104 | #define STRNCPY_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x55, 0x33\n" OSC_JUMPLABEL 105 | #define STRNCPY_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x55, 0x44\n" OSC_JUMPLABEL 106 | #define STRNCPY_S_MAGIC_SAFECequal OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x55, 0x45\n" OSC_JUMPLABEL 107 | #define STRNCPY_S_MAGIC_SAFECless OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x55, 0x46\n" OSC_JUMPLABEL 108 | 109 | #define STRNLEN_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x66, 0x11\n" OSC_JUMPLABEL 110 | #define STRNLEN_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x66, 0x22\n" OSC_JUMPLABEL 111 | #define STRNLEN_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x66, 0x33\n" OSC_JUMPLABEL 112 | #define STRNLEN_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x66, 0x44\n" OSC_JUMPLABEL 113 | 114 | #define STRSTR_S_MAGIC1 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x77, 0x11\n" OSC_JUMPLABEL 115 | #define STRSTR_S_MAGIC2 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x77, 0x22\n" OSC_JUMPLABEL 116 | #define STRSTR_S_MAGIC3 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x77, 0x33\n" OSC_JUMPLABEL 117 | #define STRSTR_S_MAGIC4 OSC_JUMPOVER ".byte 0x4d, 0x41, 0x47, 0x49, 0x43, 0xd1, 0x77, 0x44\n" OSC_JUMPLABEL 118 | 119 | #endif 120 | 121 | #define MEMCMP_S_CASE1 ({__asm__(MEMCMP_S_MAGIC1);}), OSC_DSTSIZE(_sz) 122 | #define MEMCMP_S_CASE2 ({__asm__(MEMCMP_S_MAGIC2);}), OSC_DSTSIZE(_sz) 123 | #define MEMCMP_S_CASE3 ({__asm__(MEMCMP_S_MAGIC3);}), OSC_DSTSIZE(_sz) 124 | #define MEMCMP_S_CASE4 ({__asm__(MEMCMP_S_MAGIC4);}), OSC_DSTSIZE(_sz) 125 | #define MEMCPY_S_CASE1 ({__asm__(MEMCPY_S_MAGIC1);}), OSC_DSTSIZE(_sz) 126 | #define MEMCPY_S_CASE2 ({__asm__(MEMCPY_S_MAGIC2);}), OSC_DSTSIZE(_sz) 127 | #define MEMCPY_S_CASE3 ({__asm__(MEMCPY_S_MAGIC3);}), OSC_DSTSIZE(_sz) 128 | #define MEMCPY_S_CASE4 ({__asm__(MEMCPY_S_MAGIC4);}), OSC_DSTSIZE(_sz) 129 | #define STRCAT_S_CASE1 ({__asm__(STRCAT_S_MAGIC1);}), OSC_DSTSIZE(_sz) 130 | #define STRCAT_S_CASE2 ({__asm__(STRCAT_S_MAGIC2);}), OSC_DSTSIZE(_sz) 131 | #define STRCAT_S_CASE3 ({__asm__(STRCAT_S_MAGIC3);}), OSC_DSTSIZE(_sz) 132 | #define STRCAT_S_CASE4 ({__asm__(STRCAT_S_MAGIC4);}), OSC_DSTSIZE(_sz) 133 | #define STRCMP_S_CASE1 ({__asm__(STRCMP_S_MAGIC1);}), OSC_DSTSIZE(_sz) 134 | #define STRCMP_S_CASE2 ({__asm__(STRCMP_S_MAGIC2);}), OSC_DSTSIZE(_sz) 135 | #define STRCMP_S_CASE3 ({__asm__(STRCMP_S_MAGIC3);}), OSC_DSTSIZE(_sz) 136 | #define STRCMP_S_CASE4 ({__asm__(STRCMP_S_MAGIC4);}), OSC_DSTSIZE(_sz) 137 | #define STRCPY_S_CASE1 ({__asm__(STRCPY_S_MAGIC1);}), OSC_DSTSIZE(_sz) 138 | #define STRCPY_S_CASE2 ({__asm__(STRCPY_S_MAGIC2);}), OSC_DSTSIZE(_sz) 139 | #define STRCPY_S_CASE3 ({__asm__(STRCPY_S_MAGIC3);}), OSC_DSTSIZE(_sz) 140 | #define STRCPY_S_CASE4 ({__asm__(STRCPY_S_MAGIC4);}), OSC_DSTSIZE(_sz) 141 | #define STRNCAT_S_CASE1 ({__asm__(STRNCAT_S_MAGIC1);}), OSC_DSTSIZE(_sz) 142 | #define STRNCAT_S_CASE2 ({__asm__(STRNCAT_S_MAGIC2);}), OSC_DSTSIZE(_sz) 143 | #define STRNCAT_S_CASE3 ({__asm__(STRNCAT_S_MAGIC3);}), OSC_DSTSIZE(_sz) 144 | #define STRNCAT_S_CASE4 ({__asm__(STRNCAT_S_MAGIC4);}), OSC_DSTSIZE(_sz) 145 | #define STRNCAT_S_CASE_SAFECequal ({__asm__(STRNCAT_S_MAGIC_SAFECequal);}), OSC_DSTSIZE(_sz) 146 | #define STRNCAT_S_CASE_SAFECless ({__asm__(STRNCAT_S_MAGIC_SAFECless);}), OSC_DSTSIZE(_sz) 147 | #define STRNCPY_S_CASE1 ({__asm__(STRNCPY_S_MAGIC1);}), OSC_DSTSIZE(_sz) 148 | #define STRNCPY_S_CASE2 ({__asm__(STRNCPY_S_MAGIC2);}), OSC_DSTSIZE(_sz) 149 | #define STRNCPY_S_CASE3 ({__asm__(STRNCPY_S_MAGIC3);}), OSC_DSTSIZE(_sz) 150 | #define STRNCPY_S_CASE4 ({__asm__(STRNCPY_S_MAGIC4);}), OSC_DSTSIZE(_sz) 151 | #define STRNCPY_S_CASE_SAFECequal ({__asm__(STRNCPY_S_MAGIC_SAFECequal);}), OSC_DSTSIZE(_sz) 152 | #define STRNCPY_S_CASE_SAFECless ({__asm__(STRNCPY_S_MAGIC_SAFECless);}), OSC_DSTSIZE(_sz) 153 | #define STRNLEN_S_CASE1 ({__asm__(STRNLEN_S_MAGIC1);}), OSC_DSTSIZE(_sz) 154 | #define STRNLEN_S_CASE2 ({__asm__(STRNLEN_S_MAGIC2);}), OSC_DSTSIZE(_sz) 155 | #define STRNLEN_S_CASE3 ({__asm__(STRNLEN_S_MAGIC3);}), OSC_DSTSIZE(_sz) 156 | #define STRNLEN_S_CASE4 ({__asm__(STRNLEN_S_MAGIC4);}), OSC_DSTSIZE(_sz) 157 | #define STRSTR_S_CASE1 ({__asm__(STRSTR_S_MAGIC1);}), OSC_DSTSIZE(_sz) 158 | #define STRSTR_S_CASE2 ({__asm__(STRSTR_S_MAGIC2);}), OSC_DSTSIZE(_sz) 159 | #define STRSTR_S_CASE3 ({__asm__(STRSTR_S_MAGIC3);}), OSC_DSTSIZE(_sz) 160 | #define STRSTR_S_CASE4 ({__asm__(STRSTR_S_MAGIC4);}), OSC_DSTSIZE(_sz) 161 | 162 | #else /* OPENOSC_METRIC_FEATURE_ENABLED */ 163 | 164 | #define MEMCMP_S_CASE1 165 | #define MEMCMP_S_CASE2 166 | #define MEMCMP_S_CASE3 167 | #define MEMCMP_S_CASE4 168 | #define MEMCPY_S_CASE1 169 | #define MEMCPY_S_CASE2 170 | #define MEMCPY_S_CASE3 171 | #define MEMCPY_S_CASE4 172 | #define STRCAT_S_CASE1 173 | #define STRCAT_S_CASE2 174 | #define STRCAT_S_CASE3 175 | #define STRCAT_S_CASE4 176 | #define STRCMP_S_CASE1 177 | #define STRCMP_S_CASE2 178 | #define STRCMP_S_CASE3 179 | #define STRCMP_S_CASE4 180 | #define STRCPY_S_CASE1 181 | #define STRCPY_S_CASE2 182 | #define STRCPY_S_CASE3 183 | #define STRCPY_S_CASE4 184 | #define STRNCAT_S_CASE1 185 | #define STRNCAT_S_CASE2 186 | #define STRNCAT_S_CASE3 187 | #define STRNCAT_S_CASE4 188 | #define STRNCAT_S_CASE_SAFECequal 189 | #define STRNCAT_S_CASE_SAFECless 190 | #define STRNCPY_S_CASE1 191 | #define STRNCPY_S_CASE2 192 | #define STRNCPY_S_CASE3 193 | #define STRNCPY_S_CASE4 194 | #define STRNCPY_S_CASE_SAFECequal 195 | #define STRNCPY_S_CASE_SAFECless 196 | #define STRNLEN_S_CASE1 197 | #define STRNLEN_S_CASE2 198 | #define STRNLEN_S_CASE3 199 | #define STRNLEN_S_CASE4 200 | #define STRSTR_S_CASE1 201 | #define STRSTR_S_CASE2 202 | #define STRSTR_S_CASE3 203 | #define STRSTR_S_CASE4 204 | 205 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 206 | 207 | #endif /* __OPENOSC_SAFEC_MAP_METRIC_H__ */ 208 | -------------------------------------------------------------------------------- /include/openosc_metric_only.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Cisco Systems, Inc. 3 | * 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/cisco/openosc/LICENSE 8 | */ 9 | 10 | #ifndef __OPENOSC_METRIC_ONLY_H__ 11 | #define __OPENOSC_METRIC_ONLY_H__ 12 | 13 | /* if OSC metric feature is disabled, we can completely exclude this header */ 14 | #ifdef OPENOSC_METRIC_FEATURE_ENABLED 15 | 16 | #if !defined __OPTIMIZE__ 17 | #ifndef OPENOSC_NOMAP_METRIC_ONLY 18 | #define OPENOSC_NOMAP_METRIC_ONLY 19 | #endif 20 | #endif 21 | 22 | #ifdef _FORTIFY_SOURCE 23 | #if defined __clang__ 24 | #warning "The OSC-METRICS feature suppresses fortify-source buffer-overflow warnings for clang" 25 | #else 26 | #warning "The OSC-METRICS feature suppresses some function-attribute warnings, like -Wunused-result/-Wnonnull" 27 | #endif 28 | #endif 29 | 30 | 31 | #ifdef __cplusplus 32 | #include 33 | extern "C" 34 | { 35 | #endif 36 | 37 | 38 | #include "openosc_extern.h" 39 | #include "openosc_fortify.h" 40 | 41 | #include "openosc_nomap_metric.h" 42 | #include "openosc_map_metric.h" 43 | 44 | #ifndef OPENOSC_NOT_GNU_SOURCE 45 | /* by default, extra GNU functions are supported */ 46 | #ifndef _GNU_SOURCE 47 | #define _GNU_SOURCE 48 | #endif 49 | #endif 50 | 51 | #ifndef OPENOSC_DISABLE_STRING_H_FUNCS 52 | #include "string.h" 53 | #endif /* OPENOSC_DISABLE_STRING_H_FUNCS */ 54 | 55 | 56 | #ifndef OPENOSC_DISABLE_STRING_H_FUNCS 57 | 58 | /* Mapping for memcpy */ 59 | 60 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 61 | 62 | static inline __attribute__ ((always_inline)) void * 63 | openosc_memcpy (void *dst, const void *src, size_t len) 64 | OSC_THROW 65 | { 66 | return (MEMCPY_NOMAP_CASE memcpy(dst, src, len)); 67 | } 68 | 69 | #else 70 | 71 | static inline __attribute__ ((always_inline)) void * 72 | openosc_memcpy (void *dst, const void *src, size_t len) 73 | OSC_THROW 74 | { 75 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); 76 | size_t _src_sz = __builtin_object_size(src, OSC_OBJECT_SIZE_CHECK_0); 77 | int is_len_constant = __builtin_constant_p(len); 78 | #ifdef _OPENOSC_SRC_OVERREAD_ENABLED 79 | return ((_sz != (size_t) -1) 80 | ? (is_len_constant 81 | ? ((_sz >= len) 82 | ? ((_src_sz != (size_t) -1) 83 | ? ((_src_sz >= len) 84 | ? (MEMCPY_CASE7 memcpy(dst, src, len)) 85 | : (MEMCPY_CASE8 memcpy(dst, src, len))) 86 | : (MEMCPY_CASE1 memcpy(dst, src, len))) 87 | : (MEMCPY_CASE2 memcpy(dst, src, len))) 88 | : (MEMCPY_CASE3 memcpy(dst, src, len))) 89 | : ((_src_sz != (size_t) -1) 90 | ? (is_len_constant 91 | ? ((_src_sz >= len) 92 | ? (MEMCPY_CASEa memcpy(dst, src, len)) 93 | : (MEMCPY_CASEb memcpy(dst, src, len))) 94 | : (MEMCPY_CASE9 memcpy(dst, src, len))) 95 | : (MEMCPY_CASE4 memcpy(dst, src, len)))); 96 | #else 97 | return ((_sz != (size_t) -1) 98 | ? (is_len_constant 99 | ? ((_sz >= len) 100 | ? (MEMCPY_CASE1 memcpy(dst, src, len)) 101 | : (MEMCPY_CASE2 memcpy(dst, src, len))) 102 | : (MEMCPY_CASE3 memcpy(dst, src, len))) 103 | : (MEMCPY_CASE4 memcpy(dst, src, len))); 104 | #endif 105 | } 106 | #endif 107 | 108 | #undef memcpy 109 | #define memcpy(dest, src, len) \ 110 | openosc_memcpy(dest, src, len) 111 | 112 | 113 | /* Mapping for memmove */ 114 | 115 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 116 | 117 | static inline __attribute__ ((always_inline)) void * 118 | openosc_memmove (void *dst, const void *src, size_t len) 119 | OSC_THROW 120 | { 121 | return (MEMMOVE_NOMAP_CASE memmove(dst, src, len)); 122 | } 123 | 124 | #else 125 | 126 | static inline __attribute__ ((always_inline)) void * 127 | openosc_memmove (void *dst, const void *src, size_t len) 128 | OSC_THROW 129 | { 130 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); 131 | size_t _src_sz = __builtin_object_size(src, OSC_OBJECT_SIZE_CHECK_0); 132 | int is_len_constant = __builtin_constant_p(len); 133 | #ifdef _OPENOSC_SRC_OVERREAD_ENABLED 134 | return ((_sz != (size_t) -1) 135 | ? (is_len_constant 136 | ? ((_sz >= len) 137 | ? ((_src_sz != (size_t) -1) 138 | ? ((_src_sz >= len) 139 | ? (MEMMOVE_CASE7 memmove(dst, src, len)) 140 | : (MEMMOVE_CASE8 memmove(dst, src, len))) 141 | : (MEMMOVE_CASE1 memmove(dst, src, len))) 142 | : (MEMMOVE_CASE2 memmove(dst, src, len))) 143 | : (MEMMOVE_CASE3 memmove(dst, src, len))) 144 | : ((_src_sz != (size_t) -1) 145 | ? (is_len_constant 146 | ? ((_src_sz >= len) 147 | ? (MEMMOVE_CASEa memmove(dst, src, len)) 148 | : (MEMMOVE_CASEb memmove(dst, src, len))) 149 | : (MEMMOVE_CASE9 memmove(dst, src, len))) 150 | : (MEMMOVE_CASE4 memmove(dst, src, len)))); 151 | #else 152 | return ((_sz != (size_t) -1) 153 | ? (is_len_constant 154 | ? ((_sz >= len) 155 | ? (MEMMOVE_CASE1 memmove(dst, src, len)) 156 | : (MEMMOVE_CASE2 memmove(dst, src, len))) 157 | : (MEMMOVE_CASE3 memmove(dst, src, len))) 158 | : (MEMMOVE_CASE4 memmove(dst, src, len))); 159 | #endif 160 | } 161 | #endif 162 | 163 | #undef memmove 164 | #define memmove(dest, src, len) \ 165 | openosc_memmove(dest, src, len) 166 | 167 | /* Mapping for memset */ 168 | 169 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 170 | 171 | static inline __attribute__ ((always_inline)) void * 172 | openosc_memset (void *dst, int c, size_t len) 173 | OSC_THROW 174 | { 175 | return (MEMSET_NOMAP_CASE memset(dst, c, len)); 176 | } 177 | 178 | #else 179 | 180 | static inline __attribute__ ((always_inline)) void * 181 | openosc_memset (void *dst, int c, size_t len) 182 | OSC_THROW 183 | { 184 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); 185 | int is_len_constant = __builtin_constant_p(len); 186 | return ((_sz != (size_t) -1) 187 | ? (is_len_constant 188 | ? ((_sz >= len) 189 | ? (MEMSET_CASE1 memset(dst, c, len)) 190 | : (MEMSET_CASE2 memset(dst, c, len))) 191 | : (MEMSET_CASE3 memset(dst, c, len))) 192 | : (MEMSET_CASE4 memset(dst, c, len))); 193 | } 194 | #endif 195 | 196 | #undef memset 197 | #define memset(dst, c, len) \ 198 | openosc_memset(dst, c, len) 199 | 200 | 201 | /* Mapping for bcopy */ 202 | 203 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 204 | 205 | static inline __attribute__ ((always_inline)) void 206 | openosc_bcopy (const void *src, void *dst, size_t len) 207 | OSC_THROW 208 | { 209 | return (BCOPY_NOMAP_CASE bcopy(src, dst, len)); 210 | } 211 | 212 | #else 213 | 214 | static inline __attribute__ ((always_inline)) void 215 | openosc_bcopy (const void *src, void *dst, size_t len) 216 | OSC_THROW 217 | { 218 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); 219 | size_t _src_sz = __builtin_object_size(src, OSC_OBJECT_SIZE_CHECK_0); 220 | int is_len_constant = __builtin_constant_p(len); 221 | #ifdef _OPENOSC_SRC_OVERREAD_ENABLED 222 | ((_sz != (size_t) -1) 223 | ? (is_len_constant 224 | ? ((_sz >= len) 225 | ? ((_src_sz != (size_t) -1) 226 | ? ((_src_sz >= len) 227 | ? (BCOPY_CASE7 bcopy(src, dst, len)) 228 | : (BCOPY_CASE8 bcopy(src, dst, len))) 229 | : (BCOPY_CASE1 bcopy(src, dst, len))) 230 | : (BCOPY_CASE2 bcopy(src, dst, len))) 231 | : (BCOPY_CASE3 bcopy(src, dst, len))) 232 | : ((_src_sz != (size_t) -1) 233 | ? (is_len_constant 234 | ? ((_src_sz >= len) 235 | ? (BCOPY_CASEa bcopy(src, dst, len)) 236 | : (BCOPY_CASEb bcopy(src, dst, len))) 237 | : (BCOPY_CASE9 bcopy(src, dst, len))) 238 | : (BCOPY_CASE4 bcopy(src, dst, len)))); 239 | #else 240 | ((_sz != (size_t) -1) 241 | ? (is_len_constant 242 | ? ((_sz >= len) 243 | ? (BCOPY_CASE1 bcopy(src, dst, len)) 244 | : (BCOPY_CASE2 bcopy(src, dst, len))) 245 | : (BCOPY_CASE3 bcopy(src, dst, len))) 246 | : (BCOPY_CASE4 bcopy(src, dst, len))); 247 | #endif 248 | } 249 | #endif 250 | 251 | #undef bcopy 252 | #define bcopy(src, dst, len) \ 253 | openosc_bcopy(src, dst, len) 254 | 255 | /* Mapping for bzero */ 256 | 257 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 258 | 259 | static inline __attribute__ ((always_inline)) void 260 | openosc_bzero (void *dst, size_t len) 261 | OSC_THROW 262 | { 263 | return (BZERO_NOMAP_CASE bzero(dst, len)); 264 | } 265 | 266 | #else 267 | 268 | static inline __attribute__ ((always_inline)) void 269 | openosc_bzero (void *dst, size_t len) 270 | OSC_THROW 271 | { 272 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_0); 273 | int is_len_constant = __builtin_constant_p(len); 274 | ((_sz != (size_t) -1) 275 | ? (is_len_constant 276 | ? ((_sz >= len) 277 | ? (BZERO_CASE1 bzero(dst, len)) 278 | : (BZERO_CASE2 bzero(dst, len))) 279 | : (BZERO_CASE3 bzero(dst, len))) 280 | : (BZERO_CASE4 bzero(dst, len))); 281 | } 282 | #endif 283 | 284 | #undef bzero 285 | #define bzero(dst, len) \ 286 | openosc_bzero(dst, len) 287 | 288 | 289 | /* Mapping for strcpy */ 290 | 291 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 292 | 293 | static inline __attribute__ ((always_inline)) char * 294 | openosc_strcpy (char *dst, const char *src) 295 | OSC_THROW 296 | { 297 | return (STRCPY_NOMAP_CASE strcpy(dst, src)); 298 | } 299 | 300 | #else 301 | 302 | static inline __attribute__ ((always_inline)) char * 303 | openosc_strcpy (char *dst, const char *src) 304 | OSC_THROW 305 | { 306 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); 307 | int is_len_constant = __builtin_constant_p(strlen(src)); 308 | return ((_sz != (size_t) -1) 309 | ? (is_len_constant 310 | ? ((_sz > strlen(src)) 311 | ? (STRCPY_CASE1 strcpy(dst, src)) 312 | : (STRCPY_CASE2 strcpy(dst, src))) 313 | : (STRCPY_CASE3 strcpy(dst, src))) 314 | : (STRCPY_CASE4 strcpy(dst, src))); 315 | } 316 | #endif 317 | 318 | #undef strcpy 319 | #define strcpy(dst, src) \ 320 | openosc_strcpy(dst, src) 321 | 322 | 323 | /* Mapping for strncpy */ 324 | 325 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 326 | 327 | static inline __attribute__ ((always_inline)) char * 328 | openosc_strncpy (char *dst, const char *src, size_t len) 329 | OSC_THROW 330 | { 331 | return (STRNCPY_NOMAP_CASE strncpy(dst, src, len)); 332 | } 333 | 334 | #else 335 | 336 | static inline __attribute__ ((always_inline)) char * 337 | openosc_strncpy (char *dst, const char *src, size_t len) 338 | OSC_THROW 339 | { 340 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); 341 | int is_len_constant = __builtin_constant_p(len); 342 | return ((_sz != (size_t) -1) 343 | ? (is_len_constant 344 | ? ((_sz >= len) 345 | ? (STRNCPY_CASE1 strncpy(dst, src, len)) 346 | : (STRNCPY_CASE2 strncpy(dst, src, len))) 347 | : (STRNCPY_CASE3 strncpy(dst, src, len))) 348 | : (STRNCPY_CASE4 strncpy(dst, src, len))); 349 | } 350 | #endif 351 | 352 | #undef strncpy 353 | #define strncpy(dest, src, len) \ 354 | openosc_strncpy(dest, src, len) 355 | 356 | /* Mapping for strcat */ 357 | 358 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 359 | 360 | static inline __attribute__ ((always_inline)) char * 361 | openosc_strcat (char *dst, const char *src) 362 | OSC_THROW 363 | { 364 | return (STRCAT_NOMAP_CASE strcat(dst, src)); 365 | } 366 | 367 | #else 368 | 369 | static inline __attribute__ ((always_inline)) char * 370 | openosc_strcat (char *dst, const char *src) 371 | OSC_THROW 372 | { 373 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); 374 | int is_len_constant = __builtin_constant_p(strlen(src)); 375 | return ((_sz != (size_t) -1) 376 | ? (is_len_constant 377 | ? ((_sz > strlen(src)) 378 | ? (STRCAT_CASE1 strcat(dst, src)) 379 | : (STRCAT_CASE2 strcat(dst, src))) 380 | : (STRCAT_CASE3 strcat(dst, src))) 381 | : (STRCAT_CASE4 strcat(dst, src))); 382 | } 383 | #endif 384 | 385 | #undef strcat 386 | #define strcat(dst, src) \ 387 | openosc_strcat(dst, src) 388 | 389 | /* Mapping for strncat */ 390 | 391 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 392 | 393 | static inline __attribute__ ((always_inline)) char * 394 | openosc_strncat (char *dst, const char *src, size_t len) 395 | OSC_THROW 396 | { 397 | return (STRNCAT_NOMAP_CASE strncat(dst, src, len)); 398 | } 399 | 400 | #else 401 | 402 | static inline __attribute__ ((always_inline)) char * 403 | openosc_strncat (char *dst, const char *src, size_t len) 404 | OSC_THROW 405 | { 406 | size_t _sz = __builtin_object_size(dst, OSC_OBJECT_SIZE_CHECK_1); 407 | int is_len_constant = __builtin_constant_p(len); 408 | return ((_sz != (size_t) -1) 409 | ? (is_len_constant 410 | ? ((_sz > len) 411 | ? (STRNCAT_CASE1 strncat(dst, src, len)) 412 | : (STRNCAT_CASE2 strncat(dst, src, len))) 413 | : (STRNCAT_CASE3 strncat(dst, src, len))) 414 | : (STRNCAT_CASE4 strncat(dst, src, len))); 415 | } 416 | #endif 417 | 418 | #undef strncat 419 | #define strncat(dst, src, len) \ 420 | openosc_strncat(dst, src, len) 421 | 422 | /* Mapping for strnlen */ 423 | 424 | #ifdef OPENOSC_NOMAP_METRIC_ONLY 425 | 426 | static inline __attribute__ ((always_inline)) size_t 427 | openosc_strnlen (const char *s, size_t maxlen) 428 | OSC_THROW 429 | { 430 | return (STRNLEN_NOMAP_CASE strnlen(s, maxlen)); 431 | } 432 | 433 | #else 434 | 435 | static inline __attribute__ ((always_inline)) size_t 436 | openosc_strnlen (const char *s, size_t len) 437 | OSC_THROW 438 | { 439 | size_t _sz = __builtin_object_size(s, OSC_OBJECT_SIZE_CHECK_1); 440 | int is_len_constant = __builtin_constant_p(len); 441 | return ((_sz != (size_t) -1) 442 | ? (is_len_constant 443 | ? ((_sz >= len) 444 | ? (STRNLEN_CASE1 strnlen(s, len)) 445 | : (STRNLEN_CASE2 strnlen(s, len))) 446 | : (STRNLEN_CASE3 strnlen(s, len))) 447 | : (STRNLEN_CASE4 strnlen(s, len))); 448 | } 449 | #endif 450 | 451 | #undef strnlen 452 | #define strnlen(s, maxlen) \ 453 | openosc_strnlen(s, maxlen) 454 | 455 | #endif /* OPENOSC_DISABLE_STRING_H_FUNCS */ 456 | 457 | #ifdef HAS_SAFEC 458 | #include "openosc_safec_nomap.h" 459 | #endif 460 | 461 | #ifndef OPENOSC_FORTIFY_FUNCTIONS_DISABLE 462 | #include "openosc_metric_only2.h" 463 | #endif 464 | 465 | #ifdef __cplusplus 466 | } 467 | #endif 468 | 469 | #endif /* OPENOSC_METRIC_FEATURE_ENABLED */ 470 | 471 | #endif /* __OPENOSC_METRIC_ONLY_H__ */ 472 | 473 | --------------------------------------------------------------------------------