{
 "month": "2024-02",
 "generated": "2026-10-06T12:05+00:00",
 "majors": {
  "14": {
   "counts": {
    "announced": 10,
    "certain": 9,
    "probable": 0,
    "not_published": 0,
    "not_covered": 1,
    "awaiting": 0
   },
   "advisories": [
    {
     "cve": "CVE-2024-0031",
     "osv_id": "ASB-A-297524203",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "Critical",
     "types": [
      "RCE"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds an early return of nullptr in attp_build_read_by_type_value_cmd when payload_size is less than 5, so the fixed 5-byte ATT header (opcode + start handle + end handle) is never written into a heap buffer sized by a too-small payload_size.",
      "confidence": "high",
      "backport_notes": [
       "Self-contained 7-line change in one function; it depends only on the existing structure of attp_build_read_by_type_value_cmd (payload_size parameter, osi_malloc of BT_HDR). Bluetooth is a mainline module (com.android.btservices APEX), so the fix ships via module update as well as platform tags (general platform knowledge). Verify on the target branch that callers of this function handle a nullptr BT_HDR return (callers are not shown in the material)."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 5,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "de53890aaca2ae08b3ee2d6e3fd25f702fdfa661",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/Bluetooth"
     ]
    },
    {
     "cve": "CVE-2023-40093",
     "osv_id": "ASB-A-279055389",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r3",
      "date": "2023-12-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r3",
      "date": "2023-12-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/cts",
       "sha": "a952c93009cc81c41a086d73a4030a83b7683a04",
       "tag": "android-security-14.0.0_r3",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/external/pdfium",
       "sha": "03925281cf25fec70318bf2225356d022b12b566",
       "tag": "android-security-14.0.0_r3",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 2,
     "public_before_announcement_days": 59,
     "projects": [
      "platform/cts",
      "platform/external/pdfium"
     ]
    },
    {
     "cve": "CVE-2024-0014",
     "osv_id": "ASB-A-304082474",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "not-covered",
     "detail": "platform/vendor/google/services/ConfigUpdater (not in manifest)",
     "projects": [
      "platform/vendor/google/services/ConfigUpdater"
     ]
    },
    {
     "cve": "CVE-2024-0030",
     "osv_id": "ASB-A-276898739",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Clamps the GATT server response length to GATT_MAX_ATTR_LEN and copies only that many bytes in btif_to_bta_response, instead of always copying GATT_MAX_ATTR_LEN bytes and passing through an unchecked length.",
      "confidence": "high",
      "backport_notes": [
       "Single-file, self-contained change with no dependencies beyond <algorithm>. For an older tree, apply the two-line change to btif_to_bta_response in system/btif/src/btif_gatt_util.cc, or in system/bt/btif/src/btif_gatt_util.cc before the Bluetooth module relocation (general platform knowledge). Check that GATT_MAX_ATTR_LEN is the size of tGATTS_RSP::attr_value.value in that tree."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 4,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "57b823f4f758e2ef530909da07552b5aa80c6a7d",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/Bluetooth"
     ]
    },
    {
     "cve": "CVE-2024-0033",
     "osv_id": "ASB-A-294609150",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds F_SEAL_GROW | F_SEAL_SHRINK to memfd-backed shared memory created by libbinder MemoryHeapBase(FORCE_MEMFD) and by the libcutils ashmem-dev memfd backend (which also now adds F_SEAL_SEAL when a region is made read-only), so a remote process holding the fd can no longer change the size of the shared region.",
      "confidence": "high",
      "backport_notes": [
       "Two commits in two projects, both needed. The libbinder change protects MemoryHeapBase(FORCE_MEMFD) regions; the libcutils change protects memfd-backed ashmem_create_region regions. The diffs do not show any dependency between them. Apply both and update the binderMemoryHeapBaseUnitTest.cpp expectations.",
       "On older branches, check that memfd_set_prot_region has the same shape (a single F_SEAL_FUTURE_WRITE fcntl) and that memfd_create_region holds the fd in a unique_fd, so the new early return does not leak the fd."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 9,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/native",
       "sha": "aa98edf0ce9dde4886979658a459900ca987f193",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/system/core",
       "sha": "46d46dc46446f14f26fbe8fb102dd36c1dfc1229",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 2,
     "projects": [
      "platform/frameworks/native",
      "platform/system/core"
     ]
    },
    {
     "cve": "CVE-2024-0035",
     "osv_id": "ASB-A-300903792",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "SystemUI's TileLifecycleManager now overrides ServiceConnection.onNullBinding and calls executeSetBindService(false) so that a TileService returning a null binding is unbound instead of staying bound.",
      "confidence": "high",
      "backport_notes": [
       "Single self-contained commit: the production change is one method override relying on the pre-existing executeSetBindService(boolean) in TileLifecycleManager; the added test uses the existing TileLifecycleManagerTest fixtures (mHandler, mMockPackageManagerAdapter, mMockBroadcastDispatcher, mTileServiceIntent, mUser, mExecutor).",
       "No fork comparison or older-branch code was provided in the material, so applicability to other trees is unverified."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 4,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "7b7fff1eb5014d12200a32ff9047da396c7ab6a4",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0036",
     "osv_id": "ASB-A-230492947",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "In ActivityTaskManagerService.startNextMatchingActivity, the fix makes the launch use ActivityOptions with setAvoidMoveToFront() (creating basic SafeActivityOptions when none were supplied), so the replacement activity cannot bring its task to the foreground. It also wraps the start in try/finally so the cleared Binder identity is always restored.",
      "confidence": "medium",
      "backport_notes": [
       "Single-file, single-function change. It only uses SafeActivityOptions, ActivityOptions.makeBasic() and setAvoidMoveToFront() on the ActivityOptions from SafeActivityOptions.getOptions(r). On older branches, confirm these APIs exist with the same signatures.",
       "Trees that carry the later rewrite (origCallingUid as real caller, b/337726734 / b/471797575) do not have setAvoidMoveToFront at its original position. Compare with the current upstream form of this function before reintroducing it. The try/finally around the start is common to both versions."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 7,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "3eaaa9687e90c65f51762deb343f18bef95d4e8e",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0038",
     "osv_id": "ASB-A-309426390",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds caller checks to the two injectInputEventToInputFilter entry points: UiAutomationConnection now requires a trusted, connected, non-shutdown caller, and AccessibilityManagerService now enforces android.permission.INJECT_EVENTS before forwarding the event to the accessibility input filter.",
      "confidence": "high",
      "backport_notes": [
       "Both hunks are pure additions that rely on existing members: mSecurityPolicy in AccessibilityManagerService, and mLock plus the throwIf*Locked helpers in UiAutomationConnection (already used by sibling methods). The change is expected to apply wherever injectInputEventToInputFilter exists in this form."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 3,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "3e88d987235f5a2acd50a9b6bad78dbbf39cb079",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0040",
     "osv_id": "ASB-A-300007708",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "brief": {
      "summary": "MtpPacket::setParameter now calls allocate(mPacketSize) when it grows mPacketSize, so the buffer is reallocated before putUInt32 writes the parameter at the new offset.",
      "confidence": "high",
      "backport_notes": [
       "Single-commit, 3-line change. It depends on the existing MtpPacket::allocate method, which must be present in the target branch. The bulletin lists 11, 12, 12L and 13 as affected, so those branches need the same hunk applied to MtpPacket::setParameter."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 4,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/av",
       "sha": "2ca6c27dc0336fd98f47cfb96dc514efa98e8864",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/av"
     ]
    },
    {
     "cve": "CVE-2024-0041",
     "osv_id": "ASB-A-300741186",
     "source": "osv",
     "announced": "2024-02-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Rewrites SystemStatusAnimationSchedulerImpl.removePersistentDot() so that, when the status chip is ANIMATING_OUT, the hide-dot listeners are notified immediately. Before, the notification came from a coroutine that waited for a state change under a DISAPPEAR_ANIMATION_DURATION timeout, and it was silently dropped when the animator callback arrived late.",
      "confidence": "high",
      "backport_notes": [
       "Single self-contained SystemUI (Kotlin) commit. When backporting, move the animationState update out of notifyHidePersistentDot() in the same change as the removePersistentDot() rewrite. The test changes use animatorTestRule and runTest/TestScope, which the existing SystemStatusAnimationSchedulerImplTest already uses."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 6,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r5",
      "date": "2024-02-05",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "d6f7188773409c8f5ad5fc7d3eea5b1751439e26",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    }
   ],
   "tags": [
    "android-security-14.0.0_r5"
   ],
   "unannounced": [
    {
     "bug_ids": [
      "285588444"
     ],
     "commits": [
      {
       "project": "platform/frameworks/av",
       "sha": "d17ed6b7609eef0d141b95a8672baa85a283edd3",
       "subject": "Audio policy: anonymize Bluetooth MAC addresses",
       "tag": "android-security-14.0.0_r5",
       "merged": "2023-12-06",
       "markers": []
      },
      {
       "project": "platform/frameworks/base",
       "sha": "042b577709945f32a0f32635d606dcf558b794ab",
       "subject": "AudioService: anonymize Bluetooth MAC addresses",
       "tag": "android-security-14.0.0_r5",
       "merged": "2023-12-06",
       "markers": []
      }
     ],
     "tags": [
      "android-security-14.0.0_r5"
     ],
     "tag": "android-security-14.0.0_r5"
    },
    {
     "bug_ids": [
      "278265907",
      "285588444"
     ],
     "commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "32f73f2944b76c8419d359d383f83281bcf179bf",
       "subject": "Refactor the SADeviceState to AdiDeviceState",
       "tag": "android-security-14.0.0_r5",
       "merged": "2023-12-06",
       "markers": []
      }
     ],
     "tags": [
      "android-security-14.0.0_r5"
     ],
     "tag": "android-security-14.0.0_r5"
    }
   ],
   "coverage": {
    "n_ingested_tags": 30,
    "first_ingested_tag": "android-security-14.0.0_r1",
    "latest_ingested_tag": "android-security-14.0.0_r30",
    "window_base_tag": "android-14.0.0_r1",
    "window_start": "2023-10-04",
    "partial_tags": []
   },
   "platform_update_tags": {},
   "briefs": {
    "CVE-2024-0031": {
     "cve": "CVE-2024-0031",
     "summary": "Adds an early return of nullptr in attp_build_read_by_type_value_cmd when payload_size is less than 5, so the fixed 5-byte ATT header (opcode + start handle + end handle) is never written into a heap buffer sized by a too-small payload_size.",
     "component": "platform/packages/modules/Bluetooth, system/stack/gatt (ATT protocol PDU builder, att_protocol.cc)",
     "weakness": "Missing bounds check leading to heap out-of-bounds write (and a uint16 underflow in the later length clamp)",
     "root_cause": "attp_build_read_by_type_value_cmd allocates a BT_HDR with payload_size + L2CAP_MIN_OFFSET bytes of body and then unconditionally streams 5 bytes (GATT_REQ_FIND_TYPE_VALUE opcode, s_handle, e_handle) plus the UUID and the value. No check ensured payload_size was at least as large as the fixed header. If payload_size was smaller than 5, the header write itself went past the allocation; in addition, the clamp `if (p_value_type->value_len + p_buf->len > payload_size) len = payload_size - p_buf->len;` computes payload_size - p_buf->len, which for payload_size < p_buf->len underflows when stored in the uint16_t len, making the following memcpy copy far more value data than the buffer holds.",
     "fix_analysis": [
      "system/stack/gatt/att_protocol.cc:attp_build_read_by_type_value_cmd: p_buf is now initialized to nullptr and, before osi_malloc, the function returns nullptr if payload_size < 5. This guarantees the buffer can hold the 5-byte fixed header and prevents payload_size values below 5 (such as 0) from reaching the header write and the underflowing length clamp.",
      "Single-commit fix; no other files or functions changed. The commit was cherry-picked internally (Ignore-AOSP-First: security) and landed in android-security-14.0.0_r5."
     ],
     "completeness": [
      "Covers: payload_size values below the fixed 5-byte header (including 0), which were the direct trigger of writing the header past the allocation.",
      "Leaves out, judged from the code: the check does not account for the UUID appended by gatt_build_uuid_to_stream (up to 16 bytes, size depends on the UUID). For 5 <= payload_size < p_buf->len after the UUID is appended (for a 16-byte UUID, payload_size between 5 and 20), the UUID write still exceeds payload_size and `len = payload_size - p_buf->len` still underflows in uint16_t, so the subsequent memcpy length is not bounded by the allocation. Whether a caller can supply such a payload_size is not shown in the material.",
      "Callers are not changed to handle the new nullptr return; the material does not show whether callers already check for a null BT_HDR."
     ],
     "behavior_changes": [
      "attp_build_read_by_type_value_cmd returns nullptr instead of a buffer when payload_size < 5; the Find By Type Value request is therefore not built in that case."
     ],
     "preconditions": [
      "A Find By Type Value (GATT_REQ_FIND_TYPE_VALUE) request is being built with a payload_size argument smaller than 5, e.g. 0; where payload_size comes from and how that state is reached is not shown in the material.",
      "Callers of attp_build_read_by_type_value_cmd are not shown in the material (none surfaced per index search), so the exact entry points are unknown."
     ],
     "per_major": {
      "14": "same fix: commit de53890aaca2 in android-security-14.0.0_r5 (internal cherry-pick, Ignore-AOSP-First); at android-security-14.0.0_r29 all 4 lines of the patched region are present.",
      "15": "not affected per the bulletin; at android-security-15.0.0_r17 4/4 lines of the patched region are present.",
      "16": "not affected per the bulletin; at android-security-16.0.0_r8 only 3/4 lines of the patched region are present; whether the payload_size < 5 check itself is present is not shown.",
      "17": "not affected per the bulletin; at android-security-17.0.0_r1 only 3/4 lines of the patched region are present; whether the payload_size < 5 check itself is present is not shown."
     },
     "backport_notes": [
      "Self-contained 7-line change in one function; it depends only on the existing structure of attp_build_read_by_type_value_cmd (payload_size parameter, osi_malloc of BT_HDR). Bluetooth is a mainline module (com.android.btservices APEX), so the fix ships via module update as well as platform tags (general platform knowledge). Verify on the target branch that callers of this function handle a nullptr BT_HDR return (callers are not shown in the material)."
     ],
     "confidence": "high",
     "unknowns": [
      "Which caller(s) can pass payload_size < 5 and under what connection state (the material shows no callers).",
      "Whether callers check the new nullptr return value.",
      "Whether payload_size values between 5 and 20 are reachable in practice, which determines whether the residual UUID/clamp underflow path matters.",
      "Which line of the patched region differs at android-security-16.0.0_r8 and 17.0.0_r1, and whether the check is present there.",
      "Android 13 fix commit and tag (bulletin lists 13 as affected but no 13 material is provided)."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 5,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0030": {
     "cve": "CVE-2024-0030",
     "summary": "Clamps the GATT server response length to GATT_MAX_ATTR_LEN and copies only that many bytes in btif_to_bta_response, instead of always copying GATT_MAX_ATTR_LEN bytes and passing through an unchecked length.",
     "component": "platform/packages/modules/Bluetooth, system/btif GATT server (btif_gatt_util.cc)",
     "weakness": "Missing bounds check leading to out-of-bounds read (fixed-size memcpy and unclamped length field)",
     "root_cause": "In system/btif/src/btif_gatt_util.cc, btif_to_bta_response() converted a btgatt_response_t (p_src) into a tGATTS_RSP (p_dest). It copied p_src->attr_value.len into p_dest->attr_value.len unchanged, without checking it against GATT_MAX_ATTR_LEN. It then called memcpy(p_dest->attr_value.value, p_src->attr_value.value, GATT_MAX_ATTR_LEN) whatever the actual length was. Per the commit message, the valid size of p_src->attr_value.value depends on p_src->attr_value.len, so the fixed-size copy can read past the valid source data. Also per the commit message, p_dest->attr_value.len did not match the length of p_dest->attr_value.value, so downstream code (attp_build_value_cmd) could read out of bounds.",
     "fix_analysis": [
      "system/btif/src/btif_gatt_util.cc:btif_to_bta_response: p_dest->attr_value.len is now set to std::min<uint16_t>(p_src->attr_value.len, GATT_MAX_ATTR_LEN), so the destination length is capped at GATT_MAX_ATTR_LEN. This addresses the second issue in the commit message (OOB read in attp_build_value_cmd through an oversized len).",
      "system/btif/src/btif_gatt_util.cc:btif_to_bta_response: the memcpy now copies p_dest->attr_value.len bytes (the clamped length) instead of a constant GATT_MAX_ATTR_LEN, so only the first len bytes of p_src->attr_value.value are read. This addresses the first issue in the commit message (OOB read of the source).",
      "system/btif/src/btif_gatt_util.cc: adds #include <algorithm> for std::min."
     ],
     "completeness": [
      "Within btif_to_bta_response, the fix covers both the source over-read (fixed-size memcpy) and the destination length mismatch. Per index search, the only caller shown is btif_gatts_send_response_impl. The material does not show whether other paths exist.",
      "Only attr_value.len is clamped. attr_value.offset is still copied through unchanged and is not validated here. Whether downstream code checks it is not shown in the material.",
      "attp_build_value_cmd itself is not modified. The fix relies on the clamped len reaching it rather than adding a check at the consumer.",
      "The size of btgatt_response_t::attr_value.value relative to GATT_MAX_ATTR_LEN is not shown. The fix assumes the first len bytes of the source are valid."
     ],
     "behavior_changes": [
      "A GATT server response whose attr_value.len exceeds GATT_MAX_ATTR_LEN is silently truncated to GATT_MAX_ATTR_LEN bytes rather than passed through with an oversized length.",
      "Bytes of p_dest->attr_value.value beyond the clamped len are no longer written by this function. Before the fix, all GATT_MAX_ATTR_LEN bytes were overwritten."
     ],
     "preconditions": [
      "Bluetooth is enabled and a GATT server response is being sent. Per index search, btif_to_bta_response is called from btif_gatts_send_response_impl in system/btif/src/btif_gatt_server.cc, which then calls BTA_GATTS_SendRsp.",
      "A btgatt_response_t with attr_value.len greater than GATT_MAX_ATTR_LEN, or with a value buffer whose valid size is smaller than GATT_MAX_ATTR_LEN, reaches the GATT server send-response path. The material does not show where such a response comes from."
     ],
     "per_major": {
      "14": "Same fix: commit 57b823f4f758 in android-security-14.0.0_r5 (cherry-pick of internal change Change-Id Iefa66f3a293ac2072ba79853a9ec23cdfe4c1368). At android-security-14.0.0_r29, 7/8 lines of the patched region are present. The material does not say which line differs.",
      "15": "Not affected per the bulletin. At android-security-15.0.0_r17, 7/8 lines of the patched region are present.",
      "16": "Not affected per the bulletin. At android-security-16.0.0_r8, 7/8 lines of the patched region are present.",
      "17": "Not affected per the bulletin. At android-security-17.0.0_r1, 7/8 lines of the patched region are present."
     },
     "backport_notes": [
      "Single-file, self-contained change with no dependencies beyond <algorithm>. For an older tree, apply the two-line change to btif_to_bta_response in system/btif/src/btif_gatt_util.cc, or in system/bt/btif/src/btif_gatt_util.cc before the Bluetooth module relocation (general platform knowledge). Check that GATT_MAX_ATTR_LEN is the size of tGATTS_RSP::attr_value.value in that tree."
     ],
     "confidence": "high",
     "unknowns": [
      "The declared size of btgatt_response_t::attr_value.value and of tGATTS_RSP::attr_value.value. The material only states that the valid size depends on len.",
      "How attp_build_value_cmd uses attr_value.len and value. This is not shown in the diff or context.",
      "Which line differs in the 7/8 match at the latest security tags, and whether the clamped len and len-based memcpy lines are among the lines present.",
      "Whether the oversized length can come from a remote peer or only from a local caller of the GATT server API."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 4,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0033": {
     "cve": "CVE-2024-0033",
     "summary": "Adds F_SEAL_GROW | F_SEAL_SHRINK to memfd-backed shared memory created by libbinder MemoryHeapBase(FORCE_MEMFD) and by the libcutils ashmem-dev memfd backend (which also now adds F_SEAL_SEAL when a region is made read-only), so a remote process holding the fd can no longer change the size of the shared region.",
     "component": "platform/frameworks/native (libs/binder MemoryHeapBase) and platform/system/core (libcutils ashmem-dev memfd backend)",
     "weakness": "Missing file-size seals on a memfd shared across processes (improper restriction of a shared resource; a remote process could truncate a mapped region)",
     "root_cause": "Neither memfd creation path applied F_SEAL_GROW/F_SEAL_SHRINK. In libs/binder/MemoryHeapBase.cpp the FORCE_MEMFD path creates the memfd (memfd_create + ftruncate), maps it with mapfd(), and then only applied F_SEAL_FUTURE_WRITE when READ_ONLY and F_SEAL_SEAL unless MEMFD_ALLOW_SEALING_FLAG was set. A default region therefore had no size seal, and SEAL_FLAGS could be 0, in which case sealing was skipped. In libcutils/ashmem-dev.cpp, memfd_create_region did not add size seals, and memfd_set_prot_region only added F_SEAL_FUTURE_WRITE (without F_SEAL_SEAL) for read-only requests and returned 0 for a later PROT_WRITE request on an already write-protected fd. Because the fd is handed to other processes, a recipient could ftruncate the memfd and shrink the region mapped by the originating process. Per the commit messages this crashes the originating process (DoS). The bulletin rates it High/EoP.",
     "fix_analysis": [
      "platform/frameworks/native aa98edf0ce9d, libs/binder/MemoryHeapBase.cpp: MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const* name), FORCE_MEMFD branch: SEAL_FLAGS now always includes F_SEAL_GROW | F_SEAL_SHRINK, in addition to the existing conditional F_SEAL_FUTURE_WRITE (READ_ONLY) and F_SEAL_SEAL (when MEMFD_ALLOW_SEALING_FLAG is absent). SEAL_FLAGS is therefore never 0, so fcntl(fd, F_ADD_SEALS, ...) always runs after mapfd(). The existing failure handling (munmap, mBase=nullptr, mSize=0, close(fd)) is unchanged.",
      "libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp: the four Memfd* tests now expect F_SEAL_GROW | F_SEAL_SHRINK in F_GET_SEALS for every flag combination and assert that ftruncate(fd, 4096) fails (the regions are 8192 bytes where the test bodies are shown).",
      "platform/system/core 46d46dc46446, libcutils/ashmem-dev.cpp: memfd_create_region() adds fcntl(fd, F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK) after its earlier error check. On failure it logs and returns -1 (fd appears to be a unique_fd, given fd.get(), so it is closed).",
      "libcutils/ashmem-dev.cpp: memfd_set_prot_region() now first reads fcntl(fd, F_GET_SEALS) and returns -1 if that fails. If prot includes PROT_WRITE and F_SEAL_FUTURE_WRITE is already set, it fails with errno=EINVAL to match ashmem semantics, where it used to return 0. For read-only requests it now adds F_SEAL_FUTURE_WRITE | F_SEAL_SEAL (previously only F_SEAL_FUTURE_WRITE), which prevents later seal changes."
     ],
     "completeness": [
      "Covers both memfd creation paths shown: the libbinder FORCE_MEMFD constructor and the libcutils ashmem-dev memfd backend (used when has_memfd_support() is true).",
      "In MemoryHeapBase the size seals are applied regardless of READ_ONLY or MEMFD_ALLOW_SEALING_FLAG, so every memfd region created by that constructor is protected. With MEMFD_ALLOW_SEALING_FLAG, F_SEAL_SEAL is still omitted by design, so recipients can add further seals; the header comment describes this as an opt-in.",
      "The ashmem (/dev/ashmem) fallback path in MemoryHeapBase and in ashmem-dev is untouched. The system/core commit comment says the seals are added 'to match ashmem behaviour', which implies ashmem already forbids size changes.",
      "The other MemoryHeapBase constructors (for example the device path) are not changed. They do not create a memfd and are outside this fix.",
      "On non-bionic (host) builds the FORCE_MEMFD branch is compiled out and FORCE_MEMFD is cleared, as before.",
      "In MemoryHeapBase.cpp the local static memfd_create_region() (lines 43-55 at r29) still only does memfd_create + ftruncate. The seals are applied in the constructor after mapfd(), before the constructor returns."
     ],
     "behavior_changes": [
      "ftruncate (grow or shrink) on fds from MemoryHeapBase(FORCE_MEMFD), or from memfd-backed ashmem_create_region, now fails in every process, including the creator.",
      "MemoryHeapBase FORCE_MEMFD now always calls F_ADD_SEALS. If sealing fails, the region is unmapped and the fd closed. Previously sealing was skipped when SEAL_FLAGS was 0.",
      "memfd_create_region in libcutils now returns -1 if F_ADD_SEALS fails.",
      "ashmem_set_prot_region on a memfd-backed fd: requesting PROT_WRITE after the fd was made read-only now returns -1 with errno=EINVAL. Making it read-only also sets F_SEAL_SEAL, so no further seals can be added. A failing F_GET_SEALS also returns -1.",
      "New or changed log lines in both files."
     ],
     "preconditions": [
      "A process creates shared memory in one of two ways. Either via MemoryHeapBase(size, flags, name) with FORCE_MEMFD on a bionic build (the MemoryHeapBase.h comment points to audioserver as an example user). Or via ashmem_create_region when the libcutils memfd backend is active, which requires vendor VNDK level >= Q, sys.use_memfd=true, and kernel memfd/sealing support (per __has_memfd_support).",
      "The resulting fd is passed to another process, which before the fix could call ftruncate on it."
     ],
     "per_major": {
      "14": "Fixed. Both commits (frameworks/native aa98edf0ce9d and system/core 46d46dc46446) landed in android-security-14.0.0_r5. At android-security-14.0.0_r29 the patched MemoryHeapBase.cpp seal flags are present (lines 76-77). The resolver reports 6/8 lines of the system/core patched region present; the material does not show which lines differ.",
      "15": "Not affected per the bulletin (not listed). 8/8 lines of the patched region present at android-security-15.0.0_r17.",
      "16": "Not affected per the bulletin (not listed). 8/8 lines of the patched region present at android-security-16.0.0_r8.",
      "17": "Not affected per the bulletin (not listed). 8/8 lines of the patched region present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Two commits in two projects, both needed. The libbinder change protects MemoryHeapBase(FORCE_MEMFD) regions; the libcutils change protects memfd-backed ashmem_create_region regions. The diffs do not show any dependency between them. Apply both and update the binderMemoryHeapBaseUnitTest.cpp expectations.",
      "On older branches, check that memfd_set_prot_region has the same shape (a single F_SEAL_FUTURE_WRITE fcntl) and that memfd_create_region holds the fd in a unique_fd, so the new early return does not leak the fd."
     ],
     "confidence": "high",
     "unknowns": [
      "Which concrete system services or IPC paths were used to reach the unsealed memfd in the reported issue. The material only gives the generic cross-process description from the commit messages.",
      "Why the bulletin rates this EoP/High while the commit messages describe a DoS (crash of the originating process).",
      "Which 2 of 8 lines of the system/core patched region differ at android-security-14.0.0_r29 (the shown context does not include that region).",
      "Whether MemoryHeapBaseAllocator or other index-found users of MemoryHeapBase pass FORCE_MEMFD."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 9,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0035": {
     "cve": "CVE-2024-0035",
     "summary": "SystemUI's TileLifecycleManager now overrides ServiceConnection.onNullBinding and calls executeSetBindService(false) so that a TileService returning a null binding is unbound instead of staying bound.",
     "component": "platform/frameworks/base, SystemUI Quick Settings external tiles (packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java)",
     "weakness": "Improper handling of an exceptional condition: a null binding from the remote service was not handled, so a service binding created with elevated bind flags was not released.",
     "root_cause": "TileLifecycleManager.bindServices() binds an app-supplied TileService via Context.bindServiceAsUser with BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE_WHILE_AWAKE | BIND_WAIVE_PRIORITY, plus BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS when the START_ACTIVITY_NEEDS_PENDING_INTENT compat change is not enabled for the package. Before the fix, the class implemented onServiceConnected and onServiceDisconnected but not onNullBinding. When a null binding was reported, nothing unbound the connection, so SystemUI kept the app's service bound even though no tile wrapper was created.",
     "fix_analysis": [
      "packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java: adds an @Override of onNullBinding(ComponentName name) that calls executeSetBindService(false), the same method the tests use to drive binding, so the connection created in bindServices() is released when a null binding is reported.",
      "packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java: adds testNullBindingCallsUnbind, which binds with a mock Context whose bindServiceAsUser returns true, captures the ServiceConnection, invokes onNullBinding on it, runs the executor, and verifies unbindService(captor.getValue()) is called."
     ],
     "completeness": [
      "The fix covers only the onNullBinding callback; the diff adds no other ServiceConnection handling (onBindingDied handling is not shown in the material).",
      "The bind flags in bindServices() are unchanged; the fix does not reduce what a successfully bound TileService receives, it only ensures a null-binding service does not stay bound.",
      "The test runs mExecutor.runAllReady() after onNullBinding before verifying unbindService; the exact threading of executeSetBindService(false) is not shown.",
      "The fix does not touch mBindTryCount; retry behavior after a null binding is not shown in the material."
     ],
     "behavior_changes": [
      "A TileService for which a null binding is reported is now unbound by SystemUI instead of remaining bound.",
      "No new error codes or user-visible messages; the change is only in connection lifecycle handling."
     ],
     "preconditions": [
      "An app exposes a TileService that SystemUI's TileLifecycleManager binds to (bindServices() is reached for that tile's component).",
      "A null binding is reported to the ServiceConnection (onNullBinding) instead of onServiceConnected.",
      "The elevated flags involved are those passed in bindServices(): BIND_FOREGROUND_SERVICE_WHILE_AWAKE always, and BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS only when CompatChanges.isChangeEnabled(START_ACTIVITY_NEEDS_PENDING_INTENT, packageName, mUser) is false."
     ],
     "per_major": {
      "14": "same fix: commit 7b7fff1eb501 in android-security-14.0.0_r5 (cherry-pick of 7cf363d1fe7c, Change-Id Ia8126ac65432b124683960e3ebf47301ba6172a1); at android-security-14.0.0_r29 all 7/7 lines of the patched region are present.",
      "15": "not listed by the bulletin as affected; at android-security-15.0.0_r17, 6/7 lines of the patched region are present.",
      "16": "not listed by the bulletin as affected; at android-security-16.0.0_r8, 6/7 lines of the patched region are present.",
      "17": "not listed by the bulletin as affected; at android-security-17.0.0_r1, 6/7 lines of the patched region are present."
     },
     "backport_notes": [
      "Single self-contained commit: the production change is one method override relying on the pre-existing executeSetBindService(boolean) in TileLifecycleManager; the added test uses the existing TileLifecycleManagerTest fixtures (mHandler, mMockPackageManagerAdapter, mMockBroadcastDispatcher, mTileServiceIntent, mUser, mExecutor).",
      "No fork comparison or older-branch code was provided in the material, so applicability to other trees is unverified."
     ],
     "confidence": "high",
     "unknowns": [
      "The body of executeSetBindService(false) and the exact unbind/cleanup it performs are not shown (only the test's verification that unbindService is called).",
      "Whether TileLifecycleManager overrides onBindingDied, and how a null binding interacts with the bind retry logic (mBindTryCount), is not shown.",
      "Which line differs in the 6/7 match on Android 15/16/17, and why the bulletin does not list those versions despite most of the patched region being present, is not shown.",
      "Code state on Android 11, 12, 12L and 13 (listed as affected) is not in the material."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 4,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0036": {
     "cve": "CVE-2024-0036",
     "summary": "In ActivityTaskManagerService.startNextMatchingActivity, the fix makes the launch use ActivityOptions with setAvoidMoveToFront() (creating basic SafeActivityOptions when none were supplied), so the replacement activity cannot bring its task to the foreground. It also wraps the start in try/finally so the cleared Binder identity is always restored.",
     "component": "platform/frameworks/base, services/core WindowManager/ActivityTaskManager (ActivityTaskManagerService.startNextMatchingActivity)",
     "weakness": "Missing restriction on background activity launch (the activity start runs under a cleared calling identity, with the original launcher's UID as real caller, and nothing prevents move-to-front)",
     "root_cause": "startNextMatchingActivity clears the Binder calling identity and starts the next matching activity through ActivityStarter with setRealCallingUid(r.launchedFromUid), the UID of whatever launched the calling activity. It passes whatever ActivityOptions the caller supplied, possibly null. Nothing prevented the started activity from moving its task to the front. A later in-tree comment at android-security-14.0.0_r29 calls this a background activity launch through #startNextMatchingActivity: launchedFromUid may have BAL privileges (e.g. the Launcher), and the start uses its identity.",
     "fix_analysis": [
      "services/core/java/com/android/server/wm/ActivityTaskManagerService.java:startNextMatchingActivity: after Binder.clearCallingIdentity(), a new SafeActivityOptions(ActivityOptions.makeBasic()) is created when options is null, so the launch always has options to constrain.",
      "Same function: options.getOptions(r).setAvoidMoveToFront() runs before the ActivityStarter is obtained. The start executed via obtainStarter(...).setActivityOptions(options).execute() therefore carries the avoid-move-to-front flag.",
      "Same function: the obtainStarter/execute block, the r.finishing = wasFinishing restore and the return now sit in a try block with Binder.restoreCallingIdentity(origId) in finally, so the identity is restored even if the start throws. The return becomes res == ActivityManager.START_SUCCESS, with the same meaning as before."
     ],
     "completeness": [
      "The fix only constrains move-to-front on the startNextMatchingActivity path. This commit leaves the other ActivityStarter fields in that call unchanged (setCaller(r.app.getThread()), setCallingPid(-1), setRealCallingUid(r.launchedFromUid)), so the start still runs with the original launcher's UID as real caller.",
      "At android-security-14.0.0_r29 the path has been reworked. realCallingUid/realCallingPid are now the actual Binder caller (origCallingUid/origCallingPid), with a comment citing b/230492947 and b/337726734. A further identity-forwarding restriction cites b/471797575.",
      "At r29 the setAvoidMoveToFront() call no longer sits at its original position right after the null-options check. This fits the per-major data (6/8 patched lines present). Whether it was moved further down is not shown."
     ],
     "behavior_changes": [
      "Activities started via startNextMatchingActivity get avoidMoveToFront set on their options, even when the caller supplied its own ActivityOptions. Caller-supplied options are changed to set this flag.",
      "A caller that passed null options now has basic ActivityOptions attached to the launch.",
      "The Binder calling identity is now restored if the start sequence exits with an exception.",
      "Return value meaning is unchanged: true only on ActivityManager.START_SUCCESS."
     ],
     "preconditions": [
      "The call runs on an ActivityRecord r whose process (r.app) becomes the caller of the start. How r is looked up and checked is not shown in the material.",
      "A next matching activity for the intent exists. Otherwise the function returns false before this code (context lines 1385-1388).",
      "According to the later in-tree comment, the impact depends on r.launchedFromUid belonging to an app with background-activity-launch privileges (e.g. the Launcher), because that UID is used as the real calling UID."
     ],
     "per_major": {
      "14": "Same fix: commit 3eaaa9687e90 in android-security-14.0.0_r5 (cherry-pick, Change-Id Ic88dd1e79b867b44cdcd6fc86650f5de6ebcc23d). By android-security-14.0.0_r29 the region has been rewritten further (realCallingUid now origCallingUid, identity-forwarding restriction, no setAvoidMoveToFront at its original position). 6/8 patched lines present.",
      "15": "Not affected per the bulletin (not listed). android-security-15.0.0_r17 has 6/8 of the patched lines. Its code is not shown.",
      "16": "Not affected per the bulletin (not listed). android-security-16.0.0_r8 has 7/8 of the patched lines. Its code is not shown.",
      "17": "Not affected per the bulletin (not listed). android-security-17.0.0_r1 has 6/8 of the patched lines. Its code is not shown."
     },
     "backport_notes": [
      "Single-file, single-function change. It only uses SafeActivityOptions, ActivityOptions.makeBasic() and setAvoidMoveToFront() on the ActivityOptions from SafeActivityOptions.getOptions(r). On older branches, confirm these APIs exist with the same signatures.",
      "Trees that carry the later rewrite (origCallingUid as real caller, b/337726734 / b/471797575) do not have setAvoidMoveToFront at its original position. Compare with the current upstream form of this function before reintroducing it. The try/finally around the start is common to both versions."
     ],
     "confidence": "medium",
     "unknowns": [
      "Whether setAvoidMoveToFront() was moved elsewhere or removed in the latest 14/15/16/17 security tags. The r29 context does not show it at its original position and ends at line 1444.",
      "The exact content of the follow-up changes (b/337726734, b/471797575) and whether they belong to this CVE.",
      "How the activity token is checked before r is used (not in the provided context).",
      "Details of BackgroundActivityLaunchTest#testBackgroundActivityBlockedInStartNextMatchingActivity (not in the diff)."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 7,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0038": {
     "cve": "CVE-2024-0038",
     "summary": "Adds caller checks to the two injectInputEventToInputFilter entry points: UiAutomationConnection now requires a trusted, connected, non-shutdown caller, and AccessibilityManagerService now enforces android.permission.INJECT_EVENTS before forwarding the event to the accessibility input filter.",
     "component": "platform/frameworks/base, accessibility (AccessibilityManagerService) and UiAutomationConnection",
     "weakness": "missing permission check",
     "root_cause": "AccessibilityManagerService.injectInputEventToInputFilter is an @Override of IAccessibilityManager.Stub. After waiting for the input filter to be installed, it called mInputFilter.onInputEvent(event, FLAG_PASS_TO_USER | FLAG_INJECTED) without checking the caller. Likewise, UiAutomationConnection.injectInputEventToInputFilter forwarded directly to mAccessibilityManager.injectInputEventToInputFilter without the throwIfCalledByNotTrustedUidLocked / throwIfShutdownLocked / throwIfNotConnectedLocked guards that sibling methods such as syncInputTransactions and setRotation apply. Callers able to reach either Binder interface could therefore pass InputEvents to the accessibility input filter without a permission or UID check.",
     "fix_analysis": [
      "services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java:injectInputEventToInputFilter: adds mSecurityPolicy.enforceCallingPermission(Manifest.permission.INJECT_EVENTS, \"injectInputEventToInputFilter\") as the first statement, before the mLock wait loop and the mInputFilter.onInputEvent call, so callers without INJECT_EVENTS are rejected by the security policy check.",
      "core/java/android/app/UiAutomationConnection.java:injectInputEventToInputFilter: adds a synchronized (mLock) block calling throwIfCalledByNotTrustedUidLocked(), throwIfShutdownLocked(), throwIfNotConnectedLocked() before forwarding to mAccessibilityManager.injectInputEventToInputFilter(event), matching the pattern of the adjacent syncInputTransactions and setRotation methods.",
      "Single commit; both hunks are independent additions. The test referenced is CtsAccessibilityTestCases:AccessibilityManagerTest."
     ],
     "completeness": [
      "Covers both entry points visible in the material: the service-side Binder method in AccessibilityManagerService and the UiAutomationConnection proxy method (call chain per index search: UiAutomation.injectInputEventToInputFilter -> UiAutomationConnection -> AccessibilityManagerService).",
      "The AccessibilityManagerService check enforces INJECT_EVENTS on any caller of the IAccessibilityManager method. The UiAutomationConnection check adds the trusted-UID, shutdown and connection guards used by the sibling methods in that class.",
      "The input filter wait loop and the onInputEvent forwarding are unchanged; only access control is added.",
      "No other callers or similar unchecked paths are shown in the material."
     ],
     "behavior_changes": [
      "AccessibilityManagerService.injectInputEventToInputFilter now rejects callers lacking android.permission.INJECT_EVENTS through mSecurityPolicy.enforceCallingPermission.",
      "UiAutomationConnection.injectInputEventToInputFilter now throws if the caller is not the trusted UID, if the connection has been shut down, or if it is not connected (the same guards as its sibling methods)."
     ],
     "preconditions": [
      "Caller can reach the IAccessibilityManager Binder interface (AccessibilityManagerService.injectInputEventToInputFilter) or the IUiAutomationConnection interface (UiAutomationConnection.injectInputEventToInputFilter).",
      "Before the fix there was no permission or UID requirement. The accessibility input filter must be installed (mInputFilterInstalled and mInputFilter non-null) for the event to be forwarded; otherwise only a warning is logged."
     ],
     "per_major": {
      "14": "same fix: commit 3e88d987235f in android-security-14.0.0_r5 (cherry-pick of e83d6c801bb4); 6/6 patched lines present at android-security-14.0.0_r29.",
      "15": "not affected per the bulletin; the patched region (6/6 lines) is present at android-security-15.0.0_r17.",
      "16": "not affected per the bulletin; the patched region (6/6 lines) is present at android-security-16.0.0_r8.",
      "17": "not affected per the bulletin; the patched region (6/6 lines) is present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Both hunks are pure additions that rely on existing members: mSecurityPolicy in AccessibilityManagerService, and mLock plus the throwIf*Locked helpers in UiAutomationConnection (already used by sibling methods). The change is expected to apply wherever injectInputEventToInputFilter exists in this form."
     ],
     "confidence": "high",
     "unknowns": [
      "Which Android releases first introduced injectInputEventToInputFilter (the bulletin lists only 14 and 14-next).",
      "The implementation of mSecurityPolicy.enforceCallingPermission and the exact exception it throws (not shown in the material).",
      "Which calling identity UiAutomationConnection uses when it calls AccessibilityManagerService.injectInputEventToInputFilter, and whether that identity holds INJECT_EVENTS (not shown)."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 3,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0040": {
     "cve": "CVE-2024-0040",
     "summary": "MtpPacket::setParameter now calls allocate(mPacketSize) when it grows mPacketSize, so the buffer is reallocated before putUInt32 writes the parameter at the new offset.",
     "component": "platform/frameworks/av, media/mtp (libmtp, MtpPacket)",
     "weakness": "Missing buffer reallocation after a size field update (buffer size not kept in sync with packet size), which can lead to an out-of-bounds access via putUInt32",
     "root_cause": "In media/mtp/MtpPacket.cpp, MtpPacket::setParameter computes offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t). If mPacketSize is smaller than offset + sizeof(uint32_t), it raises mPacketSize to that value. The code then called putUInt32(offset, value) without reallocating the packet buffer, so the logical packet size could exceed the allocated buffer when the write happened. The commit message says this directly: the buffer size was not changed when the packet size was increased.",
     "fix_analysis": [
      "media/mtp/MtpPacket.cpp:MtpPacket::setParameter: the single-line if becomes a block. After mPacketSize = offset + sizeof(uint32_t) is assigned, the fix adds allocate(mPacketSize) before putUInt32(offset, value) runs.",
      "The index range check (index < 1 || index > 5) and the offset computation are unchanged. Only the growth path gains the reallocation."
     ],
     "completeness": [
      "Covers the only place in the shown code where mPacketSize is increased (MtpPacket::setParameter). The putUInt32 write is now preceded by allocate(mPacketSize).",
      "The implementation of allocate() is not in the material, so the code shown does not tell us whether it keeps existing buffer contents or how it handles a size no larger than the current buffer.",
      "MtpPacket::getParameter (same file) still reads getUInt32 at MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t). It checks only that the index is in 1..5 and does not compare against mPacketSize or the buffer size. The fix does not touch it.",
      "The other putUInt16/putUInt32 users in the file (setContainerCode, setTransactionID) write at fixed header offsets and are unchanged."
     ],
     "behavior_changes": [
      "When setParameter grows the packet past its current size, it now calls allocate(mPacketSize). No new error codes or return values are introduced.",
      "There may be an extra allocation on the setParameter growth path."
     ],
     "preconditions": [
      "MtpPacket::setParameter must be called with an index in 1..5 whose parameter slot lies beyond the current mPacketSize.",
      "setParameter is outside the MTP_HOST-only section of the file. The concrete callers of setParameter are not shown in the material."
     ],
     "per_major": {
      "14": "same fix: commit 2ca6c27dc033 in android-security-14.0.0_r5 (cherry-pick of e1494a2d8e7e). 4/4 lines of the patched region are present at android-security-14.0.0_r29.",
      "15": "not affected per the bulletin. The fixed code (allocate(mPacketSize) in setParameter) is present at android-security-15.0.0_r17 (4/4 lines).",
      "16": "not affected per the bulletin. The fixed code is present at android-security-16.0.0_r8 (4/4 lines).",
      "17": "not affected per the bulletin. The fixed code is present at android-security-17.0.0_r1 (4/4 lines)."
     },
     "backport_notes": [
      "Single-commit, 3-line change. It depends on the existing MtpPacket::allocate method, which must be present in the target branch. The bulletin lists 11, 12, 12L and 13 as affected, so those branches need the same hunk applied to MtpPacket::setParameter."
     ],
     "confidence": "high",
     "unknowns": [
      "The implementation of MtpPacket::allocate is not in the material: whether it copies existing data, whether it can shrink the buffer, and how it tracks the buffer size.",
      "The material does not show which MtpServer/MtpDevice paths call setParameter on a packet whose mPacketSize is below the parameter offset.",
      "How other code uses mPacketSize after it has grown is not shown.",
      "The bulletin type is ID (information disclosure). The material does not show the exact disclosure path, only the size/buffer mismatch in setParameter."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 4,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-0041": {
     "cve": "CVE-2024-0041",
     "summary": "Rewrites SystemStatusAnimationSchedulerImpl.removePersistentDot() so that, when the status chip is ANIMATING_OUT, the hide-dot listeners are notified immediately. Before, the notification came from a coroutine that waited for a state change under a DISAPPEAR_ANIMATION_DURATION timeout, and it was silently dropped when the animator callback arrived late.",
     "component": "platform/frameworks/base, SystemUI status bar events (SystemStatusAnimationSchedulerImpl, privacy/persistent dot)",
     "weakness": "Race condition / timeout-based synchronization that caused a required cleanup callback (onHidePersistentDot) to be skipped",
     "root_cause": "In packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt, removePersistentDot() handled the ANIMATING_OUT state by launching a coroutine on coroutineScope. That coroutine ran withTimeout(DISAPPEAR_ANIMATION_DURATION) { animationState.first { SHOWING_PERSISTENT_DOT || IDLE || ANIMATION_QUEUED }; notifyHidePersistentDot() }. The state transition it waited for is driven by the animator's onAnimationEnd callback. If that callback arrived more than DISAPPEAR_ANIMATION_DURATION after the removal request, the timeout expired and notifyHidePersistentDot() was never called. Listeners were then never told to hide the dot, so the persistent dot was not removed even though hasPersistentDot had been set to false. The new test testDotIsRemoved_evenIfAnimatorCallbackIsDelayed reproduces this case: it advances the test scheduler past DISAPPEAR_ANIMATION_DURATION before the animator fires, which the test comment says caused the old code to miss the callback. In addition, notifyHidePersistentDot() itself changed animationState (to ANIMATION_QUEUED or IDLE) when the state was SHOWING_PERSISTENT_DOT.",
     "fix_analysis": [
      "SystemStatusAnimationSchedulerImpl.kt:removePersistentDot(): the ANIMATING_OUT branch no longer launches a coroutine with withTimeout. It calls notifyHidePersistentDot() synchronously (the function starts with Assert.isMainThread()). The comment says animationState will be updated later by the onAnimationEnd callback, so the hide notification no longer depends on animator timing.",
      "SystemStatusAnimationSchedulerImpl.kt:removePersistentDot(): the SHOWING_PERSISTENT_DOT branch now calls notifyHidePersistentDot() and then sets animationState to ANIMATION_QUEUED if scheduledEvent.value != null, otherwise IDLE. The two separate ifs became an if / else if chain.",
      "SystemStatusAnimationSchedulerImpl.kt:notifyHidePersistentDot(): the block that changed animationState when in SHOWING_PERSISTENT_DOT was removed. The function now only collects the listener animators (listeners.mapNotNull { it.onHidePersistentDot() }) and plays them. Updating the state is now the job of removePersistentDot().",
      "SystemStatusAnimationSchedulerImplTest.kt: two existing tests drop testScheduler.runCurrent() after removePersistentDot(). One of them now verifies onHidePersistentDot() right after the call. The new test testDotIsRemoved_evenIfAnimatorCallbackIsDelayed advances the coroutine scheduler by DISAPPEAR_ANIMATION_DURATION + 1 before advancing the animator, then asserts that the callback fires once and that the state ends as IDLE."
     ],
     "completeness": [
      "The fix covers both states in which a dot is visible or about to appear when removePersistentDot() is called: SHOWING_PERSISTENT_DOT (hide and update the state synchronously) and ANIMATING_OUT (hide synchronously, state left to onAnimationEnd).",
      "States before ANIMATING_OUT get no explicit hide call. Per the in-code comment, they rely on hasPersistentDot = false so that the disappear animation removes the chip without turning it into a dot. The fix does not change this path, and the test testPrivacyDot_isRemovedDuringChipAnimation covers it.",
      "The coroutine and timeout are removed entirely rather than given a longer timeout, so this path no longer depends on DISAPPEAR_ANIMATION_DURATION.",
      "In the ANIMATING_OUT branch, the fix relies on the onAnimationEnd callback (not shown in the diff) to move animationState out of ANIMATING_OUT. The diff does not change that callback."
     ],
     "behavior_changes": [
      "When the chip is ANIMATING_OUT, listener onHidePersistentDot() is now invoked synchronously inside removePersistentDot(), before the disappear animation finishes, instead of after the state change.",
      "removePersistentDot() no longer launches a coroutine.",
      "notifyHidePersistentDot() no longer changes animationState. In the diff, removePersistentDot() updates the state itself. Any other callers of notifyHidePersistentDot() are not shown in the material.",
      "Test expectations changed: in testPrivacyDot_isRemoved, onHidePersistentDot is verified right after removePersistentDot() without running the test scheduler."
     ],
     "preconditions": [
      "hasPersistentDot is true (set when an event has forceVisible, per the context), and removePersistentDot() is called on the main thread while animationState == ANIMATING_OUT.",
      "The animator's onAnimationEnd callback for the disappear animation arrives more than DISAPPEAR_ANIMATION_DURATION after the removal request, so the old withTimeout expired first.",
      "Callers of removePersistentDot() are not shown in the provided material."
     ],
     "per_major": {
      "14": "Same fix: commit d6f718877340, applied in android-security-14.0.0_r5. It is a cherry-pick of internal commit d027036adf63, Change-Id I7380cb956b48c38bdd540b297287786cf35b94f2. At android-security-14.0.0_r29, 6/8 lines of the patched region are present, and the context shows the new if/else-if structure in removePersistentDot().",
      "15": "Not affected per the bulletin. At android-security-15.0.0_r17, 6/8 lines of the patched region are present.",
      "16": "Not affected per the bulletin. At android-security-16.0.0_r8, 5/8 lines of the patched region are present.",
      "17": "Not affected per the bulletin. At android-security-17.0.0_r1, 5/8 lines of the patched region are present."
     },
     "backport_notes": [
      "Single self-contained SystemUI (Kotlin) commit. When backporting, move the animationState update out of notifyHidePersistentDot() in the same change as the removePersistentDot() rewrite. The test changes use animatorTestRule and runTest/TestScope, which the existing SystemStatusAnimationSchedulerImplTest already uses."
     ],
     "confidence": "high",
     "unknowns": [
      "The material does not show who calls removePersistentDot() or under what runtime conditions the animator callback is delayed.",
      "The onAnimationEnd handler that the ANIMATING_OUT branch now relies on to update animationState is not in the diff or the context.",
      "The material does not show whether notifyHidePersistentDot() has callers other than removePersistentDot().",
      "The material does not explain how a stale persistent dot maps to the bulletin's EoP classification.",
      "The material does not show why 15, 16 and 17 are not listed by the bulletin, or whether the fix is fully present there."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 6,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    }
   }
  },
  "15": {
   "counts": {
    "announced": 0,
    "certain": 0,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [],
   "tags": [],
   "unannounced": [],
   "coverage": {
    "n_ingested_tags": 18,
    "first_ingested_tag": "android-security-15.0.0_r1",
    "latest_ingested_tag": "android-security-15.0.0_r18",
    "window_base_tag": "android-15.0.0_r1",
    "window_start": "2024-09-03",
    "partial_tags": []
   },
   "platform_update_tags": {},
   "briefs": {}
  },
  "16": {
   "counts": {
    "announced": 0,
    "certain": 0,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [],
   "tags": [],
   "unannounced": [],
   "coverage": {
    "n_ingested_tags": 9,
    "first_ingested_tag": "android-security-16.0.0_r1",
    "latest_ingested_tag": "android-security-16.0.0_r9",
    "window_base_tag": "android-16.0.0_r2",
    "window_start": "2025-06-10",
    "partial_tags": []
   },
   "platform_update_tags": {},
   "briefs": {}
  },
  "17": {
   "counts": {
    "announced": 0,
    "certain": 0,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [],
   "tags": [],
   "unannounced": [],
   "coverage": {
    "n_ingested_tags": 2,
    "first_ingested_tag": "android-security-17.0.0_r1",
    "latest_ingested_tag": "android-security-17.0.0_r2",
    "window_base_tag": "android-17.0.0_r1",
    "window_start": "2026-06-16",
    "partial_tags": []
   },
   "platform_update_tags": {},
   "briefs": {}
  }
 },
 "bulletin": {
  "url": "https://source.android.com/docs/security/bulletin/2024-02-01",
  "latest_version": "1.0",
  "latest_revision": {
   "version": "1.0",
   "date": "February 5, 2024",
   "notes": "Bulletin Published."
  },
  "revisions": [
   {
    "version": "1.0",
    "date": "February 5, 2024",
    "notes": "Bulletin Published."
   }
  ],
  "tracked_since": "2026-09-30",
  "changes_since_tracking": [],
  "out_of_scope_rows": {
   "Arm components": 3,
   "MediaTek components": 9,
   "Qualcomm closed-source components": 13,
   "Qualcomm components": 4,
   "Unisoc components": 2
  },
  "note": "changes are only visible from `tracked_since`; earlier revisions of the bulletin cannot be reconstructed. Out-of-scope rows (vendor closed-source, kernel) have no public AOSP code to resolve."
 }
}