summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-06-07 15:47:42 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-06-07 15:47:42 +0000
commit5137a26a6f1f06efc060217617d36318d8ac6c59 (patch)
tree5b66b03a1084a66c6de6dc7c4669284337f63db2 /src
parentca0b64db5036b8956ec9619ce786c991ec839759 (diff)
Fix for segfault if a user quits before their ident is complete, due to session limit reached
Do this by checking their pointer in the fd_ref_table against the pointer we got when we started the lookup, so we can know if its been invalidated or not (just in case the OnClose occurs before we NULL the user) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3992 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r--src/modules/m_ident.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp
index d1a399df3..c415741b2 100644
--- a/src/modules/m_ident.cpp
+++ b/src/modules/m_ident.cpp
@@ -23,6 +23,8 @@ using namespace std;
#include "modules.h"
#include "inspircd.h"
+extern userrec* fd_ref_table[MAX_DESCRIPTORS];
+
/* $ModDesc: Provides support for RFC 1413 ident lookups */
// Version 1.5.0.0 - Updated to use InspSocket, faster and neater.
@@ -39,8 +41,9 @@ class RFC1413 : public InspSocket
public:
userrec* u; // user record that the lookup is associated with
+ int ufd;
- RFC1413(userrec* user, int maxtime, Server* S) : InspSocket((char*)inet_ntoa(user->ip4), 113, false, maxtime), Srv(S), u(user)
+ RFC1413(userrec* user, int maxtime, Server* S) : InspSocket((char*)inet_ntoa(user->ip4), 113, false, maxtime), Srv(S), u(user), ufd(user->fd)
{
Srv->Log(DEBUG,"Ident: associated.");
}
@@ -49,7 +52,7 @@ class RFC1413 : public InspSocket
{
// When we timeout, the connection failed within the allowed timeframe,
// so we just display a notice, and tidy off the ident_data.
- if (u)
+ if (u && (fd_ref_table[ufd] == u))
{
u->Shrink("ident_data");
Srv->SendServ(u->fd,"NOTICE "+std::string(u->nick)+" :*** Could not find your ident, using "+std::string(u->ident)+" instead.");
@@ -80,7 +83,7 @@ class RFC1413 : public InspSocket
*j = '\0'; // truncate at invalid chars
if (*section)
{
- if (u)
+ if (u && (fd_ref_table[ufd] == u))
{
strlcpy(u->ident,section,IDENTMAX);
Srv->Log(DEBUG,"IDENT SET: "+std::string(u->ident));
@@ -101,7 +104,24 @@ class RFC1413 : public InspSocket
{
// tidy up after ourselves when the connection is done.
// We receive this event straight after a timeout, too.
- if (u)
+ //
+ //
+ // OK, now listen up. The weird looking check here is
+ // REQUIRED. Don't try and optimize it away.
+ //
+ // When a socket is closed, it is not immediately removed
+ // from the socket list, there can be a short delay
+ // before it is culled from the list. This means that
+ // without this check, there is a chance that a user
+ // may not exist when we come to ::Shrink them, which
+ // results in a segfault. The value of "u" may not
+ // always be NULL at this point, so, what we do is
+ // check against the fd_ref_table, to see if (1) the user
+ // exists, and (2) its the SAME user, on the same file
+ // descriptor that they were when the lookup began.
+ //
+ // Fixes issue reported by webs, 7 Jun 2006
+ if (u && (fd_ref_table[ufd] == u))
{
u->Shrink("ident_data");
}
@@ -109,7 +129,7 @@ class RFC1413 : public InspSocket
virtual void OnError(InspSocketError e)
{
- if (u)
+ if (u && (fd_ref_table[ufd] == u))
{
u->Shrink("ident_data");
}
@@ -117,7 +137,7 @@ class RFC1413 : public InspSocket
virtual bool OnConnected()
{
- if (u)
+ if (u && (fd_ref_table[ufd] == u))
{
uslen = sizeof(sock_us);
themlen = sizeof(sock_them);