Quoting the documentation (emphasis theirs)
Timer callback functions execute in the context of the timer service task. It is therefore essential that timer callback functions never attempt to block. For example, a timer callback function must not call vTaskDelay(), vTaskDelayUntil(), or specify a non zero block time when accessing a queue or a semaphore.
The FreeRTOS reference book elaborates a little more, abut again without a clear explanation
It is ok to call functions such as xQueueReceive(), but only if the function’s xTicksToWait parameter (which specifies the function’s block time) is set to 0. It is not ok to call functions such as vTaskDelay(), as calling vTaskDelay() will always place the calling task into the Blocked state.
My question is: why is this such a problem? I'm waiting for a semaphore, that's set by an interrupt, in the timer callback, and it has worked fine so far. (It's used for sending long packets using a USB bulk endpoint.)
Is the only issue possibly delaying other waiting timers?