intel / ccc-linux-guest-hardening

Linux Security Hardening for Confidential Compute
https://intel.github.io/ccc-linux-guest-hardening-docs
MIT License
66 stars 14 forks source link

[Hardening aspect] Prevent multiplication overflow in kernel timekeeping #142

Open ereshetova opened 6 months ago

ereshetova commented 6 months ago

Submission: https://lore.kernel.org/all/20240308131512.44324-1-adrian.hunter@intel.com/

Summary:

Kernel timekeeping calculates a clock value by keeping a base value and adding the number of nanoseconds since that time. Those nanoseconds are calculated from the clocksource delta. Then periodically, the base value is moved forwards (refer timekeeping_advance()) which is done by the local timer interrupt handler. It is designed such that there will always be a timer interrupt before the delta becomes big enough to overflow the 64-bit multiplication used in the conversion of delta to nanoseconds (refer timekeeping_delta_to_ns()). Obviously if timer interrupts are stopped, then the multiplication does eventually overflow.

Timekeeping multiplication overflow results in a "time loop", typically cycling about every 15 minutes with x86 TSC, for example starting at 10:00:

10:00, 10:01, 10:02 ... 10:15, 10:00, 10:01, ... 10:15, 10:00, 10:01 ...

Because a VMM can deliberately stop timer interrupts for a guest, a virtual machine can be exposed to this issue.

TDX maintains a monotonically increasing virtual TSC for a TDX guest, so the overflow is allowing a backwards movement of timekeeping that would not happen otherwise.

It is considered this could break security of cryptographic protocols that rely on the timestamps for freshness / replay protection, and consequently the kernel should prevent such a time loop.

Handle multiplication overflows by falling back to higher precision calculation when the possibility of an overflow is detected.