mem: fix a buffer overflow bug in the mmap() replacement.
This commit is contained in:
parent
21cb084712
commit
8aa27ed6c6
@ -737,3 +737,28 @@ static void offset_check(int fd)
|
||||
errno = orig_errno;
|
||||
}
|
||||
|
||||
/* Utility function to know how many bytes are left until the end of
|
||||
* the file. */
|
||||
size_t _zz_bytes_until_eof(int fd, size_t offset)
|
||||
{
|
||||
int orig_errno = errno;
|
||||
#if defined HAVE_LSEEK64
|
||||
LOADSYM(lseek64);
|
||||
|
||||
off64_t current = ORIG(lseek64)(fd, 0, SEEK_CUR);
|
||||
off64_t begin = ORIG(lseek64)(fd, offset, SEEK_CUR);
|
||||
off64_t end = ORIG(lseek64)(fd, 0, SEEK_END);
|
||||
ORIG(lseek64)(fd, current, SEEK_SET);
|
||||
#else
|
||||
LOADSYM(lseek);
|
||||
|
||||
off_t current = ORIG(lseek)(fd, 0, SEEK_CUR);
|
||||
off_t begin = ORIG(lseek)(fd, offset, SEEK_CUR);
|
||||
off_t end = ORIG(lseek)(fd, 0, SEEK_END);
|
||||
ORIG(lseek)(fd, current, SEEK_SET);
|
||||
#endif
|
||||
errno = orig_errno;
|
||||
|
||||
return (begin >= end) ? 0 : (size_t)(end - begin);
|
||||
}
|
||||
|
||||
|
||||
@ -302,6 +302,7 @@ int nbmaps = 0;
|
||||
return ORIG(mymmap)(start, length, prot, flags, fd, offset); \
|
||||
\
|
||||
char *b = MAP_FAILED; \
|
||||
\
|
||||
ret = ORIG(mymmap)(NULL, length, prot, flags, fd, offset); \
|
||||
if (ret != MAP_FAILED && length) \
|
||||
{ \
|
||||
@ -326,13 +327,25 @@ int nbmaps = 0;
|
||||
} \
|
||||
maps[i] = b; \
|
||||
maps[i + 1] = ret; \
|
||||
\
|
||||
/* If we requested a memory area larger than the end of the
|
||||
* file, it was not actually allocated, so do not try to
|
||||
* copy data beyond that point. */ \
|
||||
size_t data_length = _zz_bytes_until_eof(fd, offset); \
|
||||
if (data_length > length) \
|
||||
data_length = length; \
|
||||
\
|
||||
oldpos = _zz_getpos(fd); \
|
||||
_zz_setpos(fd, offset); /* mmap() maps the fd at offset 0 */ \
|
||||
memcpy(b, ret, length); /* FIXME: get rid of this */ \
|
||||
/* FIXME: we should not blindly memcpy() here because the
|
||||
* memory area might be immense; instead, rely on mprotect()
|
||||
* and sigaction() to detect page faults and only copy memory
|
||||
* areas that get accessed. */ \
|
||||
memcpy(b, ret, data_length); \
|
||||
_zz_fuzz(fd, (uint8_t *)b, length); \
|
||||
_zz_setpos(fd, oldpos); \
|
||||
ret = b; \
|
||||
if (length >= 4) \
|
||||
if (data_length >= 4) \
|
||||
debug("%s(%p, %li, %i, %i, %i, %lli) = %p \"%c%c%c%c...", \
|
||||
__func__, start, (long int)length, prot, flags, fd, \
|
||||
(long long int)offset, ret, b[0], b[1], b[2], b[3]); \
|
||||
|
||||
@ -40,6 +40,9 @@ extern void _zz_fini(void) __attribute__((destructor));
|
||||
/* This function is needed to initialise memory functions */
|
||||
extern void _zz_mem_init(void);
|
||||
|
||||
/* This function lets us know where the end of a file is. */
|
||||
extern size_t _zz_bytes_until_eof(int fd, size_t offset);
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
extern CRITICAL_SECTION _zz_pipe_cs;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user