Fix use-after-free by tun thread after tun obj destroyed

The main thread calls pthread_cancel before freeing the tun object.
However, pthread_cancel doesn't kill the thread synchronously (man
pthread_cancel). Hence, the tun thread may still be running for a while
after the tun object is/has been(ing) freed.
Let's avoid this by making sure the thread is stopped before
freeing the object.
To accomplish it, we must wait for the thread to be cancelled. A cleanup
routie is added which will signal the "tun_released" message to the main
thread through an osmo_itq, which will then free the object (since
talloc context is managed by the main thread).

Related: SYS#5523
Change-Id: Idf005359afb41d3413b09281a9ff937d5eafcc7c
diff --git a/daemon/internal.h b/daemon/internal.h
index 09ba52e..fc5708d 100644
--- a/daemon/internal.h
+++ b/daemon/internal.h
@@ -7,6 +7,7 @@
 #include <sys/socket.h>
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/write_queue.h>
+#include <osmocom/core/it_q.h>
 #include <osmocom/core/utils.h>
 
 struct nl_sock;
@@ -84,6 +85,13 @@
 /***********************************************************************
  * TUN Device
  ***********************************************************************/
+/* Message sent tun thread -> main thread through osmo_itq */
+struct gtp_daemon_itq_msg {
+	struct llist_head list;
+	struct {
+		struct tun_device *tun;
+	} tun_released; /* tun became stopped and can be freed */
+};
 
 struct tun_device {
 	/* entry in global list */
@@ -110,6 +118,9 @@
 
 	/* the thread handling Rx from the tun fd */
 	pthread_t thread;
+
+	/* Used to store messages to be sent to main thread, since tun thread doesn't allocate through talloc */
+	struct gtp_daemon_itq_msg itq_msg;
 };
 
 struct tun_device *
@@ -121,9 +132,10 @@
 struct tun_device *
 _tun_device_find(struct gtp_daemon *d, const char *devname);
 
-void _tun_device_deref_destroy(struct tun_device *tun);
+void _tun_device_destroy(struct tun_device *tun);
 
 bool _tun_device_release(struct tun_device *tun);
+void _tun_device_deref_release(struct tun_device *tun);
 
 bool tun_device_release(struct tun_device *tun);
 
@@ -222,6 +234,12 @@
 	struct osmo_stream_srv_link *cups_link;
 	struct osmo_signalfd *signalfd;
 
+	/* inter-thread queue between main thread and workers, pass struct gtp_daemon_itq_msg: */
+	struct osmo_it_q *itq;
+
+	/* Number of tunnels in progrress of being released: */
+	unsigned int reset_all_state_tun_remaining;
+
 	struct {
 		char *cups_local_ip;
 		uint16_t cups_local_port;