We discovered a potential overflow in mask computation at https://github.com/EnAccess/OpenPAYGO-HW/blob/main/src/extended/opaygo_core_extended.c#L17
uint64_t extractBitsExtended(uint64_t source, unsigned from, unsigned to)
{
unsigned long long mask = ( (1ull<<(to-from+1ull))-1ull) << from;
return (source & mask) >> 24;
}
The additional +1ull does not have an effect on the computation. However, internally it makes the number flow out of uint64_t bounds. The result is still correct when compiled with GCC for example for 64/24 the result
is produced.
There are two concerns about it
- Various C compiler might have different overflow behaviour on different platform. It's hard to guarantee this will be working consistently on all platforms and hardware.
- This behaviour can encounter problems when porting the feature to different programming languages with stricter overflow rules. See the following example in go
package main
import "fmt"
func main() {
test := ((uint64(1) << (64 - 24 + 1)) - 1) << 24
fmt.Printf("Mask in hexadecimal: %X\n", test)
}
yields
./prog.go:6:10: ((uint64(1) << (64 - 24 + 1)) - 1) << 24 (constant 36893488147402326016 of type uint64) overflows uint64
We discovered a potential overflow in mask computation at https://github.com/EnAccess/OpenPAYGO-HW/blob/main/src/extended/opaygo_core_extended.c#L17
The additional
+1ulldoes not have an effect on the computation. However, internally it makes the number flow out ofuint64_tbounds. The result is still correct when compiled with GCC for example for 64/24 the resultis produced.
There are two concerns about it
yields