fix abort in classpath-openjdk.cpp due to buffer overflow

This addresses the case where -Djava.home=<some really long path>.

https://github.com/ReadyTalk/avian/issues/15
This commit is contained in:
Joel Dice 2012-10-03 09:43:51 -06:00
parent ab5ec510bf
commit 1ce012aa68

View File

@ -349,48 +349,66 @@ clearInterrupted(Thread*);
class MyClasspath : public Classpath { class MyClasspath : public Classpath {
public: public:
static const unsigned BufferSize = 1024;
MyClasspath(System* s, Allocator* allocator, const char* javaHome, MyClasspath(System* s, Allocator* allocator, const char* javaHome,
const char* embedPrefix): const char* embedPrefix):
allocator(allocator), ranNetOnLoad(0), ranManagementOnLoad(0) allocator(allocator), ranNetOnLoad(0), ranManagementOnLoad(0)
{ {
class StringBuilder { class StringBuilder {
public: public:
StringBuilder(System* s, char* pointer, unsigned remaining): StringBuilder(System* s, Allocator* allocator):
s(s), pointer(pointer), remaining(remaining) s(s),
allocator(allocator),
bufferSize(1024),
buffer(static_cast<char*>(allocator->allocate(bufferSize))),
offset(0)
{ } { }
void ensure(unsigned capacity) {
if (capacity > bufferSize) {
unsigned size = max(bufferSize * 2, capacity);
char* b = static_cast<char*>(allocator->allocate(size));
if (offset) {
memcpy(b, buffer, offset);
}
allocator->free(buffer, bufferSize);
buffer = b;
bufferSize = size;
}
}
void append(const char* append) { void append(const char* append) {
unsigned length = strlen(append); unsigned length = strlen(append);
expect(s, remaining > length); ensure(offset + length + 1);
strncpy(pointer, append, remaining); strncpy(buffer + offset, append, length + 1);
remaining -= length; offset += length;
pointer += length;
} }
void append(char c) { void append(char c) {
assert(s, remaining > 1); ensure(2);
pointer[0] = c; buffer[offset] = c;
pointer[1] = 0; buffer[offset + 1] = 0;
-- remaining; ++ offset;
++ pointer;
} }
System* s; System* s;
char* pointer; Allocator* allocator;
unsigned remaining; unsigned bufferSize;
} sb(s, buffer, BufferSize); char* buffer;
unsigned offset;
} sb(s, allocator);
this->javaHome = sb.pointer; unsigned javaHomeOffset = sb.offset;
sb.append(javaHome); sb.append(javaHome);
sb.append('\0'); sb.append('\0');
this->classpath = sb.pointer; unsigned classpathOffset = sb.offset;
sb.append(AVIAN_CLASSPATH); sb.append(AVIAN_CLASSPATH);
sb.append(s->pathSeparator()); sb.append(s->pathSeparator());
sb.append(javaHome); sb.append(javaHome);
@ -409,7 +427,7 @@ class MyClasspath : public Classpath {
sb.append("/lib/resources.jar"); sb.append("/lib/resources.jar");
sb.append('\0'); sb.append('\0');
this->libraryPath = sb.pointer; unsigned libraryPathOffset = sb.offset;
sb.append(javaHome); sb.append(javaHome);
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
sb.append("/bin"); sb.append("/bin");
@ -425,15 +443,23 @@ class MyClasspath : public Classpath {
#endif #endif
sb.append('\0'); sb.append('\0');
this->tzMappings = sb.pointer; unsigned tzMappingsOffset = sb.offset;
sb.append(javaHome); sb.append(javaHome);
sb.append("/lib/tzmappings"); sb.append("/lib/tzmappings");
this->tzMappingsLength = sb.pointer - tzMappings; this->tzMappingsLength = sb.offset - tzMappingsOffset;
sb.append('\0'); sb.append('\0');
this->embedPrefix = sb.pointer; unsigned embedPrefixOffset = sb.offset;
sb.append(embedPrefix); sb.append(embedPrefix);
this->embedPrefixLength = sb.pointer - this->embedPrefix; this->embedPrefixLength = sb.offset - embedPrefixOffset;
this->javaHome = sb.buffer + javaHomeOffset;
this->classpath = sb.buffer + classpathOffset;
this->libraryPath = sb.buffer + libraryPathOffset;
this->tzMappings = sb.buffer + tzMappingsOffset;
this->embedPrefix = sb.buffer + embedPrefixOffset;
this->buffer = sb.buffer;
this->bufferSize = sb.bufferSize;
} }
virtual object virtual object
@ -682,6 +708,7 @@ class MyClasspath : public Classpath {
virtual void virtual void
dispose() dispose()
{ {
allocator->free(buffer, bufferSize);
allocator->free(this, sizeof(*this)); allocator->free(this, sizeof(*this));
} }
@ -691,6 +718,8 @@ class MyClasspath : public Classpath {
const char* libraryPath; const char* libraryPath;
const char* tzMappings; const char* tzMappings;
const char* embedPrefix; const char* embedPrefix;
char* buffer;
unsigned bufferSize;
unsigned tzMappingsLength; unsigned tzMappingsLength;
unsigned embedPrefixLength; unsigned embedPrefixLength;
unsigned filePathField; unsigned filePathField;
@ -705,7 +734,6 @@ class MyClasspath : public Classpath {
unsigned zipEntryMethodField; unsigned zipEntryMethodField;
bool ranNetOnLoad; bool ranNetOnLoad;
bool ranManagementOnLoad; bool ranManagementOnLoad;
char buffer[BufferSize];
JmmInterface jmmInterface; JmmInterface jmmInterface;
}; };