View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001988 | unreal | ircd | public | 2004-07-22 15:29 | 2004-07-22 17:48 |
| Reporter | SET | Assigned To | |||
| Priority | normal | Severity | crash | Reproducibility | always |
| Status | closed | Resolution | open | ||
| Product Version | 3.2.1 | ||||
| Summary | 0001988: HOOKTYPE_SERVER_QUIT crashes on local netsplit | ||||
| Description | If a module adds a HOOKTYPE_SERVER_QUIT everything works fine if a remote servers SQUITs. But if it's a locally connected server and there a some servers behind it, it crashes. The problem is the function that SQUITs all servers that are downstream of the server that was lost. It calls the SERVER_QUIT twice, once before and once after freeing the server struct. | ||||
| Steps To Reproduce | 1. Write a module that adds a HOOKTYPE_SERVER_QUIT and accesss a few of the struct members. 2. SQUIT a local server with some servers behind it. 3. Crash. Or maybe not. But the hook is called twice for every server behind the SQUITed one. The hook is called immediately after freeing the struct so it *usually* doesn't crash. But mallocing some memory before accessing the server struct should crash the server every time. | ||||
| Additional Information | The bug is in the file src/s_misc.c function exit_client() line 604. src/s_misc.c:593:605: /* * Now, go SQUIT off the servers which are down-stream of * the one we just lost. */ recurse++; for (acptr = client; acptr; acptr = next) { next = acptr->next; if (IsServer(acptr) && acptr->srvptr == sptr) { exit_client(sptr, acptr, /* RECURSION */ sptr, comment1); <-- this function calls the hook for acptr and then frees the server struct. RunHook(HOOKTYPE_SERVER_QUIT, acptr); <-- acptr is no longer a valid pointer. Just delete this line and everything works fine. } | ||||
| 3rd party modules | |||||