Add support for fortified glibc functions (__fgets_chk, __read_chk, etc.).

This commit is contained in:
Sam Hocevar 2010-02-27 18:17:14 +00:00 committed by sam
parent 4c6ce1350e
commit 38c86c28ea
4 changed files with 180 additions and 90 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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
*/