summaryrefslogtreecommitdiff
path: root/lib/workqueue.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2021-12-01 16:28:42 -0500
committerDonald Sharp <sharpd@nvidia.com>2022-02-04 12:05:38 -0500
commit07b9ebca65832813cc00722401f282a51a11ac17 (patch)
tree84d883616148d4dfff7e32ed2ad76915fd7fcf79 /lib/workqueue.c
parent66a59f87435e5cb7be61a9566c3aecc8c3bcc5d7 (diff)
zebra: Ensure zebra_nhg_sweep_table accounts for double deletes
I'm seeing this crash in various forms: Program terminated with signal SIGSEGV, Segmentation fault. 50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. [Current thread is 1 (Thread 0x7f418efbc7c0 (LWP 3580253))] (gdb) bt (gdb) f 4 267 (*func)(hb, arg); (gdb) p hb $1 = (struct hash_bucket *) 0x558cdaafb250 (gdb) p *hb $2 = {len = 0, next = 0x0, key = 0, data = 0x0} (gdb) I've also seen a crash where data is 0x03. My suspicion is that hash_iterate is calling zebra_nhg_sweep_entry which does delete the particular entry we are looking at as well as possibly other entries when the ref count for those entries gets set to 0 as well. Then we have this loop in hash_iterate.c: for (i = 0; i < hash->size; i++) for (hb = hash->index[i]; hb; hb = hbnext) { /* get pointer to next hash bucket here, in case (*func) * decides to delete hb by calling hash_release */ hbnext = hb->next; (*func)(hb, arg); } Suppose in the previous loop hbnext is set to hb->next and we call zebra_nhg_sweep_entry. This deletes the previous entry and also happens to cause the hbnext entry to be deleted as well, because of nhg refcounts. At this point in time the memory pointed to by hbnext is not owned by the pthread anymore and we can end up on a state where it's overwritten by another pthread in zebra with data for other incoming events. What to do? Let's change the sweep function to a hash_walk and have it stop iterating and to start over if there is a possible double delete operation. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'lib/workqueue.c')
0 files changed, 0 insertions, 0 deletions