diff options
author | Arne H Juul <arnej@yahoo-inc.com> | 2016-11-11 14:45:26 +0100 |
---|---|---|
committer | Arne H Juul <arnej@yahoo-inc.com> | 2016-11-11 14:47:32 +0100 |
commit | 0ef1ae5bbd397b28586694c7ab7775e269fd5798 (patch) | |
tree | fb7cf8e2164f81468dad266f610eb89abb355a99 /vespalog/src | |
parent | d12a79dfeb505691ecf28604814e88b14bca2b65 (diff) |
avoid possible memory overrun in strchr()
* add a loop to look for newlines that takes the known
file size into account so we don't risk accessing
outside the valid mapped area.
* also, add a log warning (acting as explanation for
this-should-not-happen handling code).
Diffstat (limited to 'vespalog/src')
-rw-r--r-- | vespalog/src/vespa/log/control-file.cpp | 19 | ||||
-rw-r--r-- | vespalog/src/vespa/log/control-file.h | 3 |
2 files changed, 18 insertions, 4 deletions
diff --git a/vespalog/src/vespa/log/control-file.cpp b/vespalog/src/vespa/log/control-file.cpp index 70833847905..391a2522538 100644 --- a/vespalog/src/vespa/log/control-file.cpp +++ b/vespalog/src/vespa/log/control-file.cpp @@ -144,6 +144,18 @@ ControlFile::pageAlign(unsigned int len) } char * +ControlFile::nextNewline(char *addr) +{ + if (addr < _mapBase) return NULL; + char *end = _mapBase + _fileSize; + while (addr < end) { + if (*addr == '\n') return addr; + ++addr; + } + return NULL; +} + +char * ControlFile::alignLevels(char *addr) { unsigned long x = reinterpret_cast<unsigned long>(addr); @@ -424,12 +436,13 @@ Component * ComponentIterator::next() { Component *ret = NULL; - if (_next && _cf->insideFile(_next) && _next[0]) { - char *nn = strchr(_next, '\n'); - if (nn && _cf->insideFile(nn)) { + if (_next) { + char *nn = _cf->nextNewline(_next); + if (nn) { ret = new Component(_next); _next = ++nn; if (nn != ret->endPointer()) { + LOG(warning, "mismatch between component size and line size, aborting ComponentIterator loop"); delete ret; ret = NULL; _next = NULL; diff --git a/vespalog/src/vespa/log/control-file.h b/vespalog/src/vespa/log/control-file.h index 886f38791ba..f3d42251441 100644 --- a/vespalog/src/vespa/log/control-file.h +++ b/vespalog/src/vespa/log/control-file.h @@ -35,6 +35,8 @@ private: int _mappedSize; char *_firstComponent; + char *nextNewline(char *p); + static const int _maxMapSize = 200000; static const int _maxPrefix = 64; @@ -57,7 +59,6 @@ public: ~ControlFile(); unsigned int *getLevels(const char *name); void ensureComponent(const char *pattern); - bool insideFile(char *p) { return (p >= _mapBase) && (p < _mapBase + _fileSize); } static unsigned int *defaultLevels(); |