Cast to checked array pointers in bounds declarations (#165)

* Cast to checked array pointers in bounds declarations, not unchecked pointers

* Port Changes from LLVM Test Suite
  These changes mostly include adding `_Unchecked` to declarations and adding `#pragma BOUNDS_CHECKED ON` around the header contents.
This commit is contained in:
Sam Elliott 2017-05-31 18:36:24 -07:00 коммит произвёл GitHub
Родитель aaef796eba
Коммит 18d2581e2c
12 изменённых файлов: 125 добавлений и 17 удалений

29
include/_builtin_common.h Normal file
Просмотреть файл

@ -0,0 +1,29 @@
//---------------------------------------------------------------------//
// Bounds-safe interfaces for compiler-defined builtin functions //
// corresponding to secure/_common.h functions //
// //
// These are given in the order they appear in clang's Builtins.def. //
// Functions that do not appear can not have checked interfaces //
// defined. //
// //
// These are based on the types as declared within clang //
// and https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html //
// //
// TODO: revise string types after support for pointers to //
// null-terminated arrays is added to C. //
/////////////////////////////////////////////////////////////////////////
#ifndef __has_builtin
#define _undef__has_builtin
#define __has_builtin(x) 0
#endif
#if __has_builtin(__builtin_object_size)
_Unchecked
size_t __builtin_object_size(const void* obj, int i);
#endif
#ifdef _undef__has_builtin
#undef _undef__has_builtin
#undef __has_builtin
#endif

Просмотреть файл

@ -13,19 +13,23 @@
// null-terminated arrays is added to C. //
/////////////////////////////////////////////////////////////////////////
#include "_builtin_common.h"
#ifndef __has_builtin
#define _undef__has_builtin
#define __has_builtin(x) 0
#endif
#if __has_builtin(__builtin___snprintf_chk) || defined(__GNUC__)
extern int __snprintf_chk(char * __restrict s : count(n),
extern _Unchecked
int __snprintf_chk(char * __restrict s : count(n),
size_t n,
int flag,
size_t obj_size,
const char * __restrict format,
...);
_Unchecked
int __builtin___snprintf_chk(char * restrict s : count(n),
size_t n,
int flag,
@ -36,13 +40,15 @@ int __builtin___snprintf_chk(char * restrict s : count(n),
#if __has_builtin(__builtin___vsnprintf_chk) || defined(__GNUC__)
extern int __vsnprintf_chk(char * __restrict s : count(n),
extern _Unchecked
int __vsnprintf_chk(char * __restrict s : count(n),
size_t n,
int flag,
size_t obj_size,
const char * __restrict format,
va_list);
_Unchecked
int __builtin___vsnprintf_chk(char * restrict s : count(n),
size_t n,
int flag,

Просмотреть файл

@ -13,46 +13,51 @@
// null-terminated arrays is added to C. //
/////////////////////////////////////////////////////////////////////////
#include "_builtin_common.h"
#ifndef __has_builtin
#define _undef__has_builtin
#define __has_builtin(x) 0
#endif
#if __has_builtin(__builtin___memcpy_chk) || defined(__GNUC__)
_Unchecked
void *__builtin___memcpy_chk(void * restrict dest : byte_count(n),
const void * restrict src : byte_count(n),
size_t n,
size_t obj_size) : bounds(dest, (char *) dest + n);
size_t obj_size) : bounds(dest, (_Array_ptr<char>) dest + n);
#endif
#if __has_builtin(__builtin__memmove_chk) || defined(__GNUC__)
_Unchecked
void *__builtin__memmove_chk(void * restrict dest : byte_count(n),
const void * restrict src : byte_count(n),
size_t n,
size_t obj_size) : bounds(dest, (char *)dest + n);
size_t obj_size) : bounds(dest, (_Array_ptr<char>)dest + n);
#endif
#if __has_builtin(__builtin__memset_chk) || defined(__GNUC__)
_Unchecked
void *__builtin__memset_chk(void * s : byte_count(n),
int c,
size_t n,
size_t obj_size) : bounds(s, (char *) s + n);
size_t obj_size) : bounds(s, (_Array_ptr<char>) s + n);
#endif
#if __has_builtin(__builtin___strncat_chk) || defined(__GNUC__)
_Unchecked
char *__builtin___strncat_chk(char * restrict dest : count(n),
const char * restrict src : count(n),
size_t n,
size_t obj_size) : bounds(dest, (char *)dest + n);
size_t obj_size) : bounds(dest, (_Array_ptr<char>)dest + n);
#endif
#if __has_builtin(__builtin___strncpy_chk) || defined(__GNUC__)
_Unchecked
char *__builtin___strncpy_chk(char * restrict dest : count(n),
const char * restrict src : count(n),
size_t n,
size_t obj_size) : bounds(dest, (char *)dest + n);
size_t obj_size) : bounds(dest, (_Array_ptr<char>)dest + n);
#endif
#ifdef _undef__has_builtin

Просмотреть файл

@ -8,9 +8,13 @@
#include <fenv.h>
#pragma BOUNDS_CHECKED ON
int fesetexceptflag(const fexcept_t *flagp : itype(_Ptr<const fexcept_t>),
int excepts);
int fegetenv(fenv_t *envp : itype(_Ptr<fenv_t>));
int feholdexcept(fenv_t *envp : itype(_Ptr<fenv_t>));
int fesetenv(const fenv_t *envp : itype(_Ptr<const fenv_t>));
int feupdateenv(const fenv_t *envp : itype(_Ptr<const fenv_t>));
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -12,16 +12,25 @@
#include <stddef.h> // define wchar_t for wcstoimax and wcstoumax
#include <inttypes.h>
#pragma BOUNDS_CHECKED ON
_Unchecked
intmax_t strtoimax(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>),
int base);
_Unchecked
uintmax_t strtoumax(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>),
int base);
_Unchecked
intmax_t wcstoimax(const wchar_t * restrict nptr,
wchar_t ** restrict endptr : itype(restrict _Ptr<wchar_t *>),
int base);
_Unchecked
uintmax_t wcstoumax(const wchar_t * restrict nptr,
wchar_t ** restrict endptr : itype(restrict _Ptr<wchar_t *>),
int base);
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -11,6 +11,8 @@
#include <math.h>
#pragma BOUNDS_CHECKED ON
double frexp(double value, int *exp : itype(_Ptr<int>));
float frexpf(float value, int *exp : itype(_Ptr<int>));
long double frexpl(long double value, int *exp : itype(_Ptr<int>));
@ -24,7 +26,9 @@ double remquo(double x, double y, int *quo : itype(_Ptr<int>));
float remquof(float x, float y, int *quo : itype(_Ptr<int>));
long double remquol(long double x, long double y, int *quo : itype(_Ptr<int>));
#pragma BOUNDS_CHECKED OFF
// TODO: strings
// double nan(const char *t);
// float nanf(const char *t);
// long double nanf(const char *t);
// long double nanf(const char *t);

Просмотреть файл

@ -5,8 +5,13 @@
#include <signal.h>
#pragma BOUNDS_CHECKED ON
_Unchecked
void (*signal(int sig,
void ((*func)(int)) :
itype(_Ptr<void (int)>) // bound-safe interface for func
) : itype(_Ptr<void (int)>) // bounds-safe interface for signal return
)(int);
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -13,6 +13,7 @@
#include <stdio.h>
#pragma BOUNDS_CHECKED ON
// TODO: handle strings
// int remove(const char *name);
@ -22,8 +23,10 @@ FILE *tmpfile(void) : itype(_Ptr<FILE>);
// char *tmpnam(char *source);
int fclose(FILE *stream : itype(_Ptr<FILE>));
int fflush(FILE *stream : itype(_Ptr<FILE>));
_Unchecked
FILE *fopen(const char * restrict filename,
const char * restrict mode) : itype(_Ptr<FILE>);
_Unchecked
FILE *freopen(const char * restrict filename,
const char * restrict mode,
FILE * restrict stream : itype(restrict _Ptr<FILE>)) :
@ -42,8 +45,10 @@ int setvbuf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
// * Any pointer arguments may not meet the requirements of the
// format string.
//
_Unchecked
int fprintf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
const char * restrict format, ...);
_Unchecked
int fscanf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
const char * restrict format, ...);
// TODO: handle strings
@ -61,13 +66,16 @@ int fscanf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
// const char * restrict format, ...);
// TODO: Apple System Headers Support
#if !defined (__APPLE__) && _FORTIFY_SOURCE > 0
_Unchecked
int snprintf(char * restrict s : count(n), size_t n,
const char * restrict format, ...);
#endif
_Unchecked
int vfprintf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
const char * restrict format,
va_list arg);
_Unchecked
int vfscanf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
const char * restrict format,
va_list arg);
@ -79,6 +87,7 @@ int vfscanf(FILE * restrict stream : itype(restrict _Ptr<FILE>),
// va_list arg);
// TODO: Apple System Headers Support
#if !defined (__APPLE__) && _FORTIFY_SOURCE > 0
_Unchecked
int vsnprintf(char * restrict s : count(n), size_t n,
const char * restrict format,
va_list arg);
@ -95,9 +104,11 @@ int vsnprintf(char * restrict s : count(n), size_t n,
// va_list arg);
int fgetc(FILE *stream : itype(_Ptr<FILE>));
_Unchecked
char *fgets(char * restrict s : count(n), int n,
FILE * restrict stream : itype(restrict _Ptr<FILE>)) :
bounds(s, s + n);
_Unchecked
int fputs(const char * restrict s,
FILE * restrict stream : itype(restrict _Ptr<FILE>));
int getc(FILE *stream : itype(_Ptr<FILE>));
@ -131,3 +142,5 @@ int ferror(FILE *stream : itype(_Ptr<FILE>));
// void perror(const char *s);
#include "_builtin_stdio_checked.h"
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -10,30 +10,39 @@
/////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#pragma BOUNDS_CHECKED ON
// TODO: strings
// double atof(const char *s);
// int atoi(const char *s);
// long int atol(const char *s);
// long long int atoll(const char *s);
_Unchecked
double strtod(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>));
_Unchecked
float strtof(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>));
_Unchecked
long double strtold(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>));
_Unchecked
long int strtol(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>),
int base);
_Unchecked
long long int strtoll(const char * restrict nptr,
char ** restrict endptr : itype(restrict _Ptr<char *>),
int base);
_Unchecked
unsigned long int strtoul(const char * restrict nptr,
char ** restrict endptr :
itype(restrict _Ptr<char *>),
int base);
_Unchecked
unsigned long long int strtoull(const char * restrict nptr,
char ** restrict endptr:
itype(restrict _Ptr<char *>),
@ -85,10 +94,14 @@ int mbtowc(wchar_t * restrict output : itype(restrict _Ptr<wchar_t>),
//
// int wctomb(char *s : count(MB_CUR_MAX), wchar_t wc);
_Unchecked
size_t mbstowcs(wchar_t * restrict pwcs : count(n),
const char * restrict s,
size_t n);
_Unchecked
size_t wcstombs(char * restrict output : count(n),
const wchar_t * restrict pwcs,
size_t n);
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -12,16 +12,17 @@
/////////////////////////////////////////////////////////////////////////
#include <string.h>
#pragma BOUNDS_CHECKED ON
// TODO: Apple System Headers Support
#if !defined (__APPLE__) && _FORTIFY_SOURCE > 0
void *memcpy(void * restrict dest : byte_count(n),
const void * restrict src : byte_count(n),
size_t n) : bounds(dest, (char *) dest + n);
size_t n) : bounds(dest, (_Array_ptr<char>) dest + n);
void *memmove(void * restrict dest : byte_count(n),
const void * restrict src : byte_count(n),
size_t n) : bounds(dest, (char *)dest + n);
size_t n) : bounds(dest, (_Array_ptr<char>)dest + n);
#endif
// TODO: strings
// char *strcpy(char * restrict dest,
@ -36,7 +37,7 @@ void *memmove(void * restrict dest : byte_count(n),
#if !defined (__APPLE__) && _FORTIFY_SOURCE > 0
char *strncpy(char * restrict dest : count(n),
const char * restrict src : count(n),
size_t n) : bounds(dest, (char *)dest + n);
size_t n) : bounds(dest, (_Array_ptr<char>)dest + n);
#endif
// OMITTED INTENTIONALLY: this cannot be made checked.
@ -48,7 +49,7 @@ char *strncpy(char * restrict dest : count(n),
#ifndef __APPLE__
char *strncat(char * restrict dest : count(n),
const char * restrict src : count(n),
size_t n) : bounds(dest, (char *)dest + n);
size_t n) : bounds(dest, (_Array_ptr<char>)dest + n);
#endif
int memcmp(const void *src1 : byte_count(n), const void *src2 : byte_count(n),
@ -59,12 +60,14 @@ int memcmp(const void *src1 : byte_count(n), const void *src2 : byte_count(n),
// int strcoll(const char *src1, const char *src2);
int strncmp(const char *src : count(n), const char *s2 : count(n), size_t n);
_Unchecked
size_t strxfrm(char * restrict dest : count(n),
const char * restrict src,
size_t n);
void *memchr(const void *s : byte_count(n), int c, size_t n) :
bounds(s, (char *) s + n);
bounds(s, (_Array_ptr<char>) s + n);
// TODO: strings
// char *strchr(const char *s, int c);
@ -79,7 +82,7 @@ void *memchr(const void *s : byte_count(n), int c, size_t n) :
// TODO: Apple System Headers Support
#if !defined (__APPLE__) && _FORTIFY_SOURCE > 0
void *memset(void *s : byte_count(n), int c, size_t n) :
bounds(s, (char *) s + n);
bounds(s, (_Array_ptr<char>) s + n);
#endif
// TODO: strings
@ -87,3 +90,5 @@ void *memset(void *s : byte_count(n), int c, size_t n) :
// size_t strlen(const char *s);
#include "_builtin_string_checked.h"
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -23,6 +23,8 @@ struct timespec;
#include <threads.h>
#endif
#pragma BOUNDS_CHECKED ON
void call_once(once_flag *flag : itype(_Ptr<once_flag>),
void ((*fn)(void)) : itype(_Ptr<void (void)>));
@ -60,3 +62,5 @@ int tss_create(tss_t *key : itype(_Ptr<tss_t>),
// unchecked operation.
void *tss_get(tss_t key) : itype(_Ptr<void>);
int tss_set(tss_t key, void *value : itype(_Ptr<void>));
#pragma BOUNDS_CHECKED OFF

Просмотреть файл

@ -11,19 +11,30 @@
#include <time.h>
#pragma BOUNDS_CHECKED ON
time_t mktime(struct tm *timeptr : itype(_Ptr<struct tm>));
int timespec_get(struct timespec *ts : itype(_Ptr<struct timespec>),
int base);
_Unchecked
char *asctime(const struct tm *timeptr : itype(_Ptr<const struct tm>));
_Unchecked
char *ctime(const time_t *timer : itype(_Ptr<const time_t>));
struct tm *gmtime(const time_t *timer : itype(_Ptr<const time_t>)) :
itype(_Ptr<struct tm>);
struct tm *localtime(const time_t *timer : itype(_Ptr<const time_t>)) :
itype(_Ptr<struct tm>);
_Unchecked
size_t strftime(char * restrict output : count(maxsize),
size_t maxsize,
const char * restrict format,
const struct tm * restrict timeptr :
itype(restrict _Ptr<const struct tm>));
#pragma BOUNDS_CHECKED OFF