569b4e57e23d728969a12751afc6b45f32d0f093 added an argument allow_long_proto_names: bool in order to maintain compatibility with consensus methods older than 29.
The C code never added this 3rd argument and only calls it with 2, which can't be safe.
Trac: Username: cyberpunks
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items
0
Link issues together to show that they're related.
Learn more.
Instead, we decided to unconditionally reject relay descriptors, votes, and consensuses containing long protocol names.
It looks like we merged an old version of the Rust fix. It is possible that we updated the C fix to unconditionally reject bad documents, but never updated the Rust fix to match.
The C code never added this 3rd argument and only calls it with 2, which can't be safe.
In most calling conventions, Rust will read a register for the 3rd argument, but C hasn't initialised that register. Then the arbitrary (or uninitialised) value read from the register will be interpreted as a boolean.
This could cause a crash due to a register poison exception on some platforms. But on x86_64, I think will will just result in an arbitrary choice between validated and unvalidated.
If #27273 (moved) were fixed and there were rust + asan CI runs, would asan have probably caught this?
Probably not:
ASAN monitors RAM accesses, and the first few arguments are almost always passed in registers
ASAN can only find out of bounds accesses past a certain number of bytes. 1 byte or 1 word might not be far enough.
Here are some things that probably would have caught the bug:
using automated Rust to C function prototype generation (I'm sure we have a ticket for this, but I can't find it right now)
C to Rust unit tests (maybe depends on #25386 (moved)?), if the values in the uninitialised register weren't always zero, or if the architecture poisons uninitialised registers
fuzzing C against Rust (#27229 (moved)), if the values in the uninitialised register weren't always zero, or if the architecture poisons uninitialised registers
C to Rust unit tests (maybe depends on #25386 (moved)?), if the values in the uninitialised register weren't always zero, or if the architecture poisons uninitialised registers
We already have C unit tests for this function and they run against the Rust implementation in CI, don't they?
fuzzing C against Rust (#27229 (moved)), if the values in the uninitialised register weren't always zero, or if the architecture poisons uninitialised registers
Wouldn't the C fuzzing code need to know about the 3rd argument in order to fuzz it, and not knowing it's in the Rust version of the function signature is the problem?
But wait, MSan could probably catch this use of an uninitialized value.
C to Rust unit tests (maybe depends on #25386 (moved)?), if the values in the uninitialised register weren't always zero, or if the architecture poisons uninitialised registers
We already have C unit tests for this function and they run against the Rust implementation in CI, don't they?
We do, so:
the architectures we're running on don't poison uninitialised registers, and
either the value in the uninitialised register is always the same, or the unit test results don't change based on that value.
fuzzing C against Rust (#27229 (moved)), if the values in the uninitialised register weren't always zero, or if the architecture poisons uninitialised registers
Wouldn't the C fuzzing code need to know about the 3rd argument in order to fuzz it, and not knowing it's in the Rust version of the function signature is the problem?
No, not necessarily: if the value of the 3rd argument changes arbitrarily, a fuzzer would identify differences between the Rust and C implementation.
But wait, MSan could probably catch this use of an uninitialized value.
I think I tried MSan once. We would probably take a patch to add MSan as an option to configure.
That's true. Though we might as well try to follow the rustfmt rules for the commits merged to maint-0.3.3 too, right? If we introduce new style differences between the branches that weren't there before, future fixes to adjacent code will have unnecessary merge conflicts.
That's true. Though we might as well try to follow the rustfmt rules for the commits merged to maint-0.3.3 too, right? If we introduce new style differences between the branches that weren't there before, future fixes to adjacent code will have unnecessary merge conflicts.
It's nickm's code, so I'm going to let him decide if he wants to copy the rustfmt changes from 0.3.5 to 0.3.3.
Also, this ticket is missing the rust tag.
Fixed!
nickm, if you're happy with the branches as-is, please merge: