[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#565460: aprsd crashes when someone logs in from network amd64



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 <kamal@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;


Reply to: