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
This commit is contained in:
Neels Hofmeyr 2015-12-02 15:00:50 +01:00
parent 237fee649e
commit 18d3049612
1 changed files with 35 additions and 25 deletions

View File

@ -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;
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));
/* 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. */
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. */