Re: fixing Kannel leaks

Aarno Syvänen <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
A new try :(



Aarno

On 26.11.2003, at 12:32, Alexander Malysh wrote:

> Hi Aarno,
>
> would you please explain???
>
> 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)
>
> why not const here? With const we just tell the caller: "we do not 
> modify your
> arg."
>
>  {
>      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);
>
> why duplicate smsc Octstr here and then free it ??
> if dlr entry is not found we just avoid memory allocation...
>
>      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);
>
> why dlr_entry_destroy must be called here ???
> see bellow... there we free that struct.
>
>          msg = NULL;
>      }
>
> @@ -432,6 +437,7 @@
>          }
>      }
>
> +    octstr_destroy(namos);
>      /* destroy struct dlr_entry */
>      dlr_entry_destroy(dlr);
>
> The same agrs for dlr_mysq.c ...
>
>
> On Wednesday 26 November 2003 11:53, Aarno Syvänen wrote:
>> 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
>
> -- 
> Best regards / Mit besten Grüßen aus Düsseldorf
>
> Dipl.-Ing.
> Alexander Malysh
> ___________________________________________
>
> Centrium GmbH
> Vogelsanger Weg 80
> 40470 Düsseldorf
>
> Fon: +49 (0211) 74 84 51 80
> Fax: +49 (0211) 277 49 109
>
> email: [email protected]
> web: www.centrium.de
> msn: [email protected]
> icq: 98063111
> ___________________________________________
>
> Please avoid sending me Word, Excel or PowerPoint attachments.
> See http://www.fsf.org/philosophy/no-word-attachments.html
>
>
cvs.diff (application/octet-stream, 15.9 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 14:19:40 -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/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 14:19:40 -0000
@@ -373,11 +373,13 @@
     }
 
     /* check if we have handler registered */
-    if (handles == NULL || handles->dlr_get == NULL)
+    if (handles == NULL || handles->dlr_get == NULL) {
         return NULL;
+    }
 
     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(smsc), octstr_get_cstr(ts),
+          octstr_get_cstr(dst), typ);
 
     dlr = handles->dlr_get(smsc, ts, dst);
     if (dlr == NULL)  {
@@ -392,7 +394,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 */
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 14:19:40 -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 14:19:40 -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/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 14:19:40 -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 14:19:41 -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,6 +1823,7 @@
 
 herror:
     warning(0, "PPG: transform_message: no push headers, cannot accept");
+    octstr_destroy(content.type);
     return 0;
 
 error:
@@ -1834,8 +1835,6 @@
 
 no_transform:
     warning(0, "PPG: transform_message: push content non transformable");
-    octstr_destroy(content.type);
-    octstr_destroy(content.charset);
     return 1;
 }
 
@@ -3314,10 +3313,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 +3333,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 14:19:42 -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 14:19:42 -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 14:19:42 -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 14:19:42 -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__))
 
 
 /*
Index: 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 14:19:42 -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 14:19:42 -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 14:19:42 -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 14:19:43 -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.