Changeset View
Standalone View
include/secure/_stdio.h
- This file was added.
/* $FreeBSD$ */ | |||||
/* $OpenBSD: stdio.h,v 1.35 2006/01/13 18:10:09 miod Exp $ */ | |||||
/* $NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $ */ | |||||
/* bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 */ | |||||
ngie: This seems out of order. Shouldn't the RCS tags be below the licensing text? | |||||
/*- | |||||
* Copyright (c) 1990 The Regents of the University of California. | |||||
* All rights reserved. | |||||
* | |||||
* This code is derived from software contributed to Berkeley by | |||||
* Chris Torek. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* 3. Neither the name of the University nor the names of its contributors | |||||
* may be used to endorse or promote products derived from this software | |||||
* without specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
* @(#)stdio.h 5.17 (Berkeley) 6/3/91 | |||||
*/ | |||||
#ifndef _STDIO_H_ | |||||
#error "You should not use <secure/stdio.h> directly; include <stdio.h> instead." | |||||
#endif | |||||
#ifndef _SECURE_STDIO_H_ | |||||
#define _SECURE_STDIO_H_ | |||||
#include <secure/security.h> | |||||
#include <stdarg.h> | |||||
__BEGIN_DECLS | |||||
extern char *__fgets_chk(char *, int, FILE *, size_t); | |||||
extern char *__fgets_real(char *, int, FILE *) __RENAME(fgets); | |||||
extern char *__gets_chk(char *, size_t); | |||||
extern char *__gets_real(char *) __RENAME(gets); | |||||
__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer"); | |||||
__errordecl(__fgets_too_small_error, "fgets called with size less than zero"); | |||||
extern char *__gets_real(char *) __RENAME(gets); | |||||
extern int __sprintf_real(char * __restrict, const char * __restrict, ...) __RENAME(sprintf); | |||||
Done Inline Actions/scratch/tmp/pfg/obj/mips.mips/scratch/tmp/pfg/head/tmp/usr/include/secure/_stdio.h:58: warning: redundant redeclaration of 'gets_real' pfg: /scratch/tmp/pfg/obj/mips.mips/scratch/tmp/pfg/head/tmp/usr/include/secure/_stdio.h:58: warning… | |||||
extern int __vsprintf_real(char * __restrict, const char * __restrict, __va_list) __RENAME(vsprintf); | |||||
#if __ISO_C_VISIBLE >= 1999 | |||||
extern int __snprintf_real(char * __restrict, size_t, const char * __restrict, ...) __RENAME(snprintf) __printflike(3, 4); | |||||
extern int __vsnprintf_real(char * __restrict, size_t, const char * __restrict, __va_list) __RENAME(vsnprintf) __printflike(3, 0); | |||||
#endif | |||||
#if defined(__BSD_FORTIFY) | |||||
#if __ISO_C_VISIBLE >= 1999 | |||||
__FORTIFY_INLINE __printflike(3, 0) int | |||||
vsnprintf(char *dest, size_t size, const char *format, __va_list ap) | |||||
Done Inline Actions/scratch/tmp/pfg/obj/mips.mips/scratch/tmp/pfg/head/tmp/usr/include/secure/_stdio.h:69: warning: redundant redeclaration of 'snprintf_real' pfg: /scratch/tmp/pfg/obj/mips.mips/scratch/tmp/pfg/head/tmp/usr/include/secure/_stdio.h:69: warning… | |||||
{ | |||||
Done Inline Actions/scratch/tmp/pfg/obj/mips.mips/scratch/tmp/pfg/head/tmp/usr/include/secure/_stdio.h:70: warning: redundant redeclaration of 'vsnprintf_real' pfg: /scratch/tmp/pfg/obj/mips.mips/scratch/tmp/pfg/head/tmp/usr/include/secure/_stdio.h:70: warning… | |||||
size_t bos = __bos(dest); | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) | |||||
return (__vsnprintf_real(dest, size, format, ap)); | |||||
return (__vsnprintf_chk(dest, size, 0, bos, format, ap)); | |||||
} | |||||
#endif /* __ISO_C_VISIBLE */ | |||||
Not Done Inline ActionsYou'd have to ask the local C standard experts but I don't think declaring a standard function inline is standard compliant. What you should do instead is declare the function normally and then define a macro with the same name that performs the necessary checks. If you don't want to put too much code into the macro you can put it into a "static inline __always_inline" function instead and call this function from the macro. I think this will solve the problems you are seeing in some ports. tijl: You'd have to ask the local C standard experts but I don't think declaring a standard function… | |||||
__FORTIFY_INLINE __printflike(2, 0) int | |||||
vsprintf(char *dest, const char *format, __va_list ap) | |||||
{ | |||||
size_t bos = __bos(dest); | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) | |||||
return (__vsprintf_real(dest, format, ap)); | |||||
return (__vsprintf_chk(dest, 0, bos, format, ap)); | |||||
} | |||||
#if __ISO_C_VISIBLE >= 1999 | |||||
#if !__GNUC_PREREQ__(4, 3) /* defined(__clang__) */ | |||||
#if !defined(snprintf) | |||||
Done Inline Actionsredundant clang check pfg: redundant clang check | |||||
#define __wrap_snprintf(dest, size, ...) \ | |||||
({ \ | |||||
size_t bos = __bos(dest); \ | |||||
int ret; \ | |||||
\ | |||||
Done Inline Actions__has_builtin() || pfg: __has_builtin() || | |||||
Done Inline Actions#if !has_builtin(va_arg_pack) || defined(clang__) ? op: #if !__has_builtin(va_arg_pack) || defined(__clang__) ? | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) \ | |||||
Done Inline ActionsWe only check has_builtin() in case clang implements something from the modern gcc, so it would be something like: pfg: We only check has_builtin() in case clang implements something from the modern gcc, so it would… | |||||
ret = __snprintf_real((dest), (size), __VA_ARGS__); \ | |||||
else \ | |||||
ret = __snprintf_chk((dest), (size), 0, bos, __VA_ARGS__); \ | |||||
ret; \ | |||||
}) | |||||
#define snprintf(dest, size, ...) __wrap_snprintf((dest), (size), __VA_ARGS__) | |||||
#endif /* !snprintf */ | |||||
#else /* __GNUC_PREREQ__(4, 3) */ | |||||
__FORTIFY_INLINE __printflike(3, 4) int | |||||
snprintf(char *dest, size_t size, const char *format, ...) | |||||
{ | |||||
size_t bos = __bos(dest); | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) | |||||
return (__snprintf_real(dest, size, format, | |||||
__builtin_va_arg_pack())); | |||||
Done Inline Actions__builtin_va_arg_pack is only available in gcc 4.3+ pfg: __builtin_va_arg_pack is only available in gcc 4.3+ | |||||
return (__snprintf_chk(dest, size, 0, bos, format, | |||||
__builtin_va_arg_pack())); | |||||
} | |||||
Done Inline Actions__has_builtin() || pfg: __has_builtin() || | |||||
#endif /* !__GNUC_PREREQ__(4, 3) */ | |||||
#endif /* __ISO_C_VISIBLE */ | |||||
#if !__GNUC_PREREQ__(4, 3) /* defined(__clang__) */ | |||||
Done Inline ActionsRedundant clang check pfg: Redundant clang check | |||||
#if !defined(sprintf) | |||||
#define __wrap_sprintf(dest, ...) \ | |||||
({ \ | |||||
size_t bos = __bos(dest); \ | |||||
int ret; \ | |||||
\ | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) \ | |||||
ret = __sprintf_real((dest), __VA_ARGS__); \ | |||||
else \ | |||||
ret = __sprintf_chk((dest), 0, bos, __VA_ARGS__); \ | |||||
ret; \ | |||||
}) | |||||
#define sprintf(dest, ...) __wrap_sprintf((dest), __VA_ARGS__) | |||||
#endif /* !sprintf */ | |||||
#else /* __GNUC_PREREQ__(4, 3) */ | |||||
__FORTIFY_INLINE __printflike(2, 3) int | |||||
sprintf(char *dest, const char *format, ...) | |||||
{ | |||||
size_t bos = __bos(dest); | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) | |||||
return (__sprintf_real(dest, __builtin_va_arg_pack())); | |||||
Done Inline Actions__builtin_va_arg_pack is only available on gcc >= 4.3 pfg: __builtin_va_arg_pack is only available on gcc >= 4.3 | |||||
return (__sprintf_chk(dest, 0, __bos, format, | |||||
__builtin_va_arg_pack())); | |||||
} | |||||
#endif /* !__GNUC_PREREQ__(4, 3) */ | |||||
__FORTIFY_INLINE char * | |||||
fgets(char *dest, int size, FILE *stream) | |||||
{ | |||||
size_t bos = __bos(dest); | |||||
#if !defined(__clang__) | |||||
/* | |||||
* Compiler can prove, at compile time, that the passed in size | |||||
* is always negative. | |||||
* Force a compiler error. | |||||
*/ | |||||
if (__builtin_constant_p(size) && (size < 0)) | |||||
__fgets_too_small_error(); | |||||
#endif | |||||
/* | |||||
* Compiler doesn 't know destination size. | |||||
* Don' t call __fgets_chk. | |||||
*/ | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) | |||||
return (__fgets_real(dest, size, stream)); | |||||
#if !defined(__clang__) | |||||
Done Inline ActionsThis should be _size pfg: This should be `_size` | |||||
/* | |||||
* Compiler can prove, at compile time, that the passed in size | |||||
* is always <= the actual object size. | |||||
* Don 't call __fgets_chk. | |||||
*/ | |||||
if (__builtin_constant_p(size) && (size <= (int)bos)) | |||||
return (__fgets_real(dest, size, stream)); | |||||
/* | |||||
* Compiler can prove, at compile time, that the passed in size | |||||
* is always > the actual object size. | |||||
* Force a compiler error. | |||||
*/ | |||||
if (__builtin_constant_p(size) && (size > (int)bos)) | |||||
__fgets_too_big_error(); | |||||
#endif | |||||
return (__fgets_chk(dest, size, stream, bos)); | |||||
} | |||||
Done Inline ActionsIt looks like we should also restrict this from some gcc versions. We are using __fread_too_big_error in this path but this causing linking erros with gcc 4.2. pfg: It looks like we should also restrict this from some gcc versions. We are using… | |||||
__FORTIFY_INLINE char * | |||||
gets(char *dest) | |||||
{ | |||||
size_t bos = __bos(dest); | |||||
if (bos == __FORTIFY_UNKNOWN_SIZE) | |||||
return (__gets_real(dest)); | |||||
return (__gets_chk(dest, bos)); | |||||
} | |||||
#endif /* defined(__BSD_FORTIFY) */ | |||||
__END_DECLS | |||||
#endif /* !_SECURE_STDIO_H_ */ |
This seems out of order. Shouldn't the RCS tags be below the licensing text?