)]}'
{
  "commit": "da7ba76d152d81777b8aba117a6600e27fbca131",
  "tree": "c3c0b2bd00d01521a8dade5746ceaa1467df2550",
  "parents": [
    "cbee30a25c34542b46d462e349a2e07acf9aa54a"
  ],
  "author": {
    "name": "Roman Vinogradov",
    "email": "vinogradov.roman@gmail.com",
    "time": "Thu Feb 19 22:23:00 2026 +0100"
  },
  "committer": {
    "name": "Copybara-Service",
    "email": "copybara-worker@google.com",
    "time": "Thu Feb 19 13:24:58 2026 -0800"
  },
  "message": "[ASan] Fix crash in __asan_region_is_poisoned at application memory boundaries (#180223)\n\n`__asan_region_is_poisoned()` can crash when called on a region fully\ncontained in the last 8 bytes (shadow-granularity) before the end of an\nASan application memory range (kLowMemEnd / kMidMemEnd / kHighMemEnd).\n\nThe function performs a fast-path check by rounding UP the begin address\nand rounding DOWN the end address of the region (aligned to\n`ASAN_SHADOW_GRANULARITY`) and then scanning the corresponding shadow\nrange via `MemToShadow()` and `mem_is_zero()`. The implementation of\n`MemToShadow()` assumes that `RoundUpTo(beg, ASAN_SHADOW_GRANULARITY)`\nremains within the same application memory range. That assumption is\nincorrect near upper bound of a range: for example, begin address within\nthe last 8 bytes of the high memory range\n(`kHighMemEnd\u003d0x0000\u00277fff\u0027ffff\u0027ffff`), which is the max user address of\nVAS on x86_64, may be rounded UP so it crosses the upper bound\nkHighMemEnd. In such cases MemToShadow() is invoked on an out-of-range\naddress and crashes.\n\nPrecisely, the following calls crash in `MemToShadow(aligned_b)` because\n`aligned_b \u003d RoundUpTo(beg, ASAN_SHADOW_GRANULARITY)` returns\n`0x0000\u00278000\u00270000\u00270000` which is 1 byte beyond the VAS:\n\n`__asan_region_is_poisoned((void*)0x0000\u00277fff\u0027ffff\u0027fff9, size); // 1 \u003c\u003d\nsize \u003c\u003d 6\n__asan_region_is_poisoned((void*)0x0000\u00277fff\u0027ffff\u0027fffa, size); // 1 \u003c\u003d\nsize \u003c\u003d 5\n__asan_region_is_poisoned((void*)0x0000\u00277fff\u0027ffff\u0027fffb, size); // 1 \u003c\u003d\nsize \u003c\u003d 4\n__asan_region_is_poisoned((void*)0x0000\u00277fff\u0027ffff\u0027fffc, size); // 1 \u003c\u003d\nsize \u003c\u003d 3\n__asan_region_is_poisoned((void*)0x0000\u00277fff\u0027ffff\u0027fffd, size); // 1 \u003c\u003d\nsize \u003c\u003d 2\n__asan_region_is_poisoned((void*)0x0000\u00277fff\u0027ffff\u0027fffe, size); // size \u003d\n1`\n\nFix this by detecting cases earlier where the shadow range is empty\n(aligned_e \u003c aligned_b) and returning earlier without calling\nMemToShadow() or mem_is_zero().\n\nAdd tests checking regions at the ends of ASan LowMem, MidMem, and\nHighMem application memory ranges to ensure __asan_region_is_poisoned()\nno longer crashes on these boundary cases.\n\nGitOrigin-RevId: 35b5d13c45cd9c0d7c38120eae536f17ec9541a3\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "897a2be13e242f48f1694253a605314699fc8c64",
      "old_mode": 33188,
      "old_path": "lib/asan/asan_poisoning.cpp",
      "new_id": "b087377759919dd831eb4d2b45afe2e06a245977",
      "new_mode": 33188,
      "new_path": "lib/asan/asan_poisoning.cpp"
    },
    {
      "type": "modify",
      "old_id": "401219ac3628c6e5dc902d8a8743d884d6d96d35",
      "old_mode": 33188,
      "old_path": "lib/asan/tests/asan_noinst_test.cpp",
      "new_id": "d191d07324986851ac757cf2b2dccc9e551b305a",
      "new_mode": 33188,
      "new_path": "lib/asan/tests/asan_noinst_test.cpp"
    }
  ]
}
