ggsn: Fix heap-use-after-free during Recovery without associated PDP
Related: OS#4641
Change-Id: Ib4dca2e30e723a196084b0fa0040fbceca835359
diff --git a/ggsn/sgsn.c b/ggsn/sgsn.c
index 8360439..15548ef 100644
--- a/ggsn/sgsn.c
+++ b/ggsn/sgsn.c
@@ -116,6 +116,7 @@
{
unsigned int num = 0;
char buf[INET_ADDRSTRLEN];
+ unsigned int count = llist_count(&sgsn->pdp_list);
inet_ntop(AF_INET, &sgsn->addr, buf, sizeof(buf));
@@ -125,10 +126,17 @@
continue;
ggsn_close_one_pdp(pdp->lib);
num++;
+ if (num == count) {
+ /* Note: if except is NULL, all pdp contexts are freed and sgsn
+ * is most probably already freed at this point.
+ * As a result, last access to sgsn->pdp_list before exiting
+ * loop would access already freed memory. Avoid it by exiting
+ * the loop without the last check, and make sure sgsn is not
+ * accessed after this loop. */
+ break;
+ }
}
- /* Note: if except is NULL, all pdp contexts are freed and sgsn is
- already freed at this point */
LOGP(DGGSN, LOGL_INFO, "SGSN(%s) Dropped %u PDP contexts\n", buf, num);
return num;