qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

qemu/queue.h: clear linked list pointers on remove

Do not leave stale linked list pointers around after removal. It's
safer to set them to NULL so that use-after-removal results in an
immediate segfault.

The RCU queue removal macros are unchanged since nodes may still be
traversed after removal.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Link: https://lore.kernel.org/r/20200224103406.1894923-2-stefanha@redhat.com
Message-Id: <20200224103406.1894923-2-stefanha@redhat.com>

+15 -4
+15 -4
include/qemu/queue.h
··· 142 142 (elm)->field.le_next->field.le_prev = \ 143 143 (elm)->field.le_prev; \ 144 144 *(elm)->field.le_prev = (elm)->field.le_next; \ 145 + (elm)->field.le_next = NULL; \ 146 + (elm)->field.le_prev = NULL; \ 145 147 } while (/*CONSTCOND*/0) 146 148 147 149 /* ··· 225 227 } while (/*CONSTCOND*/0) 226 228 227 229 #define QSLIST_REMOVE_HEAD(head, field) do { \ 228 - (head)->slh_first = (head)->slh_first->field.sle_next; \ 230 + typeof((head)->slh_first) elm = (head)->slh_first; \ 231 + (head)->slh_first = elm->field.sle_next; \ 232 + elm->field.sle_next = NULL; \ 229 233 } while (/*CONSTCOND*/0) 230 234 231 235 #define QSLIST_REMOVE_AFTER(slistelm, field) do { \ 232 - (slistelm)->field.sle_next = \ 233 - QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \ 236 + typeof(slistelm) next = (slistelm)->field.sle_next; \ 237 + (slistelm)->field.sle_next = next->field.sle_next; \ 238 + next->field.sle_next = NULL; \ 234 239 } while (/*CONSTCOND*/0) 235 240 236 241 #define QSLIST_REMOVE(head, elm, type, field) do { \ ··· 241 246 while (curelm->field.sle_next != (elm)) \ 242 247 curelm = curelm->field.sle_next; \ 243 248 curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \ 249 + (elm)->field.sle_next = NULL; \ 244 250 } \ 245 251 } while (/*CONSTCOND*/0) 246 252 ··· 304 310 } while (/*CONSTCOND*/0) 305 311 306 312 #define QSIMPLEQ_REMOVE_HEAD(head, field) do { \ 307 - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ 313 + typeof((head)->sqh_first) elm = (head)->sqh_first; \ 314 + if (((head)->sqh_first = elm->field.sqe_next) == NULL) \ 308 315 (head)->sqh_last = &(head)->sqh_first; \ 316 + elm->field.sqe_next = NULL; \ 309 317 } while (/*CONSTCOND*/0) 310 318 311 319 #define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \ ··· 329 337 if ((curelm->field.sqe_next = \ 330 338 curelm->field.sqe_next->field.sqe_next) == NULL) \ 331 339 (head)->sqh_last = &(curelm)->field.sqe_next; \ 340 + (elm)->field.sqe_next = NULL; \ 332 341 } \ 333 342 } while (/*CONSTCOND*/0) 334 343 ··· 446 455 (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \ 447 456 (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \ 448 457 (elm)->field.tqe_circ.tql_prev = NULL; \ 458 + (elm)->field.tqe_circ.tql_next = NULL; \ 459 + (elm)->field.tqe_next = NULL; \ 449 460 } while (/*CONSTCOND*/0) 450 461 451 462 /* remove @left, @right and all elements in between from @head */