New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore compatibility with old CSubNet serialization #20140
Conversation
886f116
to
886be97
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK
Slightly prefer if this was handled with versioning instead (i.e. bump banlist version, if there is one, have a grace period for a few versions where both are supported).
I think it's okay to eventually drop backwards compatibility for banlists, but maybe I don't take them seriously enough.
@kallewoof I agree that that would be the way to go if there was actually a feature change. There isn't. The serialization format was just gratuitously broken, and this reverts it. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. Coverage
Updated at: 2020-10-15T09:31:57.171185. |
Concept ACK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 886be97
Maybe we don't need to ignore the entries that have the IPv4 mask in the first 4 bytes (second commit) because this code was not released?
I am planning to change CSubNet::netmask
from uint8_t [16]
to just uint8_t
(CIDR netmask number) and this is tightly related. I guess I will keep the (un)serialize to use this old format of 16 bytes with IPv4 netmask at the end because introducing a version of banlist.dat
does not look justified (it will save 15 bytes per entry on disk).
@vasild Agree that there is no strong requirement to deal with files created/modified using unreleased code. But as it's perhaps a generally useful change (it guarantees that regardless of the file's contents, you'll never end up in a situation where there are entries in |
Yes! |
Thanks for the quick fix!
I agree about this train of thought. I'm fine with keeping that sanity check if it also serves another purpose, but also understand the argument to not clutter the code with special-purpose workarounds for corruption issues that were in the master branch only for a short time. At the least it would be good to add a comment with a timeframe for removing the work-around. |
I would suggest that it assert on any wonky-mask, except then you'd create a crash for anyone that had bans from current git master. You really don't want those in memory, esp if later the ban lookup is changed to a patricia trie they'll turn into memory corruption bugs (unless the author of that code remembers this possibility and inserts the sanitization there). Perhaps an alternative is to have the sanitization and the plan for removing it is to stop storing masks and instead store prefix lengths, so that the insane values are just not representable. |
@gmaxwell This deletes the wonky-mask ones immediately after loading, FWIW. The deserializer constructs them as entries with valid=false, which are then immediately pruned. |
sorry, I was intending to respond to @laanwj who seemed to not like the deleting that much! |
Oh, I missed that. @laanwj I'm thinking that this sanity check should probably stay in the code. It isn't specific to the incompatbility here - any other damage to your banlist.dat file could also mean you end up with unremovable entries, so it seems like a generic improvement to protect against that. |
Just to note that even if we store prefix lengths (CIDR), that would be stored in 1 byte and it is still possible to have insane values, e.g. 150. |
It's good to ward against corrupted data files, especially relatively unimportant ones like the ban list, but at some point, disk is a trusted interface. There are tons of ways disk corruption can crash the daemon. And sometimes it should, so that users are aware of what is happening, making things easier to diagnose (weird behavior like undeletable bans is worse, but also impossible to avoid in general). That said I'm okay with this fix as it is, and don't think this particular change is worth bikeshedding too much. It needs to be fixed as soon as possible to avoid doing more damage. |
…tion 886be97 Ignore incorrectly-serialized banlist.dat entries (Pieter Wuille) 883cea7 Restore compatibility with old CSubNet serialization (Pieter Wuille) Pull request description: bitcoin#19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of `netmask` rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in `listbanned` cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after bitcoin#19628 but without this PR). Reported by Greg Maxwell. ACKs for top commit: laanwj: Code review ACK 886be97 vasild: ACK 886be97 Tree-SHA512: d3fb91e8ecd933406e527187974f22770374ee2e12a233e7870363f52ecda471fb0b7bae72420e8ff6b6b1594e3037a5115984c023dbadf38f86aeaffcd681e7
Summary: ``` #19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of netmask rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in listbanned cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after #19628 but without this PR). ``` Backport of core [[bitcoin/bitcoin#20140 | PR20140]]. Depends on D9176. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D9178
…tion 886be97 Ignore incorrectly-serialized banlist.dat entries (Pieter Wuille) 883cea7 Restore compatibility with old CSubNet serialization (Pieter Wuille) Pull request description: bitcoin#19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of `netmask` rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in `listbanned` cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after bitcoin#19628 but without this PR). Reported by Greg Maxwell. ACKs for top commit: laanwj: Code review ACK 886be97 vasild: ACK 886be97 Tree-SHA512: d3fb91e8ecd933406e527187974f22770374ee2e12a233e7870363f52ecda471fb0b7bae72420e8ff6b6b1594e3037a5115984c023dbadf38f86aeaffcd681e7
…tion 886be97 Ignore incorrectly-serialized banlist.dat entries (Pieter Wuille) 883cea7 Restore compatibility with old CSubNet serialization (Pieter Wuille) Pull request description: bitcoin#19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of `netmask` rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in `listbanned` cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after bitcoin#19628 but without this PR). Reported by Greg Maxwell. ACKs for top commit: laanwj: Code review ACK 886be97 vasild: ACK 886be97 Tree-SHA512: d3fb91e8ecd933406e527187974f22770374ee2e12a233e7870363f52ecda471fb0b7bae72420e8ff6b6b1594e3037a5115984c023dbadf38f86aeaffcd681e7
…tion 886be97 Ignore incorrectly-serialized banlist.dat entries (Pieter Wuille) 883cea7 Restore compatibility with old CSubNet serialization (Pieter Wuille) Pull request description: bitcoin#19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of `netmask` rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in `listbanned` cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after bitcoin#19628 but without this PR). Reported by Greg Maxwell. ACKs for top commit: laanwj: Code review ACK 886be97 vasild: ACK 886be97 Tree-SHA512: d3fb91e8ecd933406e527187974f22770374ee2e12a233e7870363f52ecda471fb0b7bae72420e8ff6b6b1594e3037a5115984c023dbadf38f86aeaffcd681e7
…tion 886be97 Ignore incorrectly-serialized banlist.dat entries (Pieter Wuille) 883cea7 Restore compatibility with old CSubNet serialization (Pieter Wuille) Pull request description: bitcoin#19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of `netmask` rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in `listbanned` cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after bitcoin#19628 but without this PR). Reported by Greg Maxwell. ACKs for top commit: laanwj: Code review ACK 886be97 vasild: ACK 886be97 Tree-SHA512: d3fb91e8ecd933406e527187974f22770374ee2e12a233e7870363f52ecda471fb0b7bae72420e8ff6b6b1594e3037a5115984c023dbadf38f86aeaffcd681e7
#19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of
netmask
rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported inlistbanned
cannot be removed).Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after #19628 but without this PR).
Reported by Greg Maxwell.