1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef _FORTIFY_FORTIFY_H 17 #define _FORTIFY_FORTIFY_H 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #ifdef _FORTIFY_SOURCE 24 #if (_FORTIFY_SOURCE == 1) || (_FORTIFY_SOURCE == 2) 25 #ifndef __FORTIFY_COMPILATION 26 #define __FORTIFY_COMPILATION 27 #endif 28 #endif 29 #endif 30 31 #ifdef _FORTIFY_SOURCE 32 #if (_FORTIFY_SOURCE == 2) 33 #ifndef __FORTIFY_RUNTIME 34 #define __FORTIFY_RUNTIME 35 #endif 36 #endif 37 #endif 38 39 #if defined(__cplusplus) 40 #define __DIAGNOSE_CAST(_k, _t, _v) (_k<_t>(_v)) 41 #else 42 #define __DIAGNOSE_CAST(_k, _t, _v) ((_t) (_v)) 43 #endif 44 45 #if defined(__LP64__) 46 #ifndef FORTIFY_LONG_MAX 47 #define FORTIFY_LONG_MAX 0x7fffffffffffffffL 48 #endif 49 #ifndef FORTIFY_SSIZE_MAX 50 #define FORTIFY_SSIZE_MAX FORTIFY_LONG_MAX 51 #endif 52 #else 53 #ifndef FORTIFY_LONG_MAX 54 #define FORTIFY_LONG_MAX 0x7fffffffL 55 #endif 56 #ifndef FORTIFY_SSIZE_MAX 57 #define FORTIFY_SSIZE_MAX FORTIFY_LONG_MAX 58 #endif 59 #endif 60 #ifndef FORTIFY_PATH_MAX 61 #define FORTIFY_PATH_MAX 4096 62 #endif 63 64 #define __DIAGNOSE_ALWAYS_INLINE __attribute__((__always_inline__)) 65 #define __DIAGNOSE_PREDICT_TRUE(exp) __builtin_expect((exp) != 0, 1) 66 #define __DIAGNOSE_PREDICT_FALSE(exp) __builtin_expect((exp) != 0, 0) 67 #define __DIAGNOSE_ENABLE_IF(cond, msg) __attribute__((enable_if(cond, msg))) 68 #define __DIAGNOSE_ERROR_IF(cond, msg) __attribute__((diagnose_if(cond, msg, "error"))) 69 #define __DIAGNOSE_WARNING_IF(cond, msg) __attribute__((diagnose_if(cond, msg, "warning"))) 70 71 #define __DIAGNOSE_BOS_LEVEL (1) 72 #define __DIAGNOSE_BOSN(s, n) __builtin_object_size((s), (n)) 73 #define __DIAGNOSE_BOS(s) __DIAGNOSE_BOSN((s), __DIAGNOSE_BOS_LEVEL) 74 75 #define __DIAGNOSE_BOS0(s) __DIAGNOSE_BOSN((s), 0) 76 #define __DIAGNOSE_PASS_OBJECT_SIZE_N(n) __attribute__((pass_object_size(n))) 77 #define __DIAGNOSE__SIZE_MUL_OVERFLOW(a, b, result) __builtin_umull_overflow(a, b, result) 78 #define __DIAGNOSE_PRINTFLIKE(x, y) __attribute__((__format__(printf, x, y))) 79 #define __DIAGNOSE_CALL_BYPASSING_FORTIFY(fn) (&(fn)) 80 #define __DIAGNOSE_FORTIFY_INLINE static __inline__ __attribute__((no_stack_protector)) \ 81 __DIAGNOSE_ALWAYS_INLINE 82 83 #define __DIAGNOSE_FORTIFY_VARIADIC static __inline__ 84 85 #define __DIAGNOSE_PASS_OBJECT_SIZE __DIAGNOSE_PASS_OBJECT_SIZE_N(__DIAGNOSE_BOS_LEVEL) 86 #define __DIAGNOSE_PASS_OBJECT_SIZE0 __DIAGNOSE_PASS_OBJECT_SIZE_N(0) 87 88 #define __DIAGNOSE_FORTIFY_UNKNOWN_SIZE ((unsigned int) -1) 89 /* The following are intended for use in unevaluated environments, e.g. diagnose_if conditions. */ 90 #define __DIAGNOSE_UNEVALUATED_LT(bos_val, val) \ 91 ((bos_val) != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE && (bos_val) < (val)) 92 93 #define __DIAGNOSE_UNEVALUATED_LE(bos_val, val) \ 94 ((bos_val) != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE && (bos_val) <= (val)) 95 96 /* The following acts in the context of evaluation. */ 97 #define __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL_AND(bos_val, op, index, cond) \ 98 ((bos_val) == __DIAGNOSE_FORTIFY_UNKNOWN_SIZE || \ 99 (__builtin_constant_p(index) && bos_val op index && (cond))) 100 101 #define __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL(bos_val, op, index) \ 102 __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL_AND(bos_val, op, index, 1) 103 104 #define __DIAGNOSE_BOS_TRIVIALLY_GE(bos_val, index) __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL((bos_val), >=, (index)) 105 #define __DIAGNOSE_BOS_TRIVIALLY_GT(bos_val, index) __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL((bos_val), >, (index)) 106 107 #define __DIAGNOSE_OVERLOAD __attribute__((overloadable)) 108 109 /* 110 * A function to prevent this function from being applied. 111 * Used to rename the function so that the compiler emits a call to "x". 112 */ 113 #define __DIAGNOSE_RENAME(x) __asm__(#x) 114 #define __DIAGNOSE_OPEN_MODES_USEFUL(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE) 115 #define __DIAGNOSE_BOS_FD_COUNT_TRIVIALLY_SAFE(bos_val, fds, fd_count) \ 116 __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL_AND((bos_val), >=, (sizeof(*(fds)) * (fd_count)), \ 117 (fd_count) <= __DIAGNOSE_CAST(static_cast, unsigned int, -1) / sizeof(*(fds))) 118 119 #define __DIAGNOSE_UNSAFE_CHK_MUL_OVERFLOW(x, y) ((__SIZE_TYPE__)-1 / (x) < (y)) 120 121 #define __DIAGNOSE_BOS_TRIVIALLY_GE_MUL(bos_val, size, count) \ 122 __DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL_AND(bos_val, >=, (size) * (count), \ 123 !__DIAGNOSE_UNSAFE_CHK_MUL_OVERFLOW(size, count)) 124 125 #define FORTIFY_RUNTIME_ERROR_PREFIX "Musl Fortify runtime error: " 126 #define OPEN_TOO_MANY_ARGS_ERROR "There are too many arguments" 127 #define OPEN_TOO_FEW_ARGS_ERROR "invoking with O_CREAT or O_TMPFILE, but missing pattern." 128 #define OPEN_USELESS_MODES_WARNING "having redundant mode bits; but missing O_CREAT." 129 #define CALLED_WITH_STRING_BIGGER_BUFFER "called with a string larger than the buffer" 130 #define FD_COUNT_LARGE_GIVEN_BUFFER "fd_count is greater than the given buffer" 131 #define CALLED_WITH_SIZE_BIGGER_BUFFER "called with bigger size than the buffer" 132 #define OUTPUT_PARAMETER_BYTES "the output parameter must be nullptr or a pointer to the buffer with >= FORTIFY_PATH_MAX bytes" 133 #define SIZE_LARGER_THEN_DESTINATION_BUFFER "the size is greater than the target buffer" 134 135 void __fortify_error(const char* info, ...); 136 137 #ifdef __cplusplus 138 } 139 #endif 140 141 #endif