Skip to content

INT32_MIN negation is undefined behavior in Policy_spt.c ComputeAuthTimeout (line 149) #124

Description

In TPMCmd/tpm/src/command/EA/Policy_spt.c, ComputeAuthTimeout() negates the expiration parameter when it is negative:

if(expiration < 0)
    expiration = -expiration;

When expiration is INT32_MIN (-2147483648), negating it is signed integer overflow, which is undefined behavior under the C standard (C11 §6.5). The mathematical result +2147483648 cannot be represented in INT32, so the compiler is free to produce any result or optimize the negation away entirely. In practice this means the computed policyTime can be wildly wrong depending on the compiler and optimization level.

The concrete effect: if expiration == INT32_MIN, the cast (UINT64)expiration after the negation produces an unpredictable value, and the resulting policy session timeout is either near-zero (immediately expired) or astronomically large, depending on how the compiler handles the overflow.

Note on exploitability: expiration is included in the signed hash (PolicySigned.c line 80: CryptDigestUpdateInt(&hashState, sizeof(UINT32), in->expiration)) and verified against the caller's signature before ComputeAuthTimeout() is reached. So triggering this with INT32_MIN specifically requires holding the signing key. This is a correctness and portability bug rather than a directly exploitable vulnerability.

Fix: add a guard before the negation:

if(expiration < 0) {
    if(expiration == INT32_MIN)
        expiration = INT32_MAX;   // clamp, or return 0 to treat as no expiration
    else
        expiration = -expiration;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions