pjfanning opened a new pull request, #3508:
URL: https://github.com/apache/pekko/pull/3508

   ### Motivation
   Gossip interns addresses, roles, hashes and app versions into tables and 
refers to them by
   index. Every one of those indexes went straight from the wire into 
`Vector.apply` with no range
   check:
   
   | Site | Table |
   | --- | --- |
   | `ClusterMessageSerializer:551,554` | observer and subject addresses in 
reachability |
   | `:570` | member address |
   | `:578` | member role |
   | `:572` | member app version |
   | `:588` | tombstone address |
   | `:596` | seen addresses |
   | `:605` | vector clock hash, reached from both `Gossip` and `GossipStatus` |
   
   A negative or out of range index raises `IndexOutOfBoundsException` rather 
than a serialization
   failure. For a `GossipEnvelope` this lands somewhere unexpected: 
`gossipEnvelopeFromProto`
   (`:608-615`) defers the whole parse into a `() =>` thunk, so the throw 
happens inside
   `ClusterCoreDaemon` when the gossip is read, not on a deserialization thread 
where a failure
   would be contained.
   
   ### Modification
   Look the indexes up through a helper that range checks first and reports a
   `NotSerializableException` naming the index and the table size. Every index 
`gossipToProto`
   writes is in range by construction, so nothing a peer legitimately sends is 
affected.
   
   **Correction to what I reported earlier.** I had also flagged 
`memberStatusFromInt` and
   `reachabilityStatusFromInt` as reachable `NoSuchElementException`s on an 
unknown enum number.
   That is wrong: `ClusterMessages.proto` is `proto2`, where an unrecognised 
enum value is moved to
   the unknown fields and the accessor returns the default, so 
`getStatus.getNumber` is always one
   of the declared values and both maps are total over it. I had a check 
written for those two and
   removed it rather than ship defensive code that cannot fire and cannot be 
tested.
   
   ### Result
   Gossip that refers to a table entry the sender did not include is reported 
as a serialization
   failure naming the index and the size.
   
   ### Tests
   - `sbt "cluster/testOnly org.apache.pekko.cluster.protobuf.*"` — 12 passed
   
   Three new tests, each checked to discriminate by reverting the production 
file and re-running;
   all three then fail with `IndexOutOfBoundsException was thrown`:
   
   - `reject gossip that refers to a lookup table entry it did not send` — 
takes a real `Welcome`,
     decompresses it, and tampers one index at a time: an address index past 
the end, a negative
     address index, a role index, a `seen` entry, and a vector clock hash index
   - `reject a gossip status that refers to a hash it did not send` — 
`GossipStatus` reaches
     `vectorClockFromProto` without going through `Gossip`, and is not 
compressed
   - `reject a gossip envelope with a bad index when the gossip is read` — 
asserts the failure
     surfaces from `envelope.gossip`, not from `fromBinary`, which is where the 
deferred parse puts it
   
   - `sbt "cluster/mimaReportBinaryIssues"` — no issues
   - `sbt "cluster/scalafmtCheckAll" headerCreateAll` — clean
   
   ### References
   None.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to