Skip to content

Commit

Permalink
Clear next field when returnining list elements in queue.c
Browse files Browse the repository at this point in the history
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 <frenaud@redhat.com>
  • Loading branch information
frozencemetery authored and flo-renaud committed Sep 3, 2018
1 parent 020dc37 commit b0b37d4
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions daemons/ipa-otpd/queue.c
Expand Up @@ -111,13 +111,17 @@ 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)
{
if (item == NULL)
return;

item->next = NULL;

if (q->head == NULL)
q->tail = q->head = item;
else {
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
}
Expand Down

0 comments on commit b0b37d4

Please sign in to comment.