Closed
Description
As outlined in #8132.
In this case the race is around ready_index. Here is the closure:
53 do sched.deschedule_running_task_and_then |sched, task| {
54 let task_handles = task.make_selectable(ports.len());
55
56 for (index, (port, task_handle)) in
57 ports.mut_iter().zip(task_handles.consume_iter()).enumerate() {
58 // If one of the ports has data by now, it will wake the handle.
59 if port.block_on(sched, task_handle) {
60 ready_index = index;
61 break;
62 }
63 }
64 }
Since we are letting any one of the ports wake the task, the access of ready_index
has the potential to clobber arbitrary values on the task's stack.
This can't be fixed just by reordering accesses, since this is in a loop, the select implementation needs to be able to write to ready_index after storing the task handle in previous ports.