From 38c86c28ea98b937f59ea5e20bb95fa660aadcec Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 27 Feb 2010 18:17:14 +0000 Subject: [PATCH] Add support for fortified glibc functions (__fgets_chk, __read_chk, etc.). --- configure.ac | 7 +- msvc/config.h | 7 ++ src/libzzuf/lib-fd.c | 211 ++++++++++++++++++++++----------------- src/libzzuf/lib-stream.c | 45 +++++++++ 4 files changed, 180 insertions(+), 90 deletions(-) diff --git a/configure.ac b/configure.ac index f20cb74..292e6af 100644 --- a/configure.ac +++ b/configure.ac @@ -48,7 +48,12 @@ AC_SUBST(DLL_LDFLAGS) AC_CHECK_HEADERS(windows.h winsock2.h io.h process.h unistd.h inttypes.h stdint.h getopt.h libc.h malloc.h dlfcn.h regex.h sys/cdefs.h sys/socket.h netinet/in.h arpa/inet.h sys/uio.h aio.h sys/mman.h sys/wait.h sys/resource.h sys/time.h endian.h mach/task.h) AC_CHECK_FUNCS(setenv waitpid setrlimit gettimeofday fork kill pipe _pipe) -AC_CHECK_FUNCS(open64 __open64 lseek64 __lseek64 mmap64 fopen64 __fopen64 freopen64 __freopen64 dup dup2 ftello ftello64 __ftello64 fseeko fseeko64 __fseeko64 fsetpos64 __fsetpos64 _IO_getc getline getdelim __getdelim fgetln __srefill __filbuf __srget __uflow map_fd memalign posix_memalign aio_read accept bind connect socket readv pread recv recvfrom recvmsg mmap valloc sigaction getpagesize getc_unlocked getchar_unlocked fgetc_unlocked fread_unlocked fgets_unlocked) +AC_CHECK_FUNCS(dup dup2 ftello fseeko _IO_getc getline getdelim fgetln map_fd memalign posix_memalign aio_read accept bind connect socket readv pread recv recvfrom recvmsg mmap valloc sigaction getpagesize) +AC_CHECK_FUNCS(getc_unlocked getchar_unlocked fgetc_unlocked fread_unlocked fgets_unlocked) +AC_CHECK_FUNCS(__getdelim __srefill __filbuf __srget __uflow) +AC_CHECK_FUNCS(open64 lseek64 mmap64 fopen64 freopen64 ftello64 fseeko64 fsetpos64) +AC_CHECK_FUNCS(__open64 __lseek64 __fopen64 __freopen64 __ftello64 __fseeko64 __fsetpos64) +AC_CHECK_FUNCS(__fgets_chk __fgets_unlocked_chk __fread_chk __fread_unlocked_chk __read_chk __recv_chk __recvfrom_chk) AC_CHECK_TYPES(sighandler_t, [], [], [#define _GNU_SOURCE diff --git a/msvc/config.h b/msvc/config.h index fb0f7bb..2e940c1 100644 --- a/msvc/config.h +++ b/msvc/config.h @@ -103,8 +103,12 @@ #define HAVE_WINSOCK2_H 1 /* #undef HAVE__IO_GETC */ #define HAVE__PIPE 1 +/* #undef HAVE___FGETS_CHK */ +/* #undef HAVE___FGETS_UNLOCKED_CHK */ /* #undef HAVE___FILBUF */ /* #undef HAVE___FOPEN64 */ +/* #undef HAVE___FREAD_CHK */ +/* #undef HAVE___FREAD_UNLOCKED_CHK */ /* #undef HAVE___FREOPEN64 */ /* #undef HAVE___FSEEKO64 */ /* #undef HAVE___FSETPOS64 */ @@ -112,6 +116,9 @@ /* #undef HAVE___GETDELIM */ /* #undef HAVE___LSEEK64 */ /* #undef HAVE___OPEN64 */ +/* #undef HAVE___READ_CHK */ +/* #undef HAVE___RECVFROM_CHK */ +/* #undef HAVE___RECV_CHK */ /* #undef HAVE___SREFILL */ /* #undef HAVE___SRGET */ /* #undef HAVE___UFLOW */ diff --git a/src/libzzuf/lib-fd.c b/src/libzzuf/lib-fd.c index d707afb..66d6a3c 100644 --- a/src/libzzuf/lib-fd.c +++ b/src/libzzuf/lib-fd.c @@ -122,10 +122,17 @@ static int (*ORIG(socket)) (int domain, int type, int protocol); #if defined HAVE_RECV static RECV_T (*ORIG(recv)) (int s, void *buf, size_t len, int flags); #endif +#if defined HAVE___RECV_CHK +static RECV_T (*ORIG(__recv_chk)) (int s, void *buf, size_t len, int flags); +#endif #if defined HAVE_RECVFROM static RECV_T (*ORIG(recvfrom))(int s, void *buf, size_t len, int flags, SOCKADDR_T *from, SOCKLEN_T *fromlen); #endif +#if defined HAVE___RECVFROM_CHK +static RECV_T (*ORIG(__recvfrom_chk))(int s, void *buf, size_t len, int flags, + SOCKADDR_T *from, SOCKLEN_T *fromlen); +#endif #if defined HAVE_RECVMSG static RECV_T (*ORIG(recvmsg)) (int s, struct msghdr *hdr, int flags); #endif @@ -134,6 +141,9 @@ static ssize_t (*ORIG(read)) (int fd, void *buf, size_t count); #else static int (*ORIG(read)) (int fd, void *buf, unsigned int count); #endif +#if defined HAVE___READ_CHK +static ssize_t (*ORIG(__read_chk)) (int fd, void *buf, size_t count); +#endif #if defined HAVE_READV static ssize_t (*ORIG(readv)) (int fd, const struct iovec *iov, int count); #endif @@ -352,78 +362,91 @@ int NEW(socket)(int domain, int type, int protocol) } #endif +#define ZZ_RECV(myrecv) \ + do \ + { \ + LOADSYM(myrecv); \ + ret = ORIG(myrecv)(s, buf, len, flags); \ + if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) \ + || _zz_islocked(s) || !_zz_isactive(s)) \ + return ret; \ + if(ret > 0) \ + { \ + char *b = buf; \ + _zz_fuzz(s, buf, ret); \ + _zz_addpos(s, ret); \ + if(ret >= 4) \ + debug("%s(%i, %p, %li, 0x%x) = %i \"%c%c%c%c...", __func__, \ + s, buf, (long int)len, flags, ret, \ + b[0], b[1], b[2], b[3]); \ + else \ + debug("%s(%i, %p, %li, 0x%x) = %i \"%c...", __func__, \ + s, buf, (long int)len, flags, ret, b[0]); \ + } \ + else \ + debug("%s(%i, %p, %li, 0x%x) = %i", __func__, \ + s, buf, (long int)len, flags, ret); \ + } while(0); + #if defined HAVE_RECV RECV_T NEW(recv)(int s, void *buf, size_t len, int flags) { - int ret; - - LOADSYM(recv); - ret = ORIG(recv)(s, buf, len, flags); - if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) - || _zz_islocked(s) || !_zz_isactive(s)) - return ret; - - if(ret > 0) - { - char *b = buf; - - _zz_fuzz(s, buf, ret); - _zz_addpos(s, ret); - - if(ret >= 4) - debug("%s(%i, %p, %li, 0x%x) = %i \"%c%c%c%c...", __func__, - s, buf, (long int)len, flags, ret, b[0], b[1], b[2], b[3]); - else - debug("%s(%i, %p, %li, 0x%x) = %i \"%c...", __func__, - s, buf, (long int)len, flags, ret, b[0]); - } - else - debug("%s(%i, %p, %li, 0x%x) = %i", __func__, - s, buf, (long int)len, flags, ret); - - return ret; + int ret; ZZ_RECV(recv); return ret; } #endif +#if defined HAVE___RECV_CHK +RECV_T NEW(__recv_chk)(int s, void *buf, size_t len, int flags) +{ + int ret; ZZ_RECV(__recv_chk); return ret; +} +#endif + +#define ZZ_RECVFROM(myrecvfrom) \ + do \ + { \ + LOADSYM(myrecvfrom); \ + ret = ORIG(myrecvfrom)(s, buf, len, flags, from, fromlen); \ + if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) \ + || _zz_islocked(s) || !_zz_isactive(s)) \ + return ret; \ + if(ret > 0) \ + { \ + char tmp[128]; \ + char *b = buf; \ + _zz_fuzz(s, buf, ret); \ + _zz_addpos(s, ret); \ + if (fromlen) \ + sprintf(tmp, "&%i", (int)*fromlen); \ + else \ + strcpy(tmp, "NULL"); \ + if (ret >= 4) \ + debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c%c%c%c...", \ + __func__, s, buf, (long int)len, flags, from, tmp, \ + ret, b[0], b[1], b[2], b[3]); \ + else \ + debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c...", \ + __func__, s, buf, (long int)len, flags, from, tmp, \ + ret, b[0]); \ + } \ + else \ + debug("%s(%i, %p, %li, 0x%x, %p, %p) = %i", __func__, \ + s, buf, (long int)len, flags, from, fromlen, ret); \ + } while(0) + #if defined HAVE_RECVFROM RECV_T NEW(recvfrom)(int s, void *buf, size_t len, int flags, SOCKADDR_T *from, SOCKLEN_T *fromlen) { - int ret; + int ret; ZZ_RECVFROM(recvfrom); return ret; +} +#endif - LOADSYM(recvfrom); - ret = ORIG(recvfrom)(s, buf, len, flags, from, fromlen); - if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) - || _zz_islocked(s) || !_zz_isactive(s)) - return ret; - - if(ret > 0) - { - char tmp[128]; - char *b = buf; - - _zz_fuzz(s, buf, ret); - _zz_addpos(s, ret); - - if (fromlen) - sprintf(tmp, "&%i", (int)*fromlen); - else - strcpy(tmp, "NULL"); - - if (ret >= 4) - debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c%c%c%c...", - __func__, s, buf, (long int)len, flags, from, tmp, - ret, b[0], b[1], b[2], b[3]); - else - debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c...", - __func__, s, buf, (long int)len, flags, from, tmp, - ret, b[0]); - } - else - debug("%s(%i, %p, %li, 0x%x, %p, %p) = %i", __func__, - s, buf, (long int)len, flags, from, fromlen, ret); - - return ret; +#if defined HAVE___RECVFROM_CHK +RECV_T NEW(__recvfrom_chk)(int s, void *buf, size_t len, int flags, + SOCKADDR_T *from, SOCKLEN_T *fromlen) +{ + int ret; ZZ_RECVFROM(__recvfrom_chk); return ret; } #endif @@ -445,40 +468,50 @@ RECV_T NEW(recvmsg)(int s, struct msghdr *hdr, int flags) } #endif +#define ZZ_READ(myread) \ + do \ + { \ + LOADSYM(myread); \ + ret = ORIG(read)(fd, buf, count); \ + if(!_zz_ready || !_zz_iswatched(fd) || !_zz_hostwatched(fd) \ + || _zz_islocked(fd) || !_zz_isactive(fd)) \ + return ret; \ + if(ret > 0) \ + { \ + char *b = buf; \ + _zz_fuzz(fd, buf, ret); \ + _zz_addpos(fd, ret); \ + if(ret >= 4) \ + debug("%s(%i, %p, %li) = %i \"%c%c%c%c...", __func__, fd, \ + buf, (long int)count, ret, b[0], b[1], b[2], b[3]); \ + else \ + debug("%s(%i, %p, %li) = %i \"%c...", __func__, fd, \ + buf, (long int)count, ret, b[0]); \ + } \ + else \ + debug("%s(%i, %p, %li) = %i", __func__, fd, \ + buf, (long int)count, ret); \ + offset_check(fd); \ + } while(0) + #if defined READ_USES_SSIZE_T ssize_t NEW(read)(int fd, void *buf, size_t count) +{ + int ret; ZZ_READ(read); return (ssize_t)ret; +} #else int NEW(read)(int fd, void *buf, unsigned int count) -#endif { - int ret; - - LOADSYM(read); - ret = ORIG(read)(fd, buf, count); - if(!_zz_ready || !_zz_iswatched(fd) || !_zz_hostwatched(fd) - || _zz_islocked(fd) || !_zz_isactive(fd)) - return ret; - - if(ret > 0) - { - char *b = buf; - - _zz_fuzz(fd, buf, ret); - _zz_addpos(fd, ret); - - if(ret >= 4) - debug("%s(%i, %p, %li) = %i \"%c%c%c%c...", __func__, fd, buf, - (long int)count, ret, b[0], b[1], b[2], b[3]); - else - debug("%s(%i, %p, %li) = %i \"%c...", __func__, fd, buf, - (long int)count, ret, b[0]); - } - else - debug("%s(%i, %p, %li) = %i", __func__, fd, buf, (long int)count, ret); - - offset_check(fd); - return ret; + int ret; ZZ_READ(read); return ret; } +#endif + +#if defined HAVE___READ_CHK +ssize_t NEW(__read_chk)(int fd, void *buf, size_t count) +{ + int ret; ZZ_READ(__read_chk); return (ssize_t)ret; +} +#endif #if defined HAVE_READV ssize_t NEW(readv)(int fd, const struct iovec *iov, int count) diff --git a/src/libzzuf/lib-stream.c b/src/libzzuf/lib-stream.c index 7f53f14..f9af751 100644 --- a/src/libzzuf/lib-stream.c +++ b/src/libzzuf/lib-stream.c @@ -109,6 +109,14 @@ static size_t (*ORIG(fread)) (void *ptr, size_t size, size_t nmemb, static size_t (*ORIG(fread_unlocked)) (void *ptr, size_t size, size_t nmemb, FILE *stream); #endif +#if defined HAVE___FREAD_CHK +static size_t (*ORIG(__fread_chk)) (void *ptr, size_t size, size_t nmemb, + FILE *stream); +#endif +#if defined HAVE___FREAD_UNLOCKED_CHK +static size_t (*ORIG(__fread_unlocked_chk)) (void *ptr, size_t size, + size_t nmemb, FILE *stream); +#endif static int (*ORIG(getc)) (FILE *stream); static int (*ORIG(getchar)) (void); static int (*ORIG(fgetc)) (FILE *stream); @@ -128,6 +136,12 @@ static char * (*ORIG(fgets)) (char *s, int size, FILE *stream); #if defined HAVE_FGETS_UNLOCKED static char * (*ORIG(fgets_unlocked)) (char *s, int size, FILE *stream); #endif +#if defined HAVE___FGETS_CHK +static char * (*ORIG(__fgets_chk)) (char *s, int size, FILE *stream); +#endif +#if defined HAVE___FGETS_UNLOCKED_CHK +static char * (*ORIG(__fgets_unlocked_chk)) (char *s, int size, FILE *stream); +#endif static int (*ORIG(ungetc)) (int c, FILE *stream); static int (*ORIG(fclose)) (FILE *fp); @@ -537,6 +551,23 @@ size_t NEW(fread_unlocked)(void *ptr, size_t size, size_t nmemb, FILE *stream) } #endif +#if defined HAVE___FREAD_CHK +#undef __fread_chk +size_t NEW(__fread_chk)(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t ret; ZZ_FREAD(__fread_chk); return ret; +} +#endif + +#if defined HAVE___FREAD_UNLOCKED_CHK +#undef __fread_unlocked_chk +size_t NEW(__fread_unlocked_chk)(void *ptr, size_t size, size_t nmemb, + FILE *stream) +{ + size_t ret; ZZ_FREAD(__fread_unlocked_chk); return ret; +} +#endif + /* * getc, getchar, fgetc etc. * @@ -721,6 +752,20 @@ char *NEW(fgets_unlocked)(char *s, int size, FILE *stream) } #endif +#if defined HAVE___FGETS_CHK +char *NEW(__fgets_chk)(char *s, int size, FILE *stream) +{ + char *ret; ZZ_FGETS(__fgets_chk, fgetc); return ret; +} +#endif + +#if defined HAVE___FGETS_UNLOCKED_CHK +char *NEW(__fgets_unlocked_chk)(char *s, int size, FILE *stream) +{ + char *ret; ZZ_FGETS(__fgets_unlocked_chk, fgetc_unlocked); return ret; +} +#endif + /* * ungetc */