Azure / Azure/AzFilesSmbMIClient
SmbRefreshTimerCallback: 32-bit integer overflow causes refresh timer to fire every ~7 minutes instead of at ticket expiration
- Dominant language
- C++
- Stars
- 0
- Forks
- 7
- Avg merge
- 6d 7h
- Merged PRs (30d)
- 1
Description
## Summary
In `SmbRefreshTimerCallback`, the calculation of the next refresh due time suffers from a 32-bit integer overflow, causing the timer to re-fire approximately every ~429 seconds (~7 minutes 9 seconds), regardless of the actual Kerberos ticket expiration time.
## Affected Code
`Windows/dll/src/AzFilesSmbMI.cpp`, inside `SmbRefreshTimerCallback`:
```cpp
LARGE_INTEGER liDueTime;
liDueTime.QuadPart = -(static_cast(dwCredentialExpiresInSeconds * 1000 * 1000 * 10));
```
## Root Cause
`static_cast` is applied **after** the multiplication has already been evaluated. `dwCredentialExpiresInSeconds` is a `DWORD` (unsigned 32-bit), and the literals `1000 * 1000 * 10` are evaluated as `int` (32-bit), so the entire multiplication is performed as a 32-bit unsigned integer operation before being cast to 64-bit.
Once `dwCredentialExpiresInSeconds` exceeds roughly 430 seconds (`2^32 / 10,000,000 ≈ 429.4967296`), the multiplication result (in 100-nanosecond units) exceeds `2^32` and wraps around, producing an unintended short due time instead of the correct one.
## Reproduction Logs
Even though the Kerberos ticket expiration is more than 84,000 seconds (over 23 hours) in the future, `SmbSetCredentialInternal` is re-executed only ~7 minutes later.
```
2026-08-27 07:19:32 [INFO] ExpirationTime: '2026-08-28T06:49:42'
2026-08-27 07:19:32 [INFO] Expires in: '84610' seconds from now (2026-08-27T07:19:32)
2026-08-27 07:26:41 [VERB] SmbSetCredentialInternal(1580) BEGIN <- re-fired after ~7m9s
2026-08-27 07:26:41 [INFO] ExpirationTime: '2026-08-28T06:49:42'
2026-08-27 07:26:41 [INFO] Expires in: '84181' seconds from now (2026-08-27T07:26:41)
2026-08-27 07:33:50 [VERB] SmbSetCredentialInternal(1580) BEGIN <- re-fired after ~7m9s again
```
### Overflow calculation verification (1st occurrence: 84610 seconds)
```
84610 × 10,000,000 = 846,100,000,000 (100ns units)
846,100,000,000 mod 4,294,967,296 = 4,286,409,984
4,286,409,984 ÷ 10,000,000 = 428.64 seconds ≈ matches observed 429s
```
### Overflow calculation verification (2nd occurrence: 84181 seconds)
```
84181 × 10,000,000 = 841,810,000,000 (100ns units)
841,810,000,000 mod 4,294,967,296 = 4,291,377,280
4,291,377,280 ÷ 10,000,000 = 429.14 seconds ≈ matches observed 429s
```
In both cases, the predicted value from the overflow calculation closely matches the observed log timing, strongly confirming the root cause.
## Impact
This affects the automatic refresh functionality driven by `SmbRefreshCredential` (the `REFRESH` command). Whenever `dwCredentialExpiresInSeconds` exceeds ~430 seconds (which is essentially always the case for normal Kerberos ticket lifetimes), the timer fires at an incorrect ~7-minute interval instead of respecting the actual expiration time.
This results in:
- Unnecessary repeated requests to the IMDS endpoint and Azure Files Service
- Increased risk of throttling / rate limiting
- Processing that should occur once every several hours (or once a day) instead running every few minutes
## Suggested Fix
Cast `dwCredentialExpiresInSeconds` to `LONGLONG` **before** performing the multiplication, so that the entire calculation is done in 64-bit arithmetic:
```cpp
liDueTime.QuadPart = -(static_cast(dwCredentialExpiresInSeconds) * 1000 * 1000 * 10);
```
## Affected File
- `Windows/dll/src/AzFilesSmbMI.cpp` (`SmbRefreshTimerCallback` function)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.