Fixed a performance issue involving std::string and EQStream identification.

Fixed a denial-of-service exploit in EQStream.
This commit is contained in:
SecretsOTheP 2014-02-15 23:50:32 -05:00
parent 46f8723314
commit 1ebf88abbb
3 changed files with 11 additions and 10 deletions

View File

@ -144,7 +144,8 @@ void EQStreamFactory::Push(EQStream *s)
void EQStreamFactory::ReaderLoop() void EQStreamFactory::ReaderLoop()
{ {
fd_set readset; fd_set readset;
std::map<std::string,EQStream *>::iterator stream_itr; std::map<std::pair<uint32, uint16>,EQStream *>::iterator stream_itr;
EQStream* currStream = NULL;
int num; int num;
int length; int length;
unsigned char buffer[2048]; unsigned char buffer[2048];
@ -183,14 +184,13 @@ timeval sleep_time;
{ {
// What do we wanna do? // What do we wanna do?
} else { } else {
char temp[25];
sprintf(temp,"%u.%d",ntohl(from.sin_addr.s_addr),ntohs(from.sin_port));
MStreams.lock(); MStreams.lock();
if ((stream_itr=Streams.find(temp))==Streams.end()) { stream_itr=Streams.find(std::make_pair(from.sin_addr.s_addr, from.sin_port));
if (stream_itr == Streams.end()) {
if (buffer[1]==OP_SessionRequest) { if (buffer[1]==OP_SessionRequest) {
EQStream *s = new EQStream(from); EQStream *s = new EQStream(from);
s->SetStreamType(StreamType); s->SetStreamType(StreamType);
Streams[temp]=s; Streams[std::make_pair(from.sin_addr.s_addr, from.sin_port)]=s;
WriterWork.Signal(); WriterWork.Signal();
Push(s); Push(s);
s->AddBytesRecv(length); s->AddBytesRecv(length);
@ -225,7 +225,7 @@ void EQStreamFactory::CheckTimeout()
MStreams.lock(); MStreams.lock();
unsigned long now=Timer::GetCurrentTime(); unsigned long now=Timer::GetCurrentTime();
std::map<std::string,EQStream *>::iterator stream_itr; std::map<std::pair<uint32, uint16>,EQStream *>::iterator stream_itr;
for(stream_itr=Streams.begin();stream_itr!=Streams.end();) { for(stream_itr=Streams.begin();stream_itr!=Streams.end();) {
EQStream *s = stream_itr->second; EQStream *s = stream_itr->second;
@ -241,7 +241,7 @@ void EQStreamFactory::CheckTimeout()
} else { } else {
//everybody is done, we can delete it now //everybody is done, we can delete it now
//std::cout << "Removing connection" << std::endl; //std::cout << "Removing connection" << std::endl;
std::map<std::string,EQStream *>::iterator temp=stream_itr; std::map<std::pair<uint32, uint16>,EQStream *>::iterator temp=stream_itr;
stream_itr++; stream_itr++;
//let whoever has the stream outside delete it //let whoever has the stream outside delete it
delete temp->second; delete temp->second;
@ -257,7 +257,7 @@ void EQStreamFactory::CheckTimeout()
void EQStreamFactory::WriterLoop() void EQStreamFactory::WriterLoop()
{ {
std::map<std::string,EQStream *>::iterator stream_itr; std::map<std::pair<uint32, uint16>,EQStream *>::iterator stream_itr;
bool havework=true; bool havework=true;
std::vector<EQStream *> wants_write; std::vector<EQStream *> wants_write;
std::vector<EQStream *>::iterator cur,end; std::vector<EQStream *>::iterator cur,end;
@ -292,7 +292,7 @@ Timer DecayTimer(20);
//bullshit checking, to see if this is really happening, GDB seems to think so... //bullshit checking, to see if this is really happening, GDB seems to think so...
if(stream_itr->second == nullptr) { if(stream_itr->second == nullptr) {
fprintf(stderr, "ERROR: nullptr Stream encountered in EQStreamFactory::WriterLoop for: %s", stream_itr->first.c_str()); fprintf(stderr, "ERROR: nullptr Stream encountered in EQStreamFactory::WriterLoop for: %i", stream_itr->first.first, stream_itr->first.second);
continue; continue;
} }

View File

@ -27,7 +27,7 @@ class EQStreamFactory : private Timeoutable {
std::queue<EQStream *> NewStreams; std::queue<EQStream *> NewStreams;
Mutex MNewStreams; Mutex MNewStreams;
std::map<std::string,EQStream *> Streams; std::map<std::pair<uint32, uint16>,EQStream *> Streams;
Mutex MStreams; Mutex MStreams;
virtual void CheckTimeout(); virtual void CheckTimeout();

View File

@ -56,6 +56,7 @@ void EQStreamIdentifier::Process() {
//if stream hasn't finished initializing then continue; //if stream hasn't finished initializing then continue;
if(r->stream->GetState() == UNESTABLISHED) if(r->stream->GetState() == UNESTABLISHED)
{ {
cur++;
continue; continue;
} }
if(r->stream->GetState() != ESTABLISHED) { if(r->stream->GetState() != ESTABLISHED) {