Commit 8d534b47 by Edward Thomson Committed by Edward Thomson

p_read: ensure requested len is ssize_t

Ensure that the given length to `p_read` is of ssize_t and ensure
that callers test the return as if it were an `ssize_t`.
parent ec3b4d35
...@@ -127,6 +127,11 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) ...@@ -127,6 +127,11 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
git_buf_clear(buf); git_buf_clear(buf);
if (!git__is_ssizet(len)) {
giterr_set(GITERR_INVALID, "Read too large.");
return -1;
}
GITERR_CHECK_ALLOC_ADD(len, 1); GITERR_CHECK_ALLOC_ADD(len, 1);
if (git_buf_grow(buf, len + 1) < 0) if (git_buf_grow(buf, len + 1) < 0)
return -1; return -1;
......
...@@ -155,6 +155,14 @@ ssize_t p_read(git_file fd, void *buf, size_t cnt) ...@@ -155,6 +155,14 @@ ssize_t p_read(git_file fd, void *buf, size_t cnt)
{ {
char *b = buf; char *b = buf;
if (!git__is_ssizet(cnt)) {
#ifdef GIT_WIN32
SetLastError(ERROR_INVALID_PARAMETER);
#endif
errno = EINVAL;
return -1;
}
while (cnt) { while (cnt) {
ssize_t r; ssize_t r;
#ifdef GIT_WIN32 #ifdef GIT_WIN32
...@@ -229,7 +237,9 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs ...@@ -229,7 +237,9 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
out->data = malloc(len); out->data = malloc(len);
GITERR_CHECK_ALLOC(out->data); GITERR_CHECK_ALLOC(out->data);
if ((p_lseek(fd, offset, SEEK_SET) < 0) || ((size_t)p_read(fd, out->data, len) != len)) { if (!git__is_ssizet(len) ||
(p_lseek(fd, offset, SEEK_SET) < 0) ||
(p_read(fd, out->data, len) != (ssize_t)len)) {
giterr_set(GITERR_OS, "mmap emulation failed"); giterr_set(GITERR_OS, "mmap emulation failed");
return -1; return -1;
} }
......
...@@ -153,6 +153,13 @@ GIT_INLINE(int) git__is_sizet(git_off_t p) ...@@ -153,6 +153,13 @@ GIT_INLINE(int) git__is_sizet(git_off_t p)
return p == (git_off_t)r; return p == (git_off_t)r;
} }
/** @return true if p fits into the range of an ssize_t */
GIT_INLINE(int) git__is_ssizet(size_t p)
{
ssize_t r = (ssize_t)p;
return p == (size_t)r;
}
/** @return true if p fits into the range of a uint32_t */ /** @return true if p fits into the range of a uint32_t */
GIT_INLINE(int) git__is_uint32(size_t p) GIT_INLINE(int) git__is_uint32(size_t p)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment