Skip to content

Potential overflow in mask computation #22

@dmohns

Description

@dmohns

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

0xFFFFFFFFFF000000

is produced.

There are two concerns about it

  1. 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.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions