Skip to content

Commit

Permalink
Add validation for adding global handles
Browse files Browse the repository at this point in the history
We want to make sure people are only adding valid handles to the list of
global handles. This means that the VALUE pointer in the CAPI needs to
point to a proper CAPI handle and not point to some random memory
location that can cause things such as GC crashes later on.

Should help in debugging stuff like therubyracer to see earlier where
extensions such as that register invalid handles.
  • Loading branch information
dbussink committed Jul 30, 2012
1 parent d72d8b0 commit b2dc727
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 0 deletions.
4 changes: 4 additions & 0 deletions vm/capi/handles.cpp
Expand Up @@ -34,6 +34,10 @@ namespace rubinius {
return allocator_->from_index(index);
}

bool Handles::validate(Handle* handle) {
return allocator_->validate(handle);
}

Handles::~Handles() {
for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
Handle* chunk = allocator_->chunks_[i];
Expand Down
2 changes: 2 additions & 0 deletions vm/capi/handles.hpp
Expand Up @@ -31,6 +31,8 @@ namespace rubinius {
uintptr_t allocate_index(STATE, Object* obj);
Handle* find_index(STATE, uintptr_t index);

bool validate(Handle* handle);

void deallocate_handles(std::list<Handle*>* cached, int mark, BakerGC* young);

void flush_all(NativeMethodEnvironment* env);
Expand Down
7 changes: 7 additions & 0 deletions vm/shared_state.cpp
Expand Up @@ -8,6 +8,7 @@
#include "instruments/timing.hpp"
#include "global_cache.hpp"
#include "capi/handles.hpp"
#include "capi/tag.hpp"

#include "util/thread.hpp"
#include "inline_cache.hpp"
Expand Down Expand Up @@ -170,6 +171,12 @@ namespace rubinius {
const char* file, int line)
{
SYNC_TL;
if(*loc && REFERENCE_P(*loc)) {
if(!global_handles_->validate(*loc)) {
rubinius::bug("Adding invalid handle\n");
}
}

capi::GlobalHandle* global_handle = new capi::GlobalHandle(loc, file, line);
global_handle_locations_.push_back(global_handle);
}
Expand Down
10 changes: 10 additions & 0 deletions vm/util/allocator.hpp
Expand Up @@ -79,6 +79,16 @@ namespace rubinius {
return chunks_[index / cChunkSize] + (index % cChunkSize);
}

bool validate(T* ptr) {
for(typename std::vector<T*>::iterator i = chunks_.begin(); i != chunks_.end(); ++i) {
T* chunk = *i;
if(ptr >= chunk && ptr < (chunk + cChunkSize)) {
return true;
}
}
return false;
}

void rebuild_freelist(std::vector<bool>* chunk_marks) {
free_list_ = (uintptr_t)-1;
in_use_ = 0;
Expand Down

0 comments on commit b2dc727

Please sign in to comment.