summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2019-09-19 12:24:06 +0200
committerPatrick Steinhardt <ps@pks.im>2019-09-21 15:20:28 +0200
commit174b7a32d2ab480e4f3547758cf6c5ed30bbf5f4 (patch)
treed5c03803ef1ee06493859cb874a434b9f9140dca /src/buffer.c
parent208f1d7a4d9603ec6781ed18c10b240c7c5d2e33 (diff)
downloadlibgit2-174b7a32d2ab480e4f3547758cf6c5ed30bbf5f4.tar.gz
buffer: fix printing into out-of-memory buffer
Before printing into a `git_buf` structure, we always call `ENSURE_SIZE` first. This macro will reallocate the buffer as-needed depending on whether the current amount of allocated bytes is sufficient or not. If `asize` is big enough, then it will just do nothing, otherwise it will call out to `git_buf_try_grow`. But in fact, it is insufficient to only check `asize`. When we fail to allocate any more bytes e.g. via `git_buf_try_grow`, then we set the buffer's pointer to `git_buf__oom`. Note that we touch neither `asize` nor `size`. So if we just check `asize > targetsize`, then we will happily let the caller of `ENSURE_SIZE` proceed with an out-of-memory buffer. As a result, we will print all bytes into the out-of-memory buffer instead, resulting in an out-of-bounds write. Fix the issue by having `ENSURE_SIZE` verify that the buffer is not marked as OOM. Add a test to verify that we're not writing into the OOM buffer.
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/buffer.c b/src/buffer.c
index dff2c37eb..61cf9675b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -18,7 +18,8 @@ char git_buf__initbuf[1];
char git_buf__oom[1];
#define ENSURE_SIZE(b, d) \
- if ((d) > (b)->asize && git_buf_grow((b), (d)) < 0)\
+ if ((b)->ptr == git_buf__oom || \
+ ((d) > (b)->asize && git_buf_grow((b), (d)) < 0))\
return -1;