fortify-headers

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

stdlib.h (4681B)


      1 /*
      2  * Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
      3  * Copyright (C) 2022 q66 <q66@chimera-linux.org>
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any
      6  * purpose with or without fee is hereby granted.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #ifndef _FORTIFY_STDLIB_H
     18 #define _FORTIFY_STDLIB_H
     19 
     20 #if !defined(__cplusplus) && !defined(__clang__)
     21 __extension__
     22 #endif
     23 #include_next <stdlib.h>
     24 
     25 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
     26 
     27 #include "fortify-headers.h"
     28 
     29 #ifdef __cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 #undef mbstowcs
     34 #if __has_builtin(__builtin_mbstowcs)
     35 __diagnose_as_builtin(__builtin_mbstowcs, 1, 2, 3)
     36 #endif
     37 _FORTIFY_FN(mbstowcs) size_t mbstowcs(wchar_t * _FORTIFY_POS0 __ws,
     38                                       const char *__s, size_t __wn)
     39 {
     40 	__fh_size_t __b = __fh_bos(__ws, 0);
     41 
     42 	if (__ws && __wn > __b / sizeof(wchar_t))
     43 		__builtin_trap();
     44 	return __orig_mbstowcs(__ws, __s, __wn);
     45 }
     46 
     47 #undef wcstombs
     48 __fh_access(write_only, 1, 3)
     49 #if __has_builtin(__builtin_wcstombs)
     50 __diagnose_as_builtin(__builtin_wcstombs, 1, 2, 3)
     51 #endif
     52 _FORTIFY_FN(wcstombs) size_t wcstombs(char * _FORTIFY_POS0 __s,
     53                                       const wchar_t *__ws, size_t __n)
     54 {
     55 	__fh_size_t __b = __fh_bos(__s, 0);
     56 
     57 	if (__s && __n > __b)
     58 		__builtin_trap();
     59 	return __orig_wcstombs(__s, __ws, __n);
     60 }
     61 
     62 #if 0
     63 /* https://github.com/jvoisin/fortify-headers/issues/24 */
     64 #ifdef MB_CUR_MAX
     65 #undef wctomb
     66 #if __has_builtin(__builtin_wctomb)
     67 __diagnose_as_builtin(__builtin_wctomb, 1, 2)
     68 #endif
     69 _FORTIFY_FN(wctomb) int wctomb(char * _FORTIFY_POS0 __s, wchar_t __w)
     70 {
     71 	__fh_size_t __b = __fh_bos(__s, 0);
     72 
     73 	if (__s && 16 > __b && MB_CUR_MAX > __b)
     74 		__builtin_trap();
     75 	return __orig_wctomb(__s, __w);
     76 }
     77 #endif // MB_CUR_MAX
     78 #endif
     79 
     80 #undef qsort
     81 #if __has_builtin(__builtin_qsort)
     82 __diagnose_as_builtin(__builtin_qsort, 1, 2, 3, 4)
     83 #endif
     84 __fh_access(read_write, 1)
     85 _FORTIFY_FN(qsort) void qsort(void * _FORTIFY_POS0 base, size_t nmemb, size_t size,
     86 	int (*compar)(const void *, const void *))
     87 {
     88 	__fh_size_t __b = __fh_bos(base, 0);
     89 
     90 	if (__bmo(nmemb, size))
     91 		__builtin_trap();
     92 	if (nmemb * size> __b)
     93 		__builtin_trap();
     94 
     95 	return __orig_qsort(base, nmemb, size, compar);
     96 }
     97 
     98 /* FIXME clang */
     99 #if !defined(__clang__)
    100 #undef malloc
    101 #undef realloc
    102 #undef calloc
    103 
    104 __fh_malloc(malloc (free, 1))
    105 __fh_alloc_size(1)
    106 __warn_unused_result
    107 #if __has_builtin(__builtin_malloc)
    108 __diagnose_as_builtin(__builtin_malloc, 1)
    109 #endif
    110 _FORTIFY_FN(malloc) void *malloc(size_t __s)
    111 {
    112 	return __orig_malloc(__s);
    113 }
    114 
    115 __fh_alloc_size(2)
    116 __warn_unused_result
    117 #if __has_builtin(__builtin_realloc)
    118 __diagnose_as_builtin(__builtin_realloc, 1, 2)
    119 #endif
    120 _FORTIFY_FN(realloc) void *realloc(void *__p, size_t __s)
    121 {
    122 	return __orig_realloc(__p, __s);
    123 }
    124 
    125 __fh_alloc_size(1, 2)
    126 __warn_unused_result
    127 #if __has_builtin(__builtin_calloc)
    128 __diagnose_as_builtin(__builtin_calloc, 1, 2)
    129 #endif
    130 _FORTIFY_FN(calloc) void *calloc(size_t __n, size_t __s)
    131 {
    132 	return __orig_calloc(__n, __s);
    133 }
    134 
    135 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
    136 #undef reallocarray
    137 __fh_alloc_size (2, 3)
    138 __warn_unused_result
    139 #if __has_builtin(__builtin_reallocarray)
    140 __diagnose_as_builtin(__builtin_reallocarray, 1, 2, 3)
    141 #endif
    142 _FORTIFY_FN(reallocarray) void* reallocarray(void* __p, size_t __n, size_t __s)
    143 {
    144 	return __orig_reallocarray(__p, __n, __s);
    145 }
    146 #endif
    147 
    148 #if (defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE))
    149 #undef realpath
    150 __warning_if(__p == NULL, "'realpath' called with path set to `NULL`; did you invert the arguments?")
    151 #if __has_builtin(__builtin_realpath)
    152 __diagnose_as_builtin(__builtin_realpath, 1, 2)
    153 #endif
    154 _FORTIFY_FN(realpath) char *realpath(const char *__p, char *__r)
    155 {
    156 	// PATH_MAX is defined as 4096
    157 	if (__r && 4096 > __fh_bos(__r, 2)) {
    158 		char __buf[4096], *__ret;
    159 		__fh_size_t __l;
    160 
    161 		__ret = __orig_realpath(__p, __buf);
    162 		if (!__ret)
    163 			return NULL;
    164 		__l = __builtin_strlen(__ret) + 1;
    165 		if (__l > __fh_bos(__r, 0))
    166 			__builtin_trap();
    167 		__builtin_memcpy(__r, __ret, __l);
    168 		return __r;
    169 	}
    170 	return __orig_realpath(__p, __r);
    171 }
    172 #endif
    173 
    174 #endif // clang
    175 
    176 #ifdef __cplusplus
    177 }
    178 #endif
    179 
    180 #endif // _FORTIFY_SOURCE
    181 
    182 #endif