bitcoin: AddTimeData will never update nTimeOffset past 199 samples
Reading the function AddTimeData, I came to notice two things:
- The structure vTimeOffsets contains up to 200 elements, after which any new element added to it will not increase its size, replacing the oldest element.
- The condition to update nTimeOffset includes checking whether the number of elements in vTimeOffsets is odd, which will never happen after there are 200 elements.
This will lead to nTimeOffset not updating past 199 calls to AddTimeData, remaining forever stuck in whatever value it had then. I don’t believe this is the inteded behaviour. I would suggest removing the oddness check, since vTimeOffsets is capable of returning the median value of an even list according to the median method of the CMedianFilter type.
In current master, the offending code is in src/timedata.cpp, line 52, columns 34-64:
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
This should better be:
if (vTimeOffsets.size() >= 5)
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Comments: 24 (21 by maintainers)
Commits related to this issue
- Add comment about never updating nTimeOffset past 199 samples Refer to issue #4521 for details. — committed to bitcoin/bitcoin by laanwj 10 years ago
- Add comment about never updating nTimeOffset past 199 samples Refer to issue #4521 for details. — committed to reddcoin-project/reddcoin-3.10 by laanwj 10 years ago
- Add -trustlocalclock option to trust local clock source If set then the local clock is taken as authorative. If false then old logics of adjusting time with median of first 199 seen nodes are preserv... — committed to KnCMiner/bitcoin by deleted user 9 years ago
- Add -trustlocalclock option to trust local clock source If set then the local clock is taken as authorative. If false then old logics of adjusting time with median of first 199 seen nodes are preserv... — committed to KnCMiner/bitcoin by deleted user 9 years ago
- Add comment about never updating nTimeOffset past 199 samples Refer to issue #4521 for details. (cherry picked from commit 93659379bdedc29a87fe351ba2950a2c976aebd9) — committed to reddcoin-project/reddcoin-3.10 by laanwj 10 years ago
- Merge bitcoin/bitcoin#23631: p2p: Don't use timestamps from inbound peers for Adjusted Time 0c85dc30e6b628f7538a67776c7eefcb84ef4f82 p2p: Don't use timestamps from inbound peers (Martin Zumsande) Pu... — committed to bitcoin/bitcoin by fanquake 3 years ago
- Merge bitcoin/bitcoin#23631: p2p: Don't use timestamps from inbound peers for Adjusted Time 0c85dc30e6b628f7538a67776c7eefcb84ef4f82 p2p: Don't use timestamps from inbound peers (Martin Zumsande) Pu... — committed to syscoin/syscoin by fanquake 3 years ago
- Merge bitcoin/bitcoin#24080: policy: Remove unused locktime flags fa8d4d9128c35de0fe715f2e2b99269d23c09cc1 scripted-diff: Clarify CheckFinalTxAtTip name (MarcoFalke) fa4e30b0f36f2e7a09db7d30dca9008ed... — committed to bitcoin/bitcoin by deleted user 2 years ago
- Merge bitcoin/bitcoin#24080: policy: Remove unused locktime flags fa8d4d9128c35de0fe715f2e2b99269d23c09cc1 scripted-diff: Clarify CheckFinalTxAtTip name (MarcoFalke) fa4e30b0f36f2e7a09db7d30dca9008ed... — committed to syscoin/syscoin by deleted user 2 years ago
- p2p: Don't use timestamps from inbound peers Summary: > This makes it harder for others to tamper with our adjusted time. Rationale from the PR description: > With the extra feeler connections (ever... — committed to Bitcoin-ABC/bitcoin-abc by mzumsande 3 years ago
- Merge bitcoin/bitcoin#29623: Simplify network-adjusted time warning logic c6be144c4b774a03a8bcab5a165768cf81e9b06b Remove timedata (stickies-v) 92e72b5d0d49aa395e626c238bc28aba8e4c3d44 [net processin... — committed to Fabcien/bitcoin by achow101 2 months ago
I wonder if it wouldn’t be better to remove the use of GetAdjustedTime. While it works well to cover some cases of misconfigured clocks, it fails to detect others.
Then, replace it with a stronger warning mechanism that also triggers when the time is off by more than ~10 minutes? Currently it only triggers after 70 minutes.
Maybe even add setting (off by default) that shuts down the node if outbound nodes report a different time than ours?
Edit: This is probably roughly the idea from https://github.com/bitcoin/bitcoin/issues/4521#issuecomment-54685781
Since we cannot agree on what is best, I suggest we leave the computer operator to decide. Let the computer trust its own clock, and disable the network time offset altogether. If the computer is setup to sync with NTP, good, if not, then good too. I think it is a good idea to bail if the machine has an offset of more than, say five or ten minutes with respect to the median time of peers it is attempting to connect to.
These are some potential attacks:
There surely are some attack vectors that I have not considered. But these that I could come up with are already affecting the current client, even with all the network offset calculation stuff. We could make the code simpler and still run the same level of risk.
All of the platforms on which core runs have well supported time sync clients, which can be configured to use any server.
Probably. Personally I’d prefer to have clock sync as just a local problem. A mechanism such as this should be used to warn, not correct. If your time is wrong, fix it. Wrong clocks cause all kinds of issues on a system.
(this excludes drift over time due to oscillators which is outside the user’s control, of course, but correcting for that requires a more advanced algorithm and as said by @gmaxwell is not required in our case as we don’t need time to be very precise…)
I can’t help wondering, if we just used the system clock, and this scheme were suggested, would it be shot down for taking a local problem and making it vulnerable to remote attack?
And I’d better not fix my clock. bitcoind will keep applying the wrong adjustment until restart.
#4526 does not explain the potential attacks that warrant not fixing this bug. While this bug remains in place, a node can become convinced by its peers that its time is off by 70 minutes, and stay that way until restarted.
According to @gmaxwell this is unintended behavior, but protects against worse attacks:
(see discussion in #4526)