fortify-headers

standalone fortify-source implementation
git clone git://git.2f30.org/fortify-headers.git
Log | Files | Refs | README | LICENSE

string.h (4475B)


      1 /*
      2  * Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
      3  *
      4  * Permission to use, copy, modify, and/or distribute this software for any
      5  * purpose with or without fee is hereby granted.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     10  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     12  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     13  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     14  */
     15 
     16 #ifndef _FORTIFY_STRING_H
     17 #define _FORTIFY_STRING_H
     18 
     19 #ifndef __cplusplus
     20 __extension__
     21 #endif
     22 #include_next <string.h>
     23 
     24 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
     25 #include "fortify-headers.h"
     26 
     27 #ifdef __cplusplus
     28 extern "C" {
     29 #endif
     30 
     31 #undef memcpy
     32 #undef memmove
     33 #undef memset
     34 #undef strcat
     35 #undef strcpy
     36 #undef strncat
     37 #undef strncpy
     38 
     39 _FORTIFY_FN(memcpy) void *memcpy(void *__od, const void *__os, size_t __n)
     40 {
     41 	size_t __bd = __builtin_object_size(__od, 0);
     42 	size_t __bs = __builtin_object_size(__os, 0);
     43 	char *__d = (char *)__od;
     44 	const char *__s = (const char *)__os;
     45 
     46 	/* trap if pointers are overlapping but not if dst == src.
     47 	 * gcc seems to like to generate code that relies on dst == src */
     48 	if ((__d < __s && __d + __n > __s) ||
     49 	    (__s < __d && __s + __n > __d))
     50 		__builtin_trap();
     51 	if (__n > __bd || __n > __bs)
     52 		__builtin_trap();
     53 	return __builtin_memcpy(__od, __os, __n);
     54 }
     55 
     56 _FORTIFY_FN(memmove) void *memmove(void *__d, const void *__s, size_t __n)
     57 {
     58 	size_t __bd = __builtin_object_size(__d, 0);
     59 	size_t __bs = __builtin_object_size(__s, 0);
     60 
     61 	if (__n > __bd || __n > __bs)
     62 		__builtin_trap();
     63 	return __orig_memmove(__d, __s, __n);
     64 }
     65 
     66 _FORTIFY_FN(memset) void *memset(void *__d, int __c, size_t __n)
     67 {
     68 	size_t __b = __builtin_object_size(__d, 0);
     69 
     70 	if (__n > __b)
     71 		__builtin_trap();
     72 	return __builtin_memset(__d, __c, __n);
     73 }
     74 
     75 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
     76  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
     77  || defined(_BSD_SOURCE)
     78 #undef stpcpy
     79 _FORTIFY_FN(stpcpy) char *stpcpy(char *__d, const char *__s)
     80 {
     81 	size_t __b = __builtin_object_size(__d, 0);
     82 
     83 	if (strlen(__s) + 1 > __b)
     84 		__builtin_trap();
     85 	return __orig_stpcpy(__d, __s);
     86 }
     87 
     88 #undef stpncpy
     89 _FORTIFY_FN(stpncpy) char *stpncpy(char *__d, const char *__s, size_t __n)
     90 {
     91 	size_t __b = __builtin_object_size(__d, 0);
     92 
     93 	if (__n > __b && strlen(__s) + 1 > __b)
     94 		__builtin_trap();
     95 	return __orig_stpncpy(__d, __s, __n);
     96 }
     97 #endif
     98 
     99 _FORTIFY_FN(strcat) char *strcat(char *__d, const char *__s)
    100 {
    101 	size_t __b = __builtin_object_size(__d, 0);
    102 
    103 	if (strlen(__s) + strlen(__d) + 1 > __b)
    104 		__builtin_trap();
    105 	return __orig_strcat(__d, __s);
    106 }
    107 
    108 _FORTIFY_FN(strcpy) char *strcpy(char *__d, const char *__s)
    109 {
    110 	size_t __b = __builtin_object_size(__d, 0);
    111 
    112 	if (strlen(__s) + 1 > __b)
    113 		__builtin_trap();
    114 	return __orig_strcpy(__d, __s);
    115 }
    116 
    117 _FORTIFY_FN(strncat) char *strncat(char *__d, const char *__s, size_t __n)
    118 {
    119 	size_t __b = __builtin_object_size(__d, 0);
    120 	size_t __sl, __dl;
    121 
    122 	if (__n > __b) {
    123 		__sl = strlen(__s);
    124 		__dl = strlen(__d);
    125 		if (__sl > __n)
    126 			__sl = __n;
    127 		if (__sl + __dl + 1 > __b)
    128 			__builtin_trap();
    129 	}
    130 	return __orig_strncat(__d, __s, __n);
    131 }
    132 
    133 _FORTIFY_FN(strncpy) char *strncpy(char *__d, const char *__s, size_t __n)
    134 {
    135 	size_t __b = __builtin_object_size(__d, 0);
    136 
    137 	if (__n > __b)
    138 		__builtin_trap();
    139 	return __orig_strncpy(__d, __s, __n);
    140 }
    141 
    142 #ifdef _GNU_SOURCE
    143 #undef mempcpy
    144 _FORTIFY_FN(mempcpy) void *mempcpy(void *__d, const void *__s, size_t __n)
    145 {
    146 	size_t __bd = __builtin_object_size(__d, 0);
    147 	size_t __bs = __builtin_object_size(__s, 0);
    148 
    149 	if (__n > __bd || __n > __bs)
    150 		__builtin_trap();
    151 	return __orig_mempcpy(__d, __s, __n);
    152 }
    153 #endif
    154 
    155 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
    156 #undef strlcat
    157 #undef strlcpy
    158 _FORTIFY_FN(strlcat) size_t strlcat(char *__d, const char *__s, size_t __n)
    159 {
    160 	size_t __b = __builtin_object_size(__d, 0);
    161 
    162 	if (__n > __b)
    163 		__builtin_trap();
    164 	return __orig_strlcat(__d, __s, __n);
    165 }
    166 
    167 _FORTIFY_FN(strlcpy) size_t strlcpy(char *__d, const char *__s, size_t __n)
    168 {
    169 	size_t __b = __builtin_object_size(__d, 0);
    170 
    171 	if (__n > __b)
    172 		__builtin_trap();
    173 	return __orig_strlcpy(__d, __s, __n);
    174 }
    175 #endif
    176 
    177 #ifdef __cplusplus
    178 }
    179 #endif
    180 
    181 #endif
    182 
    183 #endif