diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-12-02 15:00:50 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-12-03 11:47:08 +0100 |
commit | 18d304961249c7815cf3a78ebd1697a4efd9ab42 (patch) | |
tree | 61dd188d1d6ac69ec18ef84c941107062150c2cb /openbsc/src/gprs | |
parent | 237fee649e691fc3a7ef851731305b8a41921436 (diff) |
gtphub: fix use after free.
A tunnel pointer was still being checked after deleting by a call to
expiring_item_del(). 'continue' to the next tun.
Sponsored-by: On-Waves ehi
Diffstat (limited to 'openbsc/src/gprs')
-rw-r--r-- | openbsc/src/gprs/gtphub.c | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c index 36f0836f3..27c70166e 100644 --- a/openbsc/src/gprs/gtphub.c +++ b/openbsc/src/gprs/gtphub.c @@ -1273,34 +1273,44 @@ static int gtphub_check_reused_teis(struct gtphub *hub, /* Check whether the GSN sent a TEI that it is reusing from a * previous tunnel. */ - for_each_side_and_plane(side_idx, plane_idx) { - te = &tun->endpoint[side_idx][plane_idx]; - te2 = &new_tun->endpoint[side_idx][plane_idx]; - if ((te->tei_orig != te2->tei_orig) - || (!te->peer) - || (!te2->peer) - || !gsn_addr_same(&te->peer->peer_addr->addr, - &te2->peer->peer_addr->addr)) - continue; - - /* The peer is reusing a TEI that I believe to - * be part of another tunnel. The other tunnel - * must be stale, then. */ - LOG(LOGL_NOTICE, - "Expiring tunnel due to reused TEI:" - " peer %s sent %s TEI %x," - " previously used by tunnel %s...\n", - gtphub_port_str(te->peer), - gtphub_plane_idx_names[plane_idx], - te->tei_orig, - gtphub_tunnel_str(tun)); - LOG(LOGL_NOTICE, "...while establishing tunnel %s\n", - gtphub_tunnel_str(new_tun)); - - expiring_item_del(&tun->expiry_entry); - /* continue to find more matches. There shouldn't be - * any, but let's make sure. */ + int tun_continue = 0; + for_each_side(side_idx) { + for_each_plane(plane_idx) { + te = &tun->endpoint[side_idx][plane_idx]; + te2 = &new_tun->endpoint[side_idx][plane_idx]; + if ((te->tei_orig != te2->tei_orig) + || (!te->peer) + || (!te2->peer) + || !gsn_addr_same(&te->peer->peer_addr->addr, + &te2->peer->peer_addr->addr)) + continue; + + /* The peer is reusing a TEI that I believe to + * be part of another tunnel. The other tunnel + * must be stale, then. */ + LOG(LOGL_NOTICE, + "Expiring tunnel due to reused TEI:" + " peer %s sent %s TEI %x," + " previously used by tunnel %s...\n", + gtphub_port_str(te->peer), + gtphub_plane_idx_names[plane_idx], + te->tei_orig, + gtphub_tunnel_str(tun)); + LOG(LOGL_NOTICE, "...while establishing tunnel %s\n", + gtphub_tunnel_str(new_tun)); + + expiring_item_del(&tun->expiry_entry); + /* continue to find more matches. There shouldn't be + * any, but let's make sure. However, tun is deleted, + * so we need to skip to the next tunnel. */ + tun_continue = 1; + break; + } + if (tun_continue) + break; } + if (tun_continue) + continue; /* Check whether the mapped TEIs assigned to the endpoints are * used anywhere else. */ |