Skip to content

fix(ecosystem): refresh OSS GMT date on every wall-clock second change - #1658

Open
Moonpuck wants to merge 1 commit into
alibaba:mainfrom
Moonpuck:fix/oss-gmt-date-clock-jump
Open

Moonpuck wants to merge 1 commit into
alibaba:mainfrom
Moonpuck:fix/oss-gmt-date-clock-jump

Conversation

@Moonpuck

@Moonpuck Moonpuck commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Background

update_gmt_date() cached the GMT Date / x-oss-date header strings and only refreshed them every 60 seconds, with the interval measured by photon::now (a CLOCK_BOOTTIME-based timestamp) while the cached values themselves came from the wall clock (std::time).

This breaks in the common sandbox suspend/resume scenario: when a sandbox wakes up, the system wall clock steps forward by the whole suspend duration (not a manual adjustment). The cached headers keep the pre-sleep timestamp, and the photon::now-based throttle does not notice the jump, so OSS requests can be signed with a stale Date for up to 60 seconds and get rejected (RequestTimeTooSkewed / signature mismatch).

Change

Drop the interval-based throttling. Every sign() reads the wall clock directly (a vDSO call, ~tens of ns) and re-formats the cached strings whenever the second changes:

void update_gmt_date() {  // avoid updating GMT Time every time
  std::time_t now = std::time(nullptr);
  if (now == m_last_tim) return;
  struct tm tm{};
  if (gmtime_r(&now, &tm)) {
    m_last_tim = now;
    strftime(m_gmt_date, GMT_DATE_LIMIT, "%a, %d %b %Y %H:%M:%S GMT", &tm);
    strftime(m_gmt_date_iso8601, GMT_DATE_LIMIT, "%Y%m%dT%H%M%SZ", &tm);
  }
}

The 1-second refresh grain exactly matches the resolution of the date formats, so it is never coarser than correctness requires, while gmtime_r + strftime still run at most once per second. The now-unused GMT_UPDATE_INTERVAL constant is removed.

After this change, the first request following a clock jump is already signed with the correct post-wake time.

Files changed

  • ecosystem/oss.cpp — rewrite update_gmt_date()
  • ecosystem/oss_constants.h — drop unused GMT_UPDATE_INTERVAL

Validation

  • Compiles cleanly, no warnings.
  • No interface changes; both signing paths (V1 / V4) are unaffected.
  • No performance impact observed in the ossfs2 project's performance regression tests.

The previous logic throttled GMT date updates via photon::now (a
monotonic-style timestamp) with a 60s interval. After a system clock
jump, the cached Date header could stay stale for up to 60 seconds,
causing OSS requests to be rejected (RequestTimeTooSkewed / signature
mismatch) until the throttle expired.

Now each sign() reads std::time() directly (a cheap vDSO call) and
re-formats the GMT strings whenever the second changes. The throttle
grain matches the 1-second resolution of the Date format, so it is
never coarser than correctness requires, and gmtime_r/strftime still
run at most once per second.
@Moonpuck Moonpuck added the need-backport A PR that should be back-ported to prior release branches (release/*) label Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

need-backport A PR that should be back-ported to prior release branches (release/*)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant