• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
24 extern "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 
35 size_t __fread_chk(void*, size_t, size_t, FILE*, size_t);
36 size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t);
37 char* __fgets_chk(char*, int, FILE*, size_t);
38 
39 __DIAGNOSE_FORTIFY_INLINE
fread(void * const __DIAGNOSE_PASS_OBJECT_SIZE0 buf,size_t size,size_t count,FILE * stream)40 size_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
fwrite(const void * const __DIAGNOSE_PASS_OBJECT_SIZE0 buf,size_t size,size_t count,FILE * stream)59 size_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
fgets(char * const __DIAGNOSE_PASS_OBJECT_SIZE dest,int size,FILE * stream)78 char* 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 
__DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_3,VALIST_PLACE_0)94 __DIAGNOSE_FORTIFY_INLINE __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_3, VALIST_PLACE_0)
95 int 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 
__DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_2,VALIST_PLACE_0)103 __DIAGNOSE_FORTIFY_INLINE __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_2, VALIST_PLACE_0)
104 int 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 
__DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_2,VALIST_PLACE_3)110 __DIAGNOSE_FORTIFY_VARIADIC __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_2, VALIST_PLACE_3)
111 int 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 
__DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_3,VALIST_PLACE_4)121 __DIAGNOSE_FORTIFY_VARIADIC __DIAGNOSE_PRINTFLIKE(FORMAT_PLACE_3, VALIST_PLACE_4)
122 int 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