From 7f1bded535ba48d699ad1c6d055afbd99d907cf3 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Thu, 7 May 2026 22:28:20 -0700 Subject: [PATCH] fix(s3api): reject lifecycle rules whose TTL overflows int32 seconds bucketLifecycleTTLRule.TtlSec is int32. AWS allows Expiration.Days up to 2,147,483,647 which would silently overflow when multiplied by LifeCycleInterval. Compute in int64, return InvalidRequest above math.MaxInt32 seconds. --- weed/s3api/s3api_bucket_handlers.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index e4988947a..ee2ba1e67 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/weed/s3api/s3api_bucket_handlers.go @@ -880,7 +880,16 @@ func (s3a *S3ApiServer) PutBucketLifecycleConfigurationHandler(w http.ResponseWr if rule.Expiration.Days == 0 { continue } - ttlSec := int32((time.Duration(rule.Expiration.Days) * util.LifeCycleInterval).Seconds()) + // Compute in int64 first, then refuse rules whose TTL won't fit + // int32 seconds. AWS allows Days up to 2,147,483,647, which would + // silently overflow if we cast directly. + ttlSecondsInt64 := int64(rule.Expiration.Days) * int64(util.LifeCycleInterval/time.Second) + if ttlSecondsInt64 > math.MaxInt32 { + glog.Errorf("PutBucketLifecycleConfigurationHandler %s: Expiration.Days=%d exceeds int32-second TTL", bucket, rule.Expiration.Days) + s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest) + return + } + ttlSec := int32(ttlSecondsInt64) lifecycleRules = append(lifecycleRules, bucketLifecycleTTLRule{ Prefix: rulePrefix, TtlSec: ttlSec,