Jumptables for case..of may jump into invalid memory
Original Reporter info from Mantis: Martok @martok
-
Reporter name:
Original Reporter info from Mantis: Martok @martok
- Reporter name:
Description:
I have written about it on the ML yesterday &LtPos;http://lists.freepascal.org/pipermail/fpc-devel/2017-June/038005.html>, but after some investigation I feel there is an actual issue here.
With -O1 or above, "case Ordinal of" may generate a jumptable (essentially array[Ordinal] of CodePointer). If both the lowest and highest declared element of the type have a case label, range checking is omitted, otherwise a safety is put in place to check the number of elements of the jumptable.
If, for some reason, the input ordinal value is out of range, that results in an invalid memory access past the jumptable limits, jumping to an arbitrary (potentially attacker-controlled) location.
It also means that a potentially existing else statement (which may be intended for input validation) will never be reached, instead, the best case is a SIGSEGV.
Steps to reproduce:
See attached test program.
Additional information:
I'd say that without {$RangeChecks ON} (which, in this example, has absolutely no influence either way), the compiler can't make any assumption if X is in range or not. The only simple case where the compiler can safely omit the check is if the highest and lowest case label correspond to the base type size of the enum.
Mantis conversion info:
- Mantis ID: 32079
- Build: trunk-20170625
- Version: 3.1.1
- Monitored by: » Vincent (Vincent Snijders)