Package: aprsd Version: 1:2.2.5-13-5.1 Severity: important Tags: patch
https://bugs.launchpad.net/ubuntu/+source/aprsd/+bug/208913 aprsd on 64-bit system crashes with segfault while trying to process the "user" login line on any of its incoming user ports. To reproduce, simply connect to aprsd on port 14500 (e.g. with 'telnet hostname 14500') and type "user foo<ENTER>". Aprsd crashes with segfault. Note that this allows for a denial-of-service exposure in that any user (even remote users) can crash aprsd easily, as well as making aprsd unusable in conjunction with local clients e.g. xastir. The attached patch fixes the problem.
# 0001.fix-user-login-crash.patch # # Author: Kamal Mostafa <ka...@whence.com> # # * Fix "user" login crash on 64-bit platforms. (LP: #208913) # * Fix socklen_t compiler warnings (and possible failure) on 64-bit platforms. # === modified file 'src/aprsString.cpp' --- a/src/aprsString.cpp 2003-06-20 22:30:49 +0000 +++ b/src/aprsString.cpp 2009-12-26 08:35:38 +0000 @@ -905,9 +905,9 @@ //Returns index of path element if match found // or npos is not found. -unsigned aprsString::queryPath(const string& s, int start, int stop , unsigned n) +size_t aprsString::queryPath(const string& s, int start, int stop , size_t n) { - unsigned rc = npos; + size_t rc = npos; if (valid_ax25 == false) return rc; === modified file 'src/aprsString.h' --- a/src/aprsString.h 2006-05-25 18:22:50 +0000 +++ b/src/aprsString.h 2009-12-26 08:35:24 +0000 @@ -204,7 +204,7 @@ void setEchoMask(echomask_t m); //Tells if char string cp is in the ax25 path - unsigned queryPath(const string& s, int start = 0, int stop = -1, unsigned n = npos); + size_t queryPath(const string& s, int start = 0, int stop = -1, size_t n = npos); bool changePath(const char* newPath, const char* oldPath); //Change one path element bool addPath(const char* cp, char c = ' '); === modified file 'src/servers.cpp' --- a/src/servers.cpp 2008-03-21 13:02:55 +0000 +++ b/src/servers.cpp 2009-12-26 08:28:20 +0000 @@ -963,11 +963,11 @@ } // End loop detect #1 // Loop detector #2, Reject if user login call seen after qA but not last path element - unsigned rc = abuff->queryPath(abuff->call,abuff->IjpIdx + 1); + size_t rc = abuff->queryPath(abuff->call,abuff->IjpIdx + 1); if (( rc != string::npos) && (abuff->aprsType != APRSREJECT)){ - if (rc != (unsigned)(abuff->pathSize - 1)){ + if (rc != (size_t)(abuff->pathSize - 1)){ abuff->aprsType = APRSREJECT; //Looped packet, REJECT string log_str = abuff->srcHeader + *abuff; WriteLog(log_str, LOGPATH + LOOPLOG); //Write offending packet to loop.log @@ -982,7 +982,7 @@ && (abuff->sourceSock != SRC_INTERNAL)){ if (abuff->EchoMask & srcUSERVALID){ //From validated connection? - unsigned rc = abuff->queryPath(abuff->call,abuff->IjpIdx + 1); + size_t rc = abuff->queryPath(abuff->call,abuff->IjpIdx + 1); if(rc == string::npos) abuff->addPath(abuff->call); //Add user login call if not present in path. } @@ -1373,7 +1373,7 @@ unsigned char c; char star = '*'; - unsigned adr_size = sizeof(peer_adr); + socklen_t adr_size = sizeof(peer_adr); int n, rc,data; bool verified = false, loggedon = false; ULONG State = BASE; @@ -1825,7 +1825,7 @@ } string vd; - unsigned idxInvalid=0; + size_t idxInvalid=0; if (atemp.aprsType == APRSLOGON) { loggedon = true; verified = false; @@ -2111,7 +2111,7 @@ szPass[15] = '\0'; bool verified_tnc = false; - unsigned idxInvalid=0; + size_t idxInvalid=0; int valid = -1; @@ -2239,7 +2239,7 @@ void *TCPServerThread(void *p) { int s = 0, rc = 0; - unsigned i; + socklen_t client_address_size; SessionParams* session; pthread_t SessionThread; int backlog = 5; // Backlog of pending connections @@ -2285,9 +2285,9 @@ listen(s, backlog); for(;;) { - i = sizeof(client); + client_address_size = sizeof(client); session = new SessionParams; - session->Socket = accept(s, (struct sockaddr *)&client, &i); + session->Socket = accept(s, (struct sockaddr *)&client, &client_address_size); session->EchoMask = sp->EchoMask; session->ServerPort = sp->ServerPort; if (ShutDownServer) { @@ -2334,7 +2334,7 @@ { #define UDPSIZE 256 int s,i; - unsigned client_address_size; + socklen_t client_address_size; struct sockaddr_in client, server; char buf[UDPSIZE+3]; UdpParams* upp = (UdpParams*)p;