yeslogic / allsorts

Font parser, shaping engine, and subsetter implemented in Rust
https://yeslogic.com/blog/allsorts-rust-font-shaping-engine/
Apache License 2.0
726 stars 21 forks source link

Potential infinite loop in GSUB and GPOS execution #48

Open brawer opened 3 years ago

brawer commented 3 years ago

Currently, Allsorts doesn't seem to impose a limit on the iteration count during OpenType shaping. Therefore, a malicious font can trigger an infinite loop in Allsorts.

OpenType shaping can be shown to be equivalent to executing the instructions of a Turing machine. This means that there's no algorithm to reliably identify an attack font, ie. before actually executing the instructions in the GSUB and GPOS tables. (If there was such an algorithm, it would be equivalent to solving the Halting Problem for Turing machines).

Recommendation: Increment a counter for every GSUB and GPOS rule being executed. Give up when the counter exceeds a threshold. See the HarfBuzz code for a reasonable threshold value.

Test font and unit test: https://rawgit.com/unicode-org/text-rendering-tests/master/reports/Allsorts.html#GSUB-3

Technically, this test case is not really triggering an infinite loop; rather, it is a tiny font that triggers a billion rewrite steps. Anyhow, you want to impose a limit on execution time and also on the size of the memory buffer during OpenType shaping.

wezm commented 3 years ago

Thanks for opening the ticket—I should have done that as I was aware this test was failing. Just hadn't got around to working on a fix.