diff options
| author | sin | 2015-03-13 11:00:46 +0000 |
|---|---|---|
| committer | sin | 2015-03-13 11:00:46 +0000 |
| commit | 9f8c543dc81f0c4239acae6713f5414eb7dc681d (patch) | |
| tree | 0c8dad17e27c510cc3c98502841aa1a75dfa3d1e /include/stdio.h | |
| parent | b211796d68c4a6b56f999534627791f3576b6135 (diff) | |
Rework fortify implementation to use extern inline
Overriding functions with macros is legal in C but a lot of software
is not prepared for it. Use the extern inline method to achieve the
same result.
Diffstat (limited to 'include/stdio.h')
| -rw-r--r-- | include/stdio.h | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/include/stdio.h b/include/stdio.h index a33514d..98e51ac 100644 --- a/include/stdio.h +++ b/include/stdio.h | |||
| @@ -6,21 +6,30 @@ | |||
| 6 | #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 | 6 | #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 |
| 7 | 7 | ||
| 8 | #ifndef __cplusplus | 8 | #ifndef __cplusplus |
| 9 | #undef fgets | ||
| 10 | #undef fread | ||
| 11 | #undef fwrite | ||
| 12 | #undef vsnprintf | ||
| 13 | #undef vsnprintf | ||
| 14 | #undef snprintf | ||
| 15 | #undef sprintf | ||
| 9 | 16 | ||
| 10 | static inline __attribute__ ((always_inline)) | 17 | extern char *__fgets_orig(char *, int, FILE *) |
| 11 | char * | 18 | __asm__(__USER_LABEL_PREFIX__ "fgets"); |
| 12 | __fortify_fgets(char *s, int n, FILE *fp) | 19 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 20 | char *fgets(char *s, int n, FILE *fp) | ||
| 13 | { | 21 | { |
| 14 | size_t bos = __builtin_object_size(s, 0); | 22 | size_t bos = __builtin_object_size(s, 0); |
| 15 | 23 | ||
| 16 | if ((size_t)n > bos) | 24 | if ((size_t)n > bos) |
| 17 | __builtin_trap(); | 25 | __builtin_trap(); |
| 18 | return fgets(s, n, fp); | 26 | return __fgets_orig(s, n, fp); |
| 19 | } | 27 | } |
| 20 | 28 | ||
| 21 | static inline __attribute__ ((always_inline)) | 29 | extern size_t __fread_orig(void *, size_t, size_t, FILE *) |
| 22 | size_t | 30 | __asm__(__USER_LABEL_PREFIX__ "fread"); |
| 23 | __fortify_fread(void *dst, size_t n, size_t nmemb, FILE *fp) | 31 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 32 | size_t fread(void *dst, size_t n, size_t nmemb, FILE *fp) | ||
| 24 | { | 33 | { |
| 25 | size_t bos = __builtin_object_size(dst, 0); | 34 | size_t bos = __builtin_object_size(dst, 0); |
| 26 | 35 | ||
| @@ -28,12 +37,13 @@ __fortify_fread(void *dst, size_t n, size_t nmemb, FILE *fp) | |||
| 28 | __builtin_trap(); | 37 | __builtin_trap(); |
| 29 | if (n * nmemb > bos) | 38 | if (n * nmemb > bos) |
| 30 | __builtin_trap(); | 39 | __builtin_trap(); |
| 31 | return fread(dst, n, nmemb, fp); | 40 | return __fread_orig(dst, n, nmemb, fp); |
| 32 | } | 41 | } |
| 33 | 42 | ||
| 34 | static inline __attribute__ ((always_inline)) | 43 | extern size_t __fwrite_orig(const void *, size_t, size_t, FILE *) |
| 35 | size_t | 44 | __asm__(__USER_LABEL_PREFIX__ "fwrite"); |
| 36 | __fortify_fwrite(const void *dst, size_t n, size_t nmemb, FILE *fp) | 45 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 46 | size_t fwrite(const void *dst, size_t n, size_t nmemb, FILE *fp) | ||
| 37 | { | 47 | { |
| 38 | size_t bos = __builtin_object_size(dst, 0); | 48 | size_t bos = __builtin_object_size(dst, 0); |
| 39 | 49 | ||
| @@ -41,48 +51,39 @@ __fortify_fwrite(const void *dst, size_t n, size_t nmemb, FILE *fp) | |||
| 41 | __builtin_trap(); | 51 | __builtin_trap(); |
| 42 | if (n * nmemb > bos) | 52 | if (n * nmemb > bos) |
| 43 | __builtin_trap(); | 53 | __builtin_trap(); |
| 44 | return fwrite(dst, n, nmemb, fp); | 54 | return __fwrite_orig(dst, n, nmemb, fp); |
| 45 | } | 55 | } |
| 46 | 56 | ||
| 47 | static inline __attribute__ ((always_inline)) | 57 | extern int __vsprintf_orig(char *, const char *, __builtin_va_list) |
| 48 | int | 58 | __asm__(__USER_LABEL_PREFIX__ "vsprintf"); |
| 49 | __fortify_vsprintf(char *s, const char *fmt, __builtin_va_list ap) | 59 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 60 | int vsprintf(char *s, const char *fmt, __builtin_va_list ap) | ||
| 50 | { | 61 | { |
| 51 | size_t bos = __builtin_object_size(s, 0); | 62 | size_t bos = __builtin_object_size(s, 0); |
| 52 | int r; | 63 | int r; |
| 53 | 64 | ||
| 54 | if (bos != (size_t)-1) { | 65 | if (bos != (size_t)-1) { |
| 55 | r = vsnprintf(s, bos, fmt, ap); | 66 | r = __vsnprintf_orig(s, bos, fmt, ap); |
| 56 | if (r != -1 && (size_t)r >= bos) | 67 | if (r != -1 && (size_t)r >= bos) |
| 57 | __builtin_trap(); | 68 | __builtin_trap(); |
| 58 | } else { | 69 | } else { |
| 59 | r = vsprintf(s, fmt, ap); | 70 | r = __vsprintf_orig(s, fmt, ap); |
| 60 | } | 71 | } |
| 61 | return r; | 72 | return r; |
| 62 | } | 73 | } |
| 63 | 74 | ||
| 64 | static inline __attribute__ ((always_inline)) | 75 | extern int __vsnprintf_orig(char *, size_t, const char *, __builtin_va_list) |
| 65 | int | 76 | __asm__(__USER_LABEL_PREFIX__ "vsnprintf"); |
| 66 | __fortify_vsnprintf(char *s, size_t n, const char *fmt, __builtin_va_list ap) | 77 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 78 | int vsnprintf(char *s, size_t n, const char *fmt, __builtin_va_list ap) | ||
| 67 | { | 79 | { |
| 68 | size_t bos = __builtin_object_size(s, 0); | 80 | size_t bos = __builtin_object_size(s, 0); |
| 69 | 81 | ||
| 70 | if (n > bos) | 82 | if (n > bos) |
| 71 | __builtin_trap(); | 83 | __builtin_trap(); |
| 72 | return vsnprintf(s, n, fmt, ap); | 84 | return __vsnprintf_orig(s, n, fmt, ap); |
| 73 | } | 85 | } |
| 74 | 86 | ||
| 75 | #undef fgets | ||
| 76 | #define fgets(s, n, fp) __fortify_fgets(s, n, fp) | ||
| 77 | #undef fread | ||
| 78 | #define fread(dst, n, nmemb, fp) __fortify_fread(dst, n, nmemb, fp) | ||
| 79 | #undef fwrite | ||
| 80 | #define fwrite(dst, n, nmemb, fp) __fortify_fwrite(dst, n, nmemb, fp) | ||
| 81 | #undef vsprintf | ||
| 82 | #define vsprintf(s, fmt, ap) __fortify_vsprintf(s, fmt, ap) | ||
| 83 | #undef vsnprintf | ||
| 84 | #define vsnprintf(s, n, fmt, ap) __fortify_vsnprintf(s, n, fmt, ap) | ||
| 85 | |||
| 86 | #undef snprintf | 87 | #undef snprintf |
| 87 | #define snprintf(s, n, fmt, ...) ({ \ | 88 | #define snprintf(s, n, fmt, ...) ({ \ |
| 88 | size_t _n = n; \ | 89 | size_t _n = n; \ |
