diff options
author | Zoltan Kiss <zoltan.kiss@linaro.org> | 2015-12-07 17:33:50 +0000 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-12-08 14:26:52 +0300 |
commit | 994d8d029fc804b7d5d22c503abb5049d70c3d86 (patch) | |
tree | 35c59b22e4f552b9e0208cce58d4ee558b53ac7b /platform | |
parent | a4f8caf51f5b33d63c70dd42ed92c8fbc73c8c1d (diff) |
queue: fix memory corruption in reorder_enq()
reorder_prev is set to the address of the pointer origin_qe->s.reorder_head,
which is wrong. If the linked list was empty, that won't be corrected, and
reorder_prev->next points to the adjacent queue entry's status field. If that
entry is used, that queue's metadata will be corrupted.
This was found by running the chaos scheduler test with ODP-DPDK.
Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r-- | platform/linux-generic/include/odp_queue_internal.h | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h index a70044b26..1cc0ed26e 100644 --- a/platform/linux-generic/include/odp_queue_internal.h +++ b/platform/linux-generic/include/odp_queue_internal.h @@ -212,8 +212,7 @@ static inline void reorder_enq(queue_entry_t *queue, int sustain) { odp_buffer_hdr_t *reorder_buf = origin_qe->s.reorder_head; - odp_buffer_hdr_t *reorder_prev = - (odp_buffer_hdr_t *)(void *)&origin_qe->s.reorder_head; + odp_buffer_hdr_t *reorder_prev = NULL; while (reorder_buf && order >= reorder_buf->order) { reorder_prev = reorder_buf; @@ -221,7 +220,12 @@ static inline void reorder_enq(queue_entry_t *queue, } buf_hdr->next = reorder_buf; - reorder_prev->next = buf_hdr; + + if (reorder_prev) + reorder_prev->next = buf_hdr; + else + origin_qe->s.reorder_head = buf_hdr; + if (!reorder_buf) origin_qe->s.reorder_tail = buf_hdr; |