ghsa-4hwq-4cpm-8vmx
Vulnerability from github
Published
2024-02-26 20:11
Modified
2025-01-21 17:54
Summary
Vyper's `extract32` can ready dirty memory
Details

Summary

When using the built-in extract32(b, start), if the start index provided has for side effect to update b, the byte array to extract 32 bytes from, it could be that some dirty memory is read and returned by extract32.

As of v0.4.0 (specifically, commit https://github.com/vyperlang/vyper/commit/3d9c537142fb99b2672f21e2057f5f202cde194f), the compiler will panic instead of generating bytecode.

Details

Before evaluating start, the function Extract32.build_IR caches only:

  • The pointer in memory/storage to b: https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L916-L918
  • The length of b: https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L920-L922

but do not cache the actual content of b. This means that if the evaluation of start changes b's content and length, an outdated length will be used with the new content when extracting 32 bytes from b.

PoC

Calling the function foo of the following contract returns b'uuuuuuuuuuuuuuuuuuuuuuuuuuu\x00\x00789' meaning that extract32 accessed some dirty memory.

```Vyper var:Bytes[96]

@internal def bar() -> uint256: self.var = b'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu' self.var = b'' return 3

@external def foo() -> bytes32: self.var = b'abcdefghijklmnopqrstuvwxyz123456789' return extract32(self.var, self.bar(), output_type=bytes32) # returns b'uuuuuuuuuuuuuuuuuuuuuuuuuuu\x00\x00789' ```

Impact

For contracts that are affected, it means that calling extract32 returns dirty memory bytes instead of some expected output.

Show details on source website


{
   affected: [
      {
         database_specific: {
            last_known_affected_version_range: "<= 0.3.10",
         },
         package: {
            ecosystem: "PyPI",
            name: "vyper",
         },
         ranges: [
            {
               events: [
                  {
                     introduced: "0",
                  },
                  {
                     fixed: "0.4.0",
                  },
               ],
               type: "ECOSYSTEM",
            },
         ],
      },
   ],
   aliases: [
      "CVE-2024-24564",
   ],
   database_specific: {
      cwe_ids: [
         "CWE-125",
      ],
      github_reviewed: true,
      github_reviewed_at: "2024-02-26T20:11:35Z",
      nvd_published_at: "2024-02-26T20:19:05Z",
      severity: "LOW",
   },
   details: "### Summary\n\nWhen using the built-in `extract32(b, start)`, if the `start` index provided has for side effect to update `b`, the byte array to extract `32` bytes from, it could be that some dirty memory is read and returned by `extract32`.\n\nAs of v0.4.0 (specifically, commit https://github.com/vyperlang/vyper/commit/3d9c537142fb99b2672f21e2057f5f202cde194f), the compiler will panic instead of generating bytecode.\n\n### Details\n\nBefore evaluating `start`, the function `Extract32.build_IR` caches only:\n\n- The pointer in memory/storage to `b`: https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L916-L918\n- The length of `b`: https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L920-L922\n\nbut do not cache the actual content of `b`. This means that if the evaluation of `start` changes `b`'s content and length, an outdated length will be used with the new content when extracting 32 bytes from `b`.\n\n### PoC\n\nCalling the function `foo` of the following contract returns `b'uuuuuuuuuuuuuuuuuuuuuuuuuuu\\x00\\x00789'` meaning that `extract32` accessed some dirty memory.\n\n```Vyper\nvar:Bytes[96]\n\n@internal\ndef bar() -> uint256:\n    self.var = b'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu'\n    self.var = b''\n    return 3\n\n@external\ndef foo() -> bytes32:\n    self.var = b'abcdefghijklmnopqrstuvwxyz123456789'\n    return extract32(self.var, self.bar(), output_type=bytes32)\n    # returns b'uuuuuuuuuuuuuuuuuuuuuuuuuuu\\x00\\x00789'\n```\n\n### Impact\n\nFor contracts that are affected, it means that calling `extract32` returns dirty memory bytes instead of some expected output.",
   id: "GHSA-4hwq-4cpm-8vmx",
   modified: "2025-01-21T17:54:09Z",
   published: "2024-02-26T20:11:35Z",
   references: [
      {
         type: "WEB",
         url: "https://github.com/vyperlang/vyper/security/advisories/GHSA-4hwq-4cpm-8vmx",
      },
      {
         type: "ADVISORY",
         url: "https://nvd.nist.gov/vuln/detail/CVE-2024-24564",
      },
      {
         type: "WEB",
         url: "https://github.com/vyperlang/vyper/commit/3d9c537142fb99b2672f21e2057f5f202cde194f",
      },
      {
         type: "WEB",
         url: "https://github.com/pypa/advisory-database/tree/main/vulns/vyper/PYSEC-2024-205.yaml",
      },
      {
         type: "PACKAGE",
         url: "https://github.com/vyperlang/vyper",
      },
      {
         type: "WEB",
         url: "https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L916-L918",
      },
      {
         type: "WEB",
         url: "https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L920-L922",
      },
   ],
   schema_version: "1.4.0",
   severity: [
      {
         score: "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N",
         type: "CVSS_V3",
      },
   ],
   summary: "Vyper's `extract32` can ready dirty memory",
}


Log in or create an account to share your comment.

Security Advisory comment format.

This schema specifies the format of a comment related to a security advisory.

UUIDv4 of the comment
UUIDv4 of the Vulnerability-Lookup instance
When the comment was created originally
When the comment was last updated
Title of the comment
Description of the comment
The identifier of the vulnerability (CVE ID, GHSA-ID, PYSEC ID, etc.).



Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.