fixing Kannel leaks

Aarno Syvänen <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi List,

I attach cvs diff for fixing kannel leaks (as tested with our mmsc).
There are new wrappers I used to find these leaks., too. And
there was one unhandled NULL pointer.

Perhaps you check & test these



aarno
cvs.diff (application/octet-stream, 20.1 KB)
Index: gw/bb_store.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_store.c,v
retrieving revision 1.24
diff -u -B -b -r1.24 bb_store.c
--- gw/bb_store.c	15 Nov 2003 13:14:23 -0000	1.24
+++ gw/bb_store.c	26 Nov 2003 10:15:54 -0000
@@ -448,6 +448,7 @@
 	if (msg_type(msg) == sms) {
 	    if (msg->sms.sms_type == report) {
 		octstr_destroy(pack);
+                msg_destroy(msg);
 		continue;
 	    }
 	    key = octstr_format("%d-%d", msg->sms.time, msg->sms.id);
Index: gw/bearerbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/bearerbox.c,v
retrieving revision 1.150
diff -u -B -b -r1.150 bearerbox.c
Index: gw/dlr.c
===================================================================
RCS file: /home/cvs/gateway/gw/dlr.c,v
retrieving revision 1.43
diff -u -B -b -r1.43 dlr.c
--- gw/dlr.c	15 Nov 2003 13:14:23 -0000	1.43
+++ gw/dlr.c	26 Nov 2003 10:15:54 -0000
@@ -362,10 +362,11 @@
  * NOTE: If typ is end status (e.g. DELIVERED) then dlr entry
  *       will be removed from DB.
  */
-Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ)
+Msg *dlr_find(Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ)
 {
     Msg	*msg = NULL;
     struct dlr_entry *dlr = NULL;
+    Octstr *namos;
     
     if(octstr_len(smsc) == 0) {
 	warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type());
@@ -373,16 +374,19 @@
     }
 
     /* check if we have handler registered */
-    if (handles == NULL || handles->dlr_get == NULL)
+    if (handles == NULL || handles->dlr_get == NULL) {
         return NULL;
+    }
 
+    namos = octstr_duplicate(smsc);
     debug("dlr.dlr", 0, "DLR[%s]: Looking for DLR smsc=%s, ts=%s, dst=%s, type=%d",
-                                 dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(ts), octstr_get_cstr(dst), typ);
+                                 dlr_type(), octstr_get_cstr(namos), octstr_get_cstr(ts), octstr_get_cstr(dst), typ);
 
     dlr = handles->dlr_get(smsc, ts, dst);
     if (dlr == NULL)  {
         warning(0, "DLR[%s]: DLR for DST<%s> not found.",
                       dlr_type(), octstr_get_cstr(dst));
+        octstr_destroy(namos);
         return NULL;
     }
 
@@ -392,7 +396,7 @@
         msg->sms.sms_type = report;
         msg->sms.service = octstr_duplicate(dlr->service);
         msg->sms.dlr_mask = typ;
-        msg->sms.smsc_id = octstr_duplicate(dlr->smsc);
+        msg->sms.smsc_id = dlr->smsc;
         msg->sms.receiver = octstr_duplicate(dlr->destination);
         msg->sms.sender = octstr_duplicate(dlr->source);
         /* if dlr_url was present, recode it here again */
@@ -414,6 +418,7 @@
     } else {
         debug("dlr.dlr", 0, "DLR[%s]: Ignoring DLR message because of mask type=%d dlr->mask=%d", dlr_type(), typ, dlr->mask);
         /* ok that was a status report but we where not interested in having it */
+        dlr_entry_destroy(dlr);
         msg = NULL;
     }
  
@@ -432,6 +437,7 @@
         }
     }
 
+    octstr_destroy(namos);
     /* destroy struct dlr_entry */
     dlr_entry_destroy(dlr);
 
Index: gw/dlr.h
===================================================================
RCS file: /home/cvs/gateway/gw/dlr.h,v
retrieving revision 1.16
diff -u -B -b -r1.16 dlr.h
--- gw/dlr.h	15 Nov 2003 13:14:23 -0000	1.16
+++ gw/dlr.h	26 Nov 2003 10:15:54 -0000
@@ -100,7 +100,7 @@
  * Find an entry in the list. If there is one a message is returned and 
  * the entry is removed from the list otherwhise the message returned is NULL 
  */
-Msg* dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type);
+Msg* dlr_find(Octstr *smsc, const Octstr *ts, const Octstr *dst, int type);
 
 /* return the number of DLR messages in the current waiting queue */
 long dlr_messages(void);
Index: gw/dlr_mysql.c
===================================================================
RCS file: /home/cvs/gateway/gw/dlr_mysql.c,v
retrieving revision 1.5
diff -u -B -b -r1.5 dlr_mysql.c
--- gw/dlr_mysql.c	15 Nov 2003 13:14:23 -0000	1.5
+++ gw/dlr_mysql.c	26 Nov 2003 10:15:54 -0000
@@ -169,30 +169,36 @@
     Octstr *sql;
     MYSQL_RES *result;
     MYSQL_ROW row;
+    Octstr *namos;
 
+    namos = octstr_duplicate(smsc);
     sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s';",
                         octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
                         octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
                         octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
                         octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
-                        octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+                        octstr_get_cstr(namos), octstr_get_cstr(fields->field_ts),
+                        octstr_get_cstr(ts));
 
 
     result = mysql_select(sql);
     octstr_destroy(sql);
 
     if (result == NULL) {
+        octstr_destroy(namos);
         return NULL;
     }
     if (mysql_num_rows(result) < 1) {
         debug("dlr.mysql", 0, "no rows found");
         mysql_free_result(result);
+        octstr_destroy(namos);
         return NULL;
     }
     row = mysql_fetch_row(result);
     if (!row) {
         debug("dlr.mysql", 0, "rows found but could not load them");
         mysql_free_result(result);
+        octstr_destroy(namos);
         return NULL;
     }
 
@@ -210,6 +216,7 @@
     res->smsc = octstr_duplicate(smsc);
 
     mysql_free_result(result);
+    octstr_destroy(namos);
 
     return res;
 }
Index: gw/msg.c
===================================================================
RCS file: /home/cvs/gateway/gw/msg.c,v
retrieving revision 1.30
diff -u -B -b -r1.30 msg.c
--- gw/msg.c	15 Nov 2003 13:14:23 -0000	1.30
+++ gw/msg.c	26 Nov 2003 10:15:54 -0000
@@ -88,11 +88,12 @@
  * Implementations of the exported functions.
  */
 
-Msg *msg_create(enum msg_type type)
+Msg *msg_create_real(enum msg_type type, const char *file, long line,
+                     const char *func)
 {
     Msg *msg;
 
-    msg = gw_malloc(sizeof(Msg));
+    msg = gw_malloc_trace(sizeof(Msg), file, line, func);
 
     msg->type = type;
 #define INTEGER(name) p->name = MSG_PARAM_UNDEFINED;
@@ -185,13 +186,13 @@
 }
 
 
-Msg *msg_unpack(Octstr *os)
+Msg *msg_unpack_real(Octstr *os, const char *file, long line, const char *func)
 {
     Msg *msg;
     int off;
     long i;
 
-    msg = msg_create(0);
+    msg = msg_create_real(0, file, line, func);
     if (msg == NULL)
         goto error;
 
@@ -219,6 +220,7 @@
 
 error:
     error(0, "Msg packet was invalid.");
+    msg_destroy(msg);
     return NULL;
 }
 
Index: gw/msg.h
===================================================================
RCS file: /home/cvs/gateway/gw/msg.h,v
retrieving revision 1.17
diff -u -B -b -r1.17 msg.h
--- gw/msg.h	15 Nov 2003 13:14:23 -0000	1.17
+++ gw/msg.h	26 Nov 2003 10:15:54 -0000
@@ -117,8 +117,10 @@
 /*
  * Create a new, empty Msg object. Panics if fails.
  */
-Msg *msg_create(enum msg_type type);
-
+Msg *msg_create_real(enum msg_type type, const char *file, long line,
+                     const char *func);
+#define msg_create(type) \
+    gw_claim_area(msg_create_real((type), __FILE__, __LINE__, __func__))
 
 /*
  * Create a new Msg object that is a copy of an existing one.
@@ -163,6 +165,9 @@
  * Unpack an Msg from an Octstr. Return NULL for failure, otherwise a pointer
  * to the Msg.
  */
-Msg *msg_unpack(Octstr *os);
+
+Msg *msg_unpack_real(Octstr *os, const char *file, long line, const char *func);
+#define msg_unpack(os) \
+    gw_claim_area(msg_unpack_real((os), __FILE__, __LINE__, __func__))
 
 #endif
Index: gw/urltrans.c
===================================================================
RCS file: /home/cvs/gateway/gw/urltrans.c,v
retrieving revision 1.88
diff -u -B -b -r1.88 urltrans.c
Index: gw/wap-appl.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap-appl.c,v
retrieving revision 1.100
diff -u -B -b -r1.100 wap-appl.c
--- gw/wap-appl.c	15 Nov 2003 13:14:23 -0000	1.100
+++ gw/wap-appl.c	26 Nov 2003 10:15:54 -0000
@@ -1221,6 +1221,8 @@
          * POST requests for the HTTP server.
          * Mainly this is used for multipart/form-data transmissions,
          * including MMS on-the-fly message decoding.
+         * When we are doing mms, the phone POSTs contents and acknowled-
+         * gements. In this case, we dont do not deconvert anything.
          */
         if (octstr_str_compare(method, "POST") == 0 && request_body && 
             octstr_len(request_body)) {
@@ -1235,6 +1237,8 @@
                 http_header_mark_transformation(actual_headers, content.body, 
                                                 content.type);
             request_body = content.body;
+            octstr_destroy(content.type);
+            octstr_destroy(content.charset);
         }
 
         /* struct that is used for the HTTP response identifier */
Index: gw/wap_push_ppg.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_ppg.c,v
retrieving revision 1.63
diff -u -B -b -r1.63 wap_push_ppg.c
--- gw/wap_push_ppg.c	20 Nov 2003 13:14:32 -0000	1.63
+++ gw/wap_push_ppg.c	26 Nov 2003 10:15:55 -0000
@@ -1730,6 +1730,7 @@
  * chapter 6.1.1, states that we MUST reject a push having an erroneous PAP
  * push message element. So we must validate it even when we do not compile
  * it.
+ * If message content was not si or sl, we pass it without modifications.
  * We do not do any (formally optional, but phones may disagree) header 
  * conversions to the binary format here, these are responsibility of our OTA 
  * module (gw/wap_push_ota.c). 
@@ -1737,7 +1738,7 @@
  *
  * Return 
  *    a) message, either transformed or not (if there is no-transform cache 
- *       directive or wml code is erroneous) 
+ *       directive, wml code is erroneous or content was not si or sl.) 
  *    b) The transformed gw address. Use here global-sender, when the bearer
  *       is SMS (some SMS centers would require this).
  *    c) the transformed message content type
@@ -1785,8 +1786,7 @@
     if (content.body == NULL)
         goto no_transform;
 
-    content.type = http_header_find_first(push_headers, 
-        "Content-Transfer-Encoding");
+    content.type = http_header_find_first(push_headers, "Content-Transfer-Encoding");
     if (content.type) {
 	    octstr_strip_blanks(content.type);
 	    debug("wap.push.ppg", 0, "PPG: Content-Transfer-Encoding is \"%s\"",
@@ -1801,8 +1801,8 @@
 	    }
     }
 
-    http_header_get_content_type(push_headers, &content.type,
-                                 &content.charset);   
+    octstr_destroy(content.type);
+    http_header_get_content_type(push_headers, &content.type, &content.charset);   
     message_deliverable = pap_convert_content(&content);
 
     if (content.type == NULL)
@@ -1823,19 +1823,17 @@
 
 herror:
     warning(0, "PPG: transform_message: no push headers, cannot accept");
+    octstr_destroy(content.type);
     return 0;
 
 error:
     warning(0, "PPG: transform_message: push content erroneous, cannot"
             " accept");
     octstr_destroy(content.type);
-    octstr_destroy(content.charset);
     return 0;
 
 no_transform:
     warning(0, "PPG: transform_message: push content non transformable");
-    octstr_destroy(content.type);
-    octstr_destroy(content.charset);
     return 1;
 }
 
@@ -3314,10 +3312,12 @@
     if ((masklen = octstr_parse_long(&dlr_mask, dlrmaskos, 0, 10)) != -1 &&
              masklen == octstr_len(dlrmaskos) &&
              dlr_mask >= -1 && dlr_mask <= 31) {
+         octstr_destroy(dlrmaskos);
          return dlr_mask;
     }
 
     warning(0, "unparsable dlr mask, rejected");
+    octstr_destroy(dlrmaskos);
     return 0;
 }
 
@@ -3332,12 +3332,11 @@
 
 static Octstr *set_smsbox_id(List *headers, Octstr *username, int trusted_pi)
 {
-    Octstr *smsboxidos;
     Octstr *smsbox_id = NULL;
 
-    smsboxidos = http_header_value(headers, octstr_imm("X-Kannel-Smsbox-Id"));
-    if (smsboxidos != NULL) {
-        return octstr_duplicate(smsboxidos);
+    smsbox_id = http_header_value(headers, octstr_imm("X-Kannel-Smsbox-Id"));
+    if (smsbox_id != NULL) {
+        return smsbox_id;
     }
 
     if (!trusted_pi)
Index: gwlib/http.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/http.c,v
retrieving revision 1.211
diff -u -B -b -r1.211 http.c
--- gwlib/http.c	15 Nov 2003 13:14:23 -0000	1.211
+++ gwlib/http.c	26 Nov 2003 10:15:55 -0000
@@ -2700,7 +2700,8 @@
 }
 
 
-Octstr *http_header_find_first(List *headers, char *name)
+Octstr *http_header_find_first_real(List *headers, char *name, const char *file, long line,
+                                    const char *func)
 {
     long i, name_len;
     Octstr *h, *value;
@@ -2714,7 +2715,8 @@
     for (i = 0; i < list_len(headers); ++i) {
         h = list_get(headers, i);
         if (header_is_called(h, name)) {
-            value = octstr_copy(h, name_len + 1, octstr_len(h));
+            value = octstr_copy_real(h, name_len + 1, octstr_len(h),
+                                     file, line, func);
 	    octstr_strip_blanks(value);
 	    return value;
 	}
Index: gwlib/http.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/http.h,v
retrieving revision 1.60
diff -u -B -b -r1.60 http.h
--- gwlib/http.h	15 Nov 2003 13:14:23 -0000	1.60
+++ gwlib/http.h	26 Nov 2003 10:15:55 -0000
@@ -539,7 +539,10 @@
  * as a new Octet string, which the caller must free. Return NULL for
  * not found.
  */
-Octstr *http_header_find_first(List *headers, char *name);
+Octstr *http_header_find_first_real(List *headers, char *name, 
+                                    const char *file, long line, const char *func);
+#define http_header_find_first(headers, name) \
+    gw_claim_area(http_header_find_first_real((headers), (name), __FILE__, __LINE__, __func__))
 List *http_header_find_all(List *headers, char *name);
 
 
Index: gwlib/octstr.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/octstr.c,v
retrieving revision 1.153
diff -u -B -b -r1.153 octstr.c
--- gwlib/octstr.c	15 Nov 2003 13:14:23 -0000	1.153
+++ gwlib/octstr.c	26 Nov 2003 10:15:56 -0000
@@ -325,7 +325,8 @@
 }
 
 
-Octstr *octstr_copy_real(Octstr *ostr, long from, long len)
+Octstr *octstr_copy_real(Octstr *ostr, long from, long len, const char *file, long line,
+                         const char *func)
 {
     seems_valid(ostr);
     gw_assert(from >= 0);
@@ -337,7 +338,8 @@
     if (len > ostr->len - from)
         len = ostr->len - from;
 
-    return octstr_create_from_data(ostr->data + from, len);
+    return octstr_create_from_data_trace(ostr->data + from, len, file,
+                                         line, func);
 }
 
 
Index: gwlib/octstr.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/octstr.h,v
retrieving revision 1.80
diff -u -B -b -r1.80 octstr.h
--- gwlib/octstr.h	15 Nov 2003 13:14:23 -0000	1.80
+++ gwlib/octstr.h	26 Nov 2003 10:15:56 -0000
@@ -173,9 +173,10 @@
  * octet string is created. If `from+len' is after the end of `ostr', 
  * `len' is reduced appropriately.
  */
-Octstr *octstr_copy_real(Octstr *ostr, long from, long len);
+Octstr *octstr_copy_real(Octstr *ostr, long from, long len, const char *file,
+                         long line, const char *func);
 #define octstr_copy(ostr, from, len) \
-    gw_claim_area(octstr_copy_real((ostr), (from), (len)))
+    gw_claim_area(octstr_copy_real((ostr), (from), (len), __FILE__, __LINE__, __func__))
 
 
 /*
wap/wap.c
===================================================================
RCS file: /home/cvs/gateway/wap/wap.c,v
retrieving revision 1.2
diff -u -B -b -r1.2 wap.c
--- wap/wap.c	15 Nov 2003 13:14:23 -0000	1.2
+++ wap/wap.c	26 Nov 2003 10:15:56 -0000
@@ -76,14 +76,20 @@
     }
 
     /* XXX Assumption does not hold for client side */
-    if (dgram->u.T_DUnitdata_Ind.addr_tuple->local->port
-        == CONNECTIONLESS_PORT) {
+    if (dgram->u.T_DUnitdata_Ind.addr_tuple->local->port == CONNECTIONLESS_PORT) {
 	wsp_unit_dispatch_event(dgram);
     } else {
         List *events;
 
         events = wtp_unpack_wdp_datagram(dgram);
+
+        if (!events) {
+            debug("wap.wap", 0, "ignoring truncated datagram");
+            wap_event_dump(dgram);
 	wap_event_destroy(dgram);
+            return;
+        }
+
         while (list_len(events) > 0) {
 	    WAPEvent *event;
 
@@ -93,6 +99,8 @@
             else
                 wtp_initiator_dispatch_event(event);
         }
+
+        wap_event_destroy(dgram);
         list_destroy(events, NULL);
     }
 }
Index: wap/wap_events.c
===================================================================
RCS file: /home/cvs/gateway/wap/wap_events.c,v
retrieving revision 1.6
diff -u -B -b -r1.6 wap_events.c
--- wap/wap_events.c	15 Nov 2003 13:14:23 -0000	1.6
+++ wap/wap_events.c	26 Nov 2003 10:15:56 -0000
@@ -67,13 +67,14 @@
 #include "wap_events.h"
 #include "wtls_pdu.h"
 
-WAPEvent *wap_event_create(WAPEventName type) {
+WAPEvent *wap_event_create_real(WAPEventName type, const char *file, long line,
+                                const char *func) {
 	WAPEvent *event;
 	
 	gw_assert(type >= 0);
 	gw_assert(type < WAPEventNameCount);
 
-	event = gw_malloc(sizeof(WAPEvent));
+	event = gw_malloc_trace(sizeof(WAPEvent), file, line, func);
 	event->type = type;
 
 	switch (event->type) {
Index: wap/wap_events.h
===================================================================
RCS file: /home/cvs/gateway/wap/wap_events.h,v
retrieving revision 1.5
diff -u -B -b -r1.5 wap_events.h
--- wap/wap_events.h	15 Nov 2003 13:14:23 -0000	1.5
+++ wap/wap_events.h	26 Nov 2003 10:15:56 -0000
@@ -102,7 +102,10 @@
 
 
 
-WAPEvent *wap_event_create(WAPEventName type);
+WAPEvent *wap_event_create_real(WAPEventName type, const char *file, long line,
+                                const char *func);
+#define wap_event_create(type) \
+    gw_claim_area(wap_event_create_real((type), __FILE__, __LINE__, __func__))
 void wap_event_destroy(WAPEvent *event);
 void wap_event_destroy_item(void *event);
 WAPEvent *wap_event_duplicate(WAPEvent *event);
Index: wap/wtp.c
===================================================================
RCS file: /home/cvs/gateway/wap/wtp.c,v
retrieving revision 1.4
diff -u -B -b -r1.4 wtp.c
--- wap/wtp.c	15 Nov 2003 13:14:24 -0000	1.4
+++ wap/wtp.c	26 Nov 2003 10:15:56 -0000
@@ -348,8 +348,10 @@
 
     data = datagram->u.T_DUnitdata_Ind.user_data;
 
-    if (truncated_datagram(datagram))
+    if (truncated_datagram(datagram)) {
+        warning(0, "WTP: got a truncated datagram, ignoring");
 	return NULL;
+    }
 
     pdu = wtp_pdu_unpack(data);
 
@@ -357,7 +359,7 @@
  * Wtp_pdu_unpack returned NULL, we build a rcv error event. 
  */
     if (pdu == NULL) {
-        error(0, "pdu unpacking returned NULL");
+        error(0, "WTP: cannot unpack pdu, creating an error pdu");
         event = pack_error(datagram);
         return event;
     }   		
@@ -370,7 +372,7 @@
         event = unpack_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
         /* if an WTP initiator gets invoke, it would be an illegal pdu. */
         if (!wtp_event_is_for_responder(event)){
-            debug("wap.wtp", 0, "Invoke when initiator. Message was");
+            debug("wap.wtp", 0, "WTP: Invoke when initiator. Message was");
             wap_event_destroy(event);
             event = pack_error(datagram);
         }
@@ -384,7 +386,7 @@
         event = unpack_result(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
         /* if an WTP responder gets result, it would be an illegal pdu. */
         if (wtp_event_is_for_responder(event)){
-            debug("wap.wtp", 0, "Result when responder. Message was");
+            debug("wap.wtp", 0, "WTP: Result when responder. Message was");
             wap_event_destroy(event);
             event = pack_error(datagram);
         }
@@ -404,7 +406,7 @@
 
 	default:
 	    event = pack_error(datagram);
-	    debug("wap.wtp", 0, "Unhandled PDU type. Message was");
+	    debug("wap.wtp", 0, "WTP: Unhandled PDU type. Message was");
             wap_event_dump(datagram);
 	    return event;
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.