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 _STDIO_H 17#error "Never include this file directly; instead, include <stdio.h>" 18#endif 19 20#include <stdarg.h> 21#include "fortify.h" 22 23#ifdef __cplusplus 24extern "C" { 25#endif 26 27#if defined(__FORTIFY_COMPILATION) 28 29#define FORMAT_PLACE_2 (2) 30#define FORMAT_PLACE_3 (3) 31#define VALIST_PLACE_0 (0) 32#define VALIST_PLACE_3 (3) 33#define VALIST_PLACE_4 (4) 34 35size_t __fread_chk(void*, size_t, size_t, FILE*, size_t); 36size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t); 37char* __fgets_chk(char*, int, FILE*, size_t); 38 39__DIAGNOSE_FORTIFY_INLINE 40size_t fread(void* const __DIAGNOSE_PASS_OBJECT_SIZE0 buf, 41 size_t size, size_t count, FILE* stream) 42__DIAGNOSE_OVERLOAD 43__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNSAFE_CHK_MUL_OVERFLOW(size, count), 44 "in call to 'fread', size * count overflows") 45__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS0(buf), size * count), 46 "in call to 'fread', size * count is too large for the given buffer") 47{ 48#ifdef __FORTIFY_RUNTIME 49 size_t bos = __DIAGNOSE_BOS0(buf); 50 51 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_MUL(bos, size, count)) { 52 return __fread_chk(buf, size, count, stream, bos); 53 } 54#endif 55 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(fread)(buf, size, count, stream); 56} 57 58__DIAGNOSE_FORTIFY_INLINE 59size_t fwrite(const void* const __DIAGNOSE_PASS_OBJECT_SIZE0 buf, 60 size_t size, size_t count, FILE* stream) 61__DIAGNOSE_OVERLOAD 62__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNSAFE_CHK_MUL_OVERFLOW(size, count), 63 "in call to 'fwrite', size * count overflows") 64__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS0(buf), size * count), 65 "in call to 'fwrite', size * count is too large for the given buffer") 66{ 67#ifdef __FORTIFY_RUNTIME 68 size_t bos = __DIAGNOSE_BOS0(buf); 69 70 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_MUL(bos, size, count)) { 71 return __fwrite_chk(buf, size, count, stream, bos); 72 } 73#endif 74 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(fwrite)(buf, size, count, stream); 75} 76 77__DIAGNOSE_FORTIFY_INLINE 78char* fgets(char* const __DIAGNOSE_PASS_OBJECT_SIZE dest, int size, FILE* stream) 79__DIAGNOSE_OVERLOAD 80__DIAGNOSE_ERROR_IF(size < 0, "in call to 'fgets', size should not be less than 0") 81__DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size), 82 "in call to 'fgets', " SIZE_LARGER_THEN_DESTINATION_BUFFER) 83{ 84#ifdef __FORTIFY_RUNTIME 85 size_t bos = __DIAGNOSE_BOS(dest); 86 87 if (!__DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL_AND(bos, >=, (size_t)size, size >= 0)) { 88 return __fgets_chk(dest, size, stream, bos); 89 } 90#endif 91 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(fgets)(dest, size, stream); 92} 93 94__DIAGNOSE_FORTIFY_INLINE __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_3, VALIST_PLACE_0) 95int vsnprintf(char* const __DIAGNOSE_PASS_OBJECT_SIZE dest, 96 size_t size, const char* format, va_list ap) 97__DIAGNOSE_OVERLOAD 98{ 99 size_t bos = __DIAGNOSE_BOS(dest); 100 return __builtin___vsnprintf_chk(dest, size, 0, bos, format, ap); 101} 102 103__DIAGNOSE_FORTIFY_INLINE __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_2, VALIST_PLACE_0) 104int vsprintf(char* const __DIAGNOSE_PASS_OBJECT_SIZE dest, const char* format, va_list ap) 105__DIAGNOSE_OVERLOAD 106{ 107 return __builtin___vsprintf_chk(dest, 0, __DIAGNOSE_BOS(dest), format, ap); 108} 109 110__DIAGNOSE_FORTIFY_VARIADIC __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_2, VALIST_PLACE_3) 111int sprintf(char* const __DIAGNOSE_PASS_OBJECT_SIZE dest, const char* format, ...) 112__DIAGNOSE_OVERLOAD 113{ 114 va_list va_l; 115 va_start(va_l, format); 116 int result = __builtin___vsprintf_chk(dest, 0, __DIAGNOSE_BOS(dest), format, va_l); 117 va_end(va_l); 118 return result; 119} 120 121__DIAGNOSE_FORTIFY_VARIADIC __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_3, VALIST_PLACE_4) 122int snprintf(char* const __DIAGNOSE_PASS_OBJECT_SIZE dest, size_t size, const char* format, ...) 123__DIAGNOSE_OVERLOAD 124{ 125 va_list va_l; 126 va_start(va_l, format); 127 int result = __builtin___vsnprintf_chk(dest, size, 0, __DIAGNOSE_BOS(dest), format, va_l); 128 va_end(va_l); 129 return result; 130} 131 132#endif // defined(__FORTIFY_COMPILATION) 133 134#ifdef __cplusplus 135} 136#endif