3 ms·
Possibly completely unrelated question (this stuff is firmly over my head): toward the end of the first PoC there's /* if we don't break the loop after s
by exikyut 8y ago
Possibly completely unrelated question (this stuff is firmly over my head): toward the end of the first PoC there's
/* if we don't break the loop after some time when it doesn't
work, in NO_INTERRUPTS mode with SMP disabled, the machine will lock
up */
The bit at the top of the that says
======== Demo code (no privilege boundaries crossed) ========
is suggestive and unambiguous, but the program executions show (with "$"s) that this is being executed as non-root.
So... is this deadlock fundamentally related to the speculative execution glitch(es)?
- mrob 8y agoLocking up the machine is a possibility when you disable interrupts. Disabling interrupts with the cli instruction needs the IO privilege level (IOPL) to be at least as high as the protection ring the code is running in. Linux runs userspace code in ring 3, so the IOPL has to be set to 3 with the iopl call first. This requires the CAP_SYS_RAWIO capability, which allows you to do pretty much anything already.
- geogriffin 8y agoYou wouldn't be able to disable interrupts as non-root. The iopl syscall allows the PoC to use CLI to disable interrupts. See the "sudo" in the NO_INTERRUPTS runs: $ gcc -o test test.c -Wall -DHIT_THRESHOLD=50 -DNO_INTERRUPTS $ sudo ./test I would guess the deadlock is due to a hardware watchdog timer rebooting the system, or some other hardware function that needs to be tended to periodically before it hangs.
- pdkl95 8y agoIt doesn't look like a deadlock; turning off interrupts prevents the preemptive scheduler from running. Without a timer interrupt, the only way the scheduler would run is if it's invoked to put the process to sleep during a blocking syscall or explicitly with sched_yield(2), pthread_yield(3), etc. If interrupts are off, the the PoC program might wait forever for "hits > 32" if never testfun() never detects a "hit". Giving up after 1M bust loops ("cycles < 1000000") should prevent this from happening... but... I wonder... gcc -o test test.c -Wall -DHIT_THRESHOLD=50 -DNO_INTERRUPTS Without -O0, some optimizations are still enabled. Could a modern "clever" optimizing compiler assume that the speculative "hit" never happens and therefor conclude that "cycles" is only used after the loop when it is "guaranteed" to have the value 1000000 and "optimize" the loop into something like /*long cycles = 0;*/ //DEAD while (hits < 32 /*&& cycles < 1000000*/) { //DEAD // ... rest of loop body, maybe? /* cycles++; */ //DEAD pipeline_flush(); /*}*/ //DEAD and the sprintf() into something like: sprintf(out_, "%c: %s in 100000 cycles (hitrate: %f%%)\n", secret_read_area[idx], results, 100*hits/(double)(100000)); I'm probably worrying about nothing. Or at lest I should be worrying about nothing, but with the current trend of "clever" optimizers exploiting everything they think is provable, I'm no longer certain. bleh
- caf 8y agoThe pipeline_flush() asm block has a "memory" clobber which will certainly prevent this kind of optimisation.
- exikyut 8y agoWoops! Completely missed that, heh. There go my plans for non-root system lockup :(
- userbinator 8y agoThat makes me curious; I wonder what on a modern PC relies on periodic interrupts, and would lock up the machine if they didn't occur. I know on the original PC and XT, DRAM refresh relied on interrupts but that stopped being the case with the AT: https://www.reenigne.org/blog/how-to-get-away-with-disabling-dram-refresh/ https://www.reenigne.org/blog/how-to-get-away-with-disabling...
- gizmo686 8y agoIsn't preemption still interupt based. Without interrupts, there would be nothing to cause the CPU to stop executing the demo code. With SMP disabled, this means that nothing else will get a chance to run until the demo code yields itself (or re-enables interupts).