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;
}
In TPMCmd/tpm/src/command/EA/Policy_spt.c, ComputeAuthTimeout() negates the expiration parameter when it is negative:
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: