From 81adf4db616f43704f0f1b8598149f6e2b123518 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Wed, 22 Aug 2018 15:32:16 -0400 Subject: [PATCH] Clear next field when returnining list elements in queue.c The ipa-otpd code occasionally removes elements from one queue, inspects and modifies them, and then inserts them into another (possibly identical, possibly different) queue. When the next pointer isn't cleared, this can result in element membership in both queues, leading to double frees, or even self-referential elements, causing infinite loops at traversal time. Rather than eliminating the pattern, make it safe by clearing the next field any time an element enters or exits a queue. Related https://pagure.io/freeipa/issue/7262 Reviewed-By: Florence Blanc-Renaud --- daemons/ipa-otpd/queue.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/daemons/ipa-otpd/queue.c b/daemons/ipa-otpd/queue.c index 9e29fb238d5c7a7395bcf3860ce7445c27ca98ac..2944b7ea0db6f49d0a3230b5f33c7a89281fd8c6 100644 --- a/daemons/ipa-otpd/queue.c +++ b/daemons/ipa-otpd/queue.c @@ -111,6 +111,8 @@ void otpd_queue_push(struct otpd_queue *q, struct otpd_queue_item *item) q->head = q->tail = item; else q->tail = q->tail->next = item; + + item->next = NULL; } void otpd_queue_push_head(struct otpd_queue *q, struct otpd_queue_item *item) @@ -118,6 +120,8 @@ void otpd_queue_push_head(struct otpd_queue *q, struct otpd_queue_item *item) if (item == NULL) return; + item->next = NULL; + if (q->head == NULL) q->tail = q->head = item; else { @@ -145,6 +149,8 @@ struct otpd_queue_item *otpd_queue_pop(struct otpd_queue *q) if (q->head == NULL) q->tail = NULL; + if (item != NULL) + item->next = NULL; return item; } @@ -160,6 +166,7 @@ struct otpd_queue_item *otpd_queue_pop_msgid(struct otpd_queue *q, int msgid) *prev = item->next; if (q->head == NULL) q->tail = NULL; + item->next = NULL; return item; } } -- 2.17.1