[PATCH 1/2] write_queue: Avoid possible use-after-free if fd is read-/writable

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Daniel Willmann dwillmann at sysmocom.de
Wed May 21 13:08:18 UTC 2014


If the FD is both readable and writable and the read callback closes the
connection (and frees the surrounding structure) we shouldn't call the
write callback (or check anything else in the read fd).

With this patch callback functions can return -EBADFD if they don't want
the FD to be handled any more.
---
 src/write_queue.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/src/write_queue.c b/src/write_queue.c
index cef40f8..d17493d 100644
--- a/src/write_queue.c
+++ b/src/write_queue.c
@@ -21,8 +21,15 @@
  *
  */
 
+#include <errno.h>
 #include <osmocom/core/write_queue.h>
 
+#define HANDLE_BAD_FD(rc, label) \
+	do { \
+		if (rc == -EBADFD) \
+			goto label; \
+	} while (0);
+
 /*! \addtogroup write_queue
  *  @{
  */
@@ -39,14 +46,19 @@
 int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
 {
 	struct osmo_wqueue *queue;
+	int rc;
 
 	queue = container_of(fd, struct osmo_wqueue, bfd);
 
-	if (what & BSC_FD_READ)
-		queue->read_cb(fd);
+	if (what & BSC_FD_READ) {
+		rc = queue->read_cb(fd);
+		HANDLE_BAD_FD(rc, err_badfd);
+	}
 
-	if (what & BSC_FD_EXCEPT)
-		queue->except_cb(fd);
+	if (what & BSC_FD_EXCEPT) {
+		rc = queue->except_cb(fd);
+		HANDLE_BAD_FD(rc, err_badfd);
+	}
 
 	if (what & BSC_FD_WRITE) {
 		struct msgb *msg;
@@ -58,16 +70,21 @@ int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
 			--queue->current_length;
 
 			msg = msgb_dequeue(&queue->msg_queue);
-			queue->write_cb(fd, msg);
+			rc = queue->write_cb(fd, msg);
 			msgb_free(msg);
 
+			HANDLE_BAD_FD(rc, err_badfd);
+
 			if (!llist_empty(&queue->msg_queue))
 				fd->when |= BSC_FD_WRITE;
 		}
 	}
 
 	return 0;
+err_badfd:
+	return rc;
 }
+#undef HANDLE_BAD_FD
 
 /*! \brief Initialize a \ref osmo_wqueue structure
  *  \param[in] queue Write queue to operate on
-- 
1.8.4.2





More information about the OpenBSC mailing list