ggsn: Fix heap-use-after-free during Recovery without associated PDP
Related: OS#4641 Change-Id: Ib4dca2e30e723a196084b0fa0040fbceca835359
This commit is contained in:
parent
bd2b55679e
commit
b6a0e3fd2e
12
ggsn/sgsn.c
12
ggsn/sgsn.c
|
@ -116,6 +116,7 @@ static unsigned int sgsn_peer_drop_all_pdp_except(struct sgsn_peer *sgsn, struct
|
||||||
{
|
{
|
||||||
unsigned int num = 0;
|
unsigned int num = 0;
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
|
unsigned int count = llist_count(&sgsn->pdp_list);
|
||||||
|
|
||||||
inet_ntop(AF_INET, &sgsn->addr, buf, sizeof(buf));
|
inet_ntop(AF_INET, &sgsn->addr, buf, sizeof(buf));
|
||||||
|
|
||||||
|
@ -125,10 +126,17 @@ static unsigned int sgsn_peer_drop_all_pdp_except(struct sgsn_peer *sgsn, struct
|
||||||
continue;
|
continue;
|
||||||
ggsn_close_one_pdp(pdp->lib);
|
ggsn_close_one_pdp(pdp->lib);
|
||||||
num++;
|
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);
|
LOGP(DGGSN, LOGL_INFO, "SGSN(%s) Dropped %u PDP contexts\n", buf, num);
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
|
Loading…
Reference in New Issue