[PATCH] Memory leak in smpp_pdu.c

Donald Jackson <[email protected]> Sat, 24 Sep 2016 12:00:20 +0200
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <CALzQDrADv2trOSxqGZjetctMzwFzr5YXRDmi1+ZKcRfdLmUdFA@mail.gmail.com>
Hi all,

I have been assisting with a KSMPPD implementation and couldn't figure out
why the application was leaking memory.

After a long search I found that an SMPP client was sending the same TLV
multiple times which was causing lost pointers/memory leaks.

I believe this would effect all Kannel derivatives (OpenSMPPBox, Commercial
SMPPBox and Bearerbox) in the cases where an incorrectly implemented (or
malicious?) client or gateway could be the cause of memory leaks.

Herewith patch to fix.

Thanks,
Donald
smpp_pdu_tlv_memory_leak.patch (application/octet-stream, 1.4 KB)
Index: gw/smsc/smpp_pdu.c
===================================================================
--- gw/smsc/smpp_pdu.c	(revision 5173)
+++ gw/smsc/smpp_pdu.c	(working copy)
@@ -598,6 +598,11 @@
                         pos += opt_len; \
                         continue; \
                     } \
+                    if(p->mname != NULL) { \
+                        warning(0, "SMPP: Optional field (%s) was sent more than once, overwriting", #mname); \
+                        octstr_destroy(p->mname); \
+                        p->mname = NULL; \
+                    } \
                     copy_until_nul(#mname, data_without_len, &pos, opt_len, &p->mname); \
                     if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \
                 } else
@@ -610,6 +615,11 @@
                         pos += opt_len; \
                         continue; \
                     } \
+                    if(p->mname != NULL) { \
+                        warning(0, "SMPP: Optional field (%s) was sent more than once, overwriting", #mname); \
+                        octstr_destroy(p->mname); \
+                        p->mname = NULL; \
+                    } \
                     p->mname = octstr_copy(data_without_len, pos, opt_len); \
                     pos += opt_len; \
                     if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \