Siyao Meng created HDDS-17440:
---------------------------------
Summary: Block token verification should check that the request's
container ID is the container of the token's block
Key: HDDS-17440
URL: https://issues.apache.org/jira/browse/HDDS-17440
Project: Apache Ozone
Issue Type: Bug
Reporter: Siyao Meng
Attachments: CR-13-check-block-token-container.patch
h3. Mechanism
A block token is issued for one block, identified by its container ID and local
ID ({{OzoneBlockTokenIdentifier}}), so it authorizes commands for the container
that holds that block. {{BlockTokenVerifier}} matches the token against the
block ID carried inside the command ({{HddsUtils.getBlockID}}, for example the
block ID of {{WriteChunk}}, {{PutBlock}} or {{GetBlock}}), and
{{HddsDispatcher.dispatchRequest}} selects the container by the command's top
level {{containerID}}. The verifier does not check that the two container IDs
are equal, so that half of the invariant is left to the code that builds the
request.
The verification has worked this way since the per command block token check
was added in HDDS-2321, so every release from 0.5.0 onwards has it (code
reading at each release tag).
h3. Compatibility
Every stock request builder sets the top level container ID from the block it
names: the {{ContainerProtocolCalls}} helpers used by {{BlockOutputStream}},
{{ECBlockOutputStream}}, {{ChunkInputStream}}, {{BlockExtendedInputStream}},
the filesystem clients and the debug tools, {{BlockInputStream}} for its
{{GetBlock}}, {{StreamBlockInputStream}}, and the freon datanode generators. EC
reconstruction and container reconciliation on the datanode use the same
streams and helpers. {{XceiverClientGrpc}}, {{XceiverClientShortCircuit}} and
{{ContainerCommandRequestMessage}} copy requests and keep the field. Commands
already in a Raft log are not affected, because the token is checked when a
command is submitted, not when it is applied. This is from code reading, plus
the suites listed below.
h3. Impact
Requests built by stock clients already satisfy the invariant, so they behave
the same with and without the change. The change makes the datanode enforce the
invariant itself.
h3. Reproduction
No standalone reproduction is attached. The regression test in the attached
patch covers the check and fails on unmodified source:
* {{TestOzoneBlockTokenSecretManager.tokenCannotBeUsedForOtherContainer}}
({{hadoop-hdds/framework}}): a signed token for one block must be rejected for
a {{WriteChunk}} and a {{GetBlock}} on that block whose top level container ID
is not the block's. Without the change it fails with {{Expecting code to raise
a throwable.}} The existing {{tokenCanBeUsedForSpecificBlock}} and the access
mode tests in the same class cover the accepted cases.
h3. Patch
[^CR-13-check-block-token-container.patch], against
7212465c0bb19615708c144238317db51c2a696d. It also applies to master at
1acf315d546.
{{BlockTokenVerifier.verify}} now also checks, after the existing block and
access mode checks, that the command's top level {{containerID}} equals the
container ID of its block, and otherwise throws {{BlockTokenException}} ("Block
token with <service> can't be used to access container <id>"), which the
dispatcher reports as {{BLOCK_TOKEN_VERIFICATION_FAILED}} like the other token
checks. It applies to every command that requires a block token
({{HddsUtils.requireBlockToken}}) and does nothing when block tokens are
disabled. There is no wire or protocol change.
With the patch the token verifier suites in {{hadoop-hdds/framework}}
({{TestOzoneBlockTokenSecretManager}}, {{TestBlockTokenVerifier}},
{{TestContainerTokenVerifier}}, {{TestOzoneBlockTokenIdentifier}}),
{{TestHddsDispatcher}}, and the secure and EC integration suites
{{TestBlockTokens}}, {{TestSecureOzoneRpcClient}},
{{TestSecureOzoneContainer}}, {{TestSecureContainerServer}},
{{TestContainerCommandsEC}} and {{TestContainerCommandReconciliation}} pass,
and checkstyle on {{hadoop-hdds/framework}} is clean.
Found by code review as part of the TLA+ verification effort under HDDS-15926,
on commit 7212465c0bb19615708c144238317db51c2a696d. Checked against HDDS issues
and apache/ozone pull requests for duplicates before filing. Related but not
duplicates: HDDS-2321 (added the per command block token check), HDDS-5236
(extended the set of commands that require a block token). The attached patch
is a proposal for review. Generated with Specula (Claude Opus 5.5).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]