Intro flood + luck can cause div by zero on onion service that uses PoW
Every 300 seconds we call update_suggested_effort(), which always resets rend_handled to 0 and sometimes does other stuff. If you can arrange to get a burst of intro cells onto the onion service right before it calls this update function, its rend_handled could remain 0 and still have the right circumstances for running: ``` switch (aimd_event) { case INCREASE: if (pow_state->suggested_effort < UINT32_MAX) { pow_state->suggested_effort = MAX(pow_state->suggested_effort + 1, (uint32_t)(pow_state->total_effort / pow_state->rend_handled)); } ``` It's that last "divided by rend_handled" part that's bad. I've been having trouble convincing myself of how plausible this scenario might be in practice -- you need to get a lot of intro requests queued while not letting any of them get processed in time. Do you need it to go a whole 300 second period with rend_handled staying at 0? Could this be done by having it be quiet and empty for 299 seconds and then sending a blitz of cells to make ``` pow_state->max_trimmed_effort > pow_state->suggested_effort``` true and then before it gets around to processing *any* of them, it tries the INCREASE route? Maybe. Being cautious, it is reasonable to imagine that somebody could work hard to do it, combined with some luck. And given enough random permutations of events it will eventually happen by accident too.
issue