[ 
https://issues.apache.org/jira/browse/HDDS-17408?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Siyao Meng updated HDDS-17408:
------------------------------
    Affects Version/s: 2.3.0

> STS revocation cutoff is overwritten on apply, so a revoke applied with a 
> lower stamp lowers the stored cutoff
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17408
>                 URL: https://issues.apache.org/jira/browse/HDDS-17408
>             Project: Apache Ozone
>          Issue Type: Bug
>    Affects Versions: 2.3.0
>            Reporter: Siyao Meng
>            Priority: Major
>         Attachments: MC-2-keep-highest-sts-revocation-cutoff.patch
>
>
> h3. Mechanism
> {{S3RevokeSTSTokenRequest.preExecute}} stamps {{revocationTimeMillis}} with 
> the current time of the OM that runs it, before the request is submitted to 
> Ratis. On apply, {{S3RevokeSTSTokenRequest.validateAndUpdateCache}} puts that 
> value into the {{s3RevokedStsTokenTable}} cache and 
> {{S3RevokeSTSTokenResponse.addToDBBatch}} writes it to the DB, both without 
> reading the cutoff already stored for the {{originalAccessKeyId}}.
> Nothing orders the stamp with the log position of the request: 
> {{OMExecutionFlow.submitExecutionToRatis}} runs {{preExecute}} and the Ratis 
> submit without a lock, and the stamps come from whichever OM runs 
> {{preExecute}}. So the stamps of two revokes for the same key do not 
> necessarily increase in log order, and when a revoke whose stamp is lower 
> than the stored cutoff is applied, every OM replaces the stored cutoff with 
> the lower value.
> h3. Trigger
> A revoke for an {{originalAccessKeyId}} is applied while the cutoff stored 
> for that key is higher than the revoke's stamp. This is the case when the 
> revoke was stamped before an earlier applied revoke for the same key was 
> stamped (stamp and apply are not ordered), or when it was stamped by an OM 
> whose clock is behind the clock that stamped the stored cutoff.
> h3. Impact
> * After the apply, the stored cutoff for the key is the lower stamp on every 
> OM, in the cache and in the DB, and it stays there when the table is loaded 
> from the DB. Only a later revoke with a higher stamp raises it; 
> {{RevokedSTSTokenCleanupService}} only deletes entries.
> * {{S3SecurityUtil.isRevokedStsToken}} compares a token's signed 
> {{creationTime}} with this stored value only. For tokens created between the 
> lower stamp and the higher one, its result follows the lower cutoff, although 
> the revoke that set the higher cutoff had been applied, until they expire.
> * No data is lost or changed. STS is not part of a released Ozone version.
> h3. Reproduction
> The regression test in the attached patch covers it and fails on unmodified 
> source: 
> {{TestS3RevokeSTSTokenRequest.testRevokeWithLowerStampKeepsStoredCutoff}} 
> ({{hadoop-ozone/ozone-manager}}) applies revokes stamped 11000, 10000 and 
> 12000 for one key through the real request and response on a real 
> {{OmMetadataManagerImpl}}, commits each response, and checks the cache and 
> the DB. Without the change it fails with {{expected: 11000L but was: 10000L}} 
> after the second revoke.
> No standalone reproduction is attached. Not run: a multi OM cluster; the test 
> sets the apply order directly.
> h3. Patch
> [^MC-2-keep-highest-sts-revocation-cutoff.patch], against 
> 5f7111a27ea07ce6b7bf5284a4213ebacb65f2ae. It also applies to master at 
> 65320362775.
> {{S3RevokeSTSTokenRequest.validateAndUpdateCache}} reads the stored cutoff 
> for the key ({{getIfExist}}) and keeps the larger of the stored value and the 
> stamp, and uses that value for both the cache entry and the response, so the 
> cache and the DB agree and a revoke never lowers the stored cutoff. The table 
> is fully cached, so the read sees every value applied before. All OMs keep 
> the same value as long as their caches agree. At this commit a purge removes 
> the row only from the DB, so an OM that kept the table in memory still holds 
> a purged cutoff; for a stamp more than 12 hours below a purged cutoff it 
> would keep a different value than an OM that loaded the table from the DB. 
> The purge change in HDDS-17406, which also removes the cached entry, closes 
> this. There is no proto change: the request still carries the stamp from 
> {{preExecute}}, and {{S3RevokeSTSTokenResponse}} is unchanged.
> One behaviour changes: a cutoff stamped ahead of real time can no longer be 
> lowered by a later revoke, so for that key STS tokens created before it are 
> rejected until real time passes it; this fails closed and is bounded by how 
> far the clock was ahead.
> This patch should land with or after HDDS-17406. Both change the test setup 
> of {{TestS3RevokeSTSTokenRequest}}, so whichever lands second needs a rebase.
> With the patch, {{TestS3RevokeSTSTokenRequest}}, {{TestS3SecurityUtil}}, 
> {{TestRevokedSTSTokenCleanupService}}, {{TestOzoneManagerRatisRequest}}, 
> {{TestS3AssumeRoleRequest}} and {{TestOmMetadataManager}} pass, and 
> checkstyle on {{hadoop-ozone/ozone-manager}} is clean.
> Found by TLA+ model checking and code review of the OM STS token revocation 
> and cleanup paths under HDDS-15926, on commit 
> 5f7111a27ea07ce6b7bf5284a4213ebacb65f2ae. Checked against HDDS issues and 
> apache/ozone pull requests for duplicates before filing. Related but not 
> duplicates: HDDS-16110 (introduced the per key revocation cutoff), HDDS-14067 
> (the revoke request and {{revokeststoken}}), HDDS-14094 (the cleanup 
> service). 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