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]

Reply via email to