smpp: Unset esme->acl on socket close

We set acl->esme during _process_bind(), but we don't clear it
in case the TCP connection for the ESME is dead.  This leads to
a stale acl->esme pointer, which we will attempt to dereference
the next time a SMS is delivered to a route pointing to this acl,
where it will be a heap use-after-free.

This was discovered using AddressSanitizer and MSC_Tests.ttcn

Closes: OS#3168
Change-Id: I1f140d7f9c7d89f200ddbcd81a8df66de69fb3e4
This commit is contained in:
Harald Welte 2018-04-14 15:04:28 +02:00
parent 99a8d235f3
commit ce96928e12
1 changed files with 6 additions and 0 deletions

View File

@ -249,6 +249,8 @@ static void esme_destroy(struct osmo_esme *esme)
}
smpp_cmd_flush_pending(esme);
llist_del(&esme->list);
if (esme->acl)
esme->acl->esme = NULL;
talloc_free(esme);
}
@ -875,6 +877,8 @@ dead_socket:
osmo_fd_unregister(&esme->wqueue.bfd);
close(esme->wqueue.bfd.fd);
esme->wqueue.bfd.fd = -1;
if (esme->acl)
esme->acl->esme = NULL;
smpp_esme_put(esme);
return 0;
@ -891,6 +895,8 @@ static int esme_link_write_cb(struct osmo_fd *ofd, struct msgb *msg)
osmo_fd_unregister(&esme->wqueue.bfd);
close(esme->wqueue.bfd.fd);
esme->wqueue.bfd.fd = -1;
if (esme->acl)
esme->acl->esme = NULL;
smpp_esme_put(esme);
} else if (rc < msgb_length(msg)) {
LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id);