{
 "month": "2024-03",
 "generated": "2026-10-06T12:05+00:00",
 "majors": {
  "14": {
   "counts": {
    "announced": 12,
    "certain": 12,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [
    {
     "cve": "CVE-2024-0039",
     "osv_id": "ASB-A-295887535",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "Critical",
     "types": [
      "RCE"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds running size accounting (size_now) with a CHECK_SIZE guard before every write in attp_build_value_cmd, so the ATT PDU builder frees the buffer and returns nullptr instead of writing past the payload_size-sized allocation. It also widens and validates the Read By Type pair-length field.",
      "confidence": "medium",
      "backport_notes": [
       "Backport the Reland (Change-Id I291fd665, 06f9a5f1526b), not the first landing Ie16251c3. The first version omits the p++ when it reserves the Read By Type pair-length byte, so it emits malformed PDUs. If Ie16251c3 is already present, apply the reland on top. The net effect is 'p_pair_len = p++;', LOG_ERROR, and no extra 'payload_size > size_now' condition.",
       "Because the function can now return nullptr, check in the target branch that every caller of attp_build_value_cmd handles a null result (the callers are not shown in the material). On older branches the LOG_ERROR macro may need to become LOG(ERROR), as in the first landing."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "bd2d00da33f0de28768b9dcd79c334088316604d",
       "tag": "android-security-14.0.0_r5",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "06f9a5f1526b576503b92994e6e02746bddb95d0",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "b140db65f6bc09cea2e4954c5875aebebf6c58b9",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 3,
     "first_commit_before_announcement_days": 25,
     "multi_tag_fix": true,
     "projects": [
      "platform/packages/modules/Bluetooth"
     ]
    },
    {
     "cve": "CVE-2024-23717",
     "osv_id": "ASB-A-318374503",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "Critical",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Removes the p_dev_rec->is_device_authenticated() conjunct from access_secure_service_from_temp_bond() in system/stack/btm/btm_sec.cc. The helper now flags any remote-initiated access to a service requiring incoming authentication from a temporarily bonded device, not only when the device record is already marked authenticated.",
      "confidence": "medium",
      "backport_notes": [
       "Single commit with a one-line logic change in a static helper in btm_sec.cc. To apply it, remove the is_device_authenticated() conjunct. If a fork has inline copies of this predicate, check each one.",
       "Bluetooth is a mainline module (com.android.btservices) from Android 13 onward (general platform knowledge). The commit's Test line builds com.android.btservices."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "618374db66c05c67a9c31eeb43cdf9205549fff0",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/Bluetooth"
     ]
    },
    {
     "cve": "CVE-2023-40081",
     "osv_id": "ASB-A-284297452",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "brief": {
      "summary": "SystemUI's MediaDataManager now asks UriGrantsManagerService, through a new hidden binder method checkGrantUriPermission_ignoreNonSystem, whether the media app's uid may read a resumable media artwork URI before SystemUI loads that bitmap.",
      "confidence": "high",
      "backport_notes": [
       "The fix spans three parts that depend on each other and should land together: the AIDL method in IUriGrantsManager.aidl, its implementation in UriGrantsManagerService.java (system_server), and the SystemUI caller in MediaDataManager.kt. The mediaEntries/appUid lookup must also move above the artwork load, as in the diff. The SystemUI file path may differ on other branches: per index search, an Android 14 tree contains media/controls/domain/pipeline/MediaDataManager.kt.",
       "The new tests use ExtendedMockito static mocking of UriGrantsManager and ImageDecoder, so the target branch's SystemUI tests need that test dependency."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 8,
       "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_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/frameworks/base",
       "sha": "162be1ccbbb098abe6fc3380ffceb17a948e6c4b",
       "tag": "android-security-14.0.0_r3",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "public_before_announcement_days": 88,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0045",
     "osv_id": "ASB-A-300903400",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds an SMP command length validation at the start of smp_proc_sec_req in system/stack/smp/smp_act.cc. A Security Request command with an invalid length is now rejected with SMP_INVALID_PARAMETERS instead of being parsed, which addresses an out-of-bounds read when auth_req is read from the payload.",
      "confidence": "high",
      "backport_notes": [
       "Self-contained 7-line insertion in smp_act.cc. The target tree must already have smp_command_has_invalid_length, SMP_INVALID_PARAMETERS, SMP_AUTH_CMPL_EVT and smp_sm_event, because the commit adds none of them."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/Bluetooth",
       "sha": "16c3f8dc40b2f8fded9c51e4beb759ee8170a353",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/Bluetooth"
     ]
    },
    {
     "cve": "CVE-2024-0046",
     "osv_id": "ASB-A-299441833",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds a check in the install-existing-package path of InstallPackageHelper so that a request carrying INSTALL_INSTANT_APP is rejected with INSTALL_FAILED_INVALID_URI when the target package is a system app or an updated system app.",
      "confidence": "high",
      "backport_notes": [
       "Single 3-line insertion. The only dependencies are PackageSetting.isSystem()/isUpdatedSystemApp() and the local `instantApp` boolean already present in the method. If backporting from the r29 tree, drop the isPackageDeviceAdmin/isProtectedPackage terms unless those locals exist in the target."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 2,
       "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "022aff702e6607ca21d2eb6947f126e8d59a61c5",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0047",
     "osv_id": "ASB-A-311687929",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "DoS"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Three frameworks/base commits make UserManagerService persist device policy global and local user restrictions under distinct XML tags, read the pre-userVersion-10 local restriction format correctly on upgrade, and force DevicePolicyEngine to re-sync global and per-user restriction state into UserManager whenever a DPC sets or clears a user restriction.",
      "confidence": "medium",
      "backport_notes": [
       "Apply in order 3cd8a2c783fc (writer tags, also adds the test helper setUserRestrictions), then bd5cc7f03256 (depends on the prior test and on RestrictionsSet.readRestrictions/mergeAll and mUserVersion being available), then f51673939874 (DevicePolicyEngine, separate file; requires UserRestrictionPolicyKey, BooleanPolicyValue and the policy engine). No fork comparison was provided in the material."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "3cd8a2c783fc736627b38f639fe4e239abcf6af1",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/frameworks/base",
       "sha": "bd5cc7f03256b328438b9bc3791c6b811a2f1f17",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/frameworks/base",
       "sha": "f516739398746fef7e0cf1437d9a40e2ad3c10bb",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 3,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0048",
     "osv_id": "ASB-A-316893159",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Schedules a 15 minute MESSAGE_TIMED_OUT message for every AccountManagerService.Session at construction, so that a session still open at timeout runs onTimedOut(), which calls getResponseAndClose() and reports an error to the caller.",
      "confidence": "medium",
      "backport_notes": [
       "Single commit adding 10 lines to one file. It uses the existing MESSAGE_TIMED_OUT, mHandler, cancelTimeout and onTimedOut. The constant block around the insertion point differs between tags (r29 has MAXIMUM_PASSWORD_LENGTH and STORAGE_LIMIT_PER_USER next to it), so the hunk context may need manual adjustment. Check on each branch that MessageHandler routes MESSAGE_TIMED_OUT to Session.onTimedOut."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "813900c458e9113e27d8d44a912b1c7ae281381c",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-0049",
     "osv_id": "ASB-A-273936274",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds isValidOMXParam() validation at the start of the six VP8/VP9/Android-VPx OMX get/set parameter handlers in the libstagefright software VPx encoders. When the caller-supplied parameter struct fails validation, they now return OMX_ErrorBadParameter and log a SafetyNet event.",
      "confidence": "high",
      "backport_notes": [
       "Single self-contained commit. It only depends on isValidOMXParam() and android_errorWriteLog already being available to these files (both are used elsewhere in libstagefright OMX components, general platform knowledge). Insert the guard as the first statement of each of the six handlers, before the nPortIndex check. The bulletin lists 12, 12L and 13 as affected, so the same change applies there if the files are present."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/av",
       "sha": "6a4f0a82bbf3fba44ab79e9380e0428123f3e668",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/av"
     ]
    },
    {
     "cve": "CVE-2024-0050",
     "osv_id": "ASB-A-273935108",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds isValidOMXParam() validation of the client-supplied DescribeHDR10PlusInfoParams structure in SoftVideoDecoderOMXComponent::getConfig and SoftVideoDecoderOMXComponent::internalSetConfig before the structure is used.",
      "confidence": "high",
      "backport_notes": [
       "Self-contained 8-line change that relies only on the isValidOMXParam() template already used elsewhere in the same file. Apply it inside the kDescribeHdr10PlusInfoIndex cases, immediately after the DescribeHDR10PlusInfoParams casts. Consider also carrying the later b/329641908 nParamSize-vs-nSize check visible at android-security-14.0.0_r29."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/av",
       "sha": "23a035af9be9f4ec6fe16a5fb9710d19ef669eec",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/av"
     ]
    },
    {
     "cve": "CVE-2024-0051",
     "osv_id": "ASB-A-276442130",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds an end-of-list check to the outQueue search loop in SoftMPEG4::onQueueFilled. If the current output header is not found, the decoder now returns instead of walking past the end of the output buffer list.",
      "confidence": "high",
      "backport_notes": [
       "A single, self-contained commit that changes one loop in SoftMPEG4::onQueueFilled. The bulletin also lists 12, 12L and 13 as affected. The added `++it;` line has one extra leading space compared with the surrounding code; keep this in mind when doing line-based presence checks."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/av",
       "sha": "3bedd18fd3f4465162666592a2850da9f4c0ff48",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/av"
     ]
    },
    {
     "cve": "CVE-2024-0052",
     "osv_id": "ASB-A-303871379",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Makes the Health Connect change-log read path apply the same exercise-route access rules as the normal read path. ExerciseSessionRecord routes returned through getChangeLogs are now limited to the caller's own sessions unless the caller holds READ_EXERCISE_ROUTE.",
      "confidence": "high",
      "backport_notes": [
       "The fix changes method signatures in RecordHelper.getReadTableRequest / getExtraDataReadRequests, ReadTransactionRequest and DataPermissionEnforcer.collectExtraReadPermissionToStateMapping. Any downstream RecordHelper subclass that overrides the UUID-based getExtraDataReadRequests must be updated to the new 4-argument form. Both HealthConnectServiceImpl call sites (readRecords and getChangeLogs) must be adapted together. HealthFitness ships as a mainline module, so the service code is normally updated through the module rather than the platform image (general platform knowledge).",
       "The RecentAccessViewModelTest.kt and HealthConnectUiTestHelper.kt hunks are unrelated test adjustments and can be dropped if they do not apply."
      ],
      "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/HealthFitness",
       "sha": "178f4824574fdf33ed4ac584d092240d1c771b04",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/HealthFitness"
     ]
    },
    {
     "cve": "CVE-2024-0053",
     "osv_id": "ASB-A-281525042",
     "source": "osv",
     "announced": "2024-03-01",
     "severity": "High",
     "types": [
      "ID"
     ],
     "status": "resolved",
     "brief": {
      "summary": "PrintManagerService.getCustomPrinterIcon now checks URI-based custom printer icons returned by a print service and returns null for any icon whose URI encodes a user id whose profile parent is not getCurrentUserId().",
      "confidence": "medium",
      "backport_notes": [
       "The change is confined to PrintManagerImpl in one file. It uses existing helpers in the same class (resolveCallingUserEnforcingPermissions, resolveCallingProfileParentLocked, getCurrentUserId) and the mLock field.",
       "Only 4/5 lines of the patched region match on every latest security tag. Before applying, check how the region differs and that the helpers exist with the same signatures."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 8,
       "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_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "bf68f31ff7fa42712820be61bc13cf8f68f285eb",
       "tag": "android-security-14.0.0_r6",
       "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_r6"
   ],
   "unannounced": [],
   "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-0039": {
     "cve": "CVE-2024-0039",
     "summary": "Adds running size accounting (size_now) with a CHECK_SIZE guard before every write in attp_build_value_cmd, so the ATT PDU builder frees the buffer and returns nullptr instead of writing past the payload_size-sized allocation. It also widens and validates the Read By Type pair-length field.",
     "component": "platform/packages/modules/Bluetooth, GATT/ATT stack (system/stack/gatt/att_protocol.cc)",
     "weakness": "Missing bounds check leading to heap out-of-bounds write (plus unsigned arithmetic underflow and uint8_t truncation of a length field)",
     "root_cause": "attp_build_value_cmd allocates sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET. It then writes, in order: the opcode; a 1-byte pair length (GATT_RSP_READ_BY_TYPE only); a 2-byte handle (all opcodes except GATT_RSP_READ_BLOB/GATT_RSP_READ); a 2-byte offset (prepare write req/rsp only); and finally the value. It never checks that payload_size is large enough for the fixed header bytes. The only check was 'if (payload_size - p_buf->len < len) len = payload_size - p_buf->len'. When payload_size is smaller than the bytes already emitted, this subtraction is negative and the comparison is true. The negative result is assigned to the uint16_t len, which gives a large length for ARRAY_TO_STREAM and a heap overflow. The pair_len field was also a uint8_t computed as len + 2, so it was silently truncated.",
     "fix_analysis": [
      "Commit bd2d00da33f0 / b140db65f6bc (Change-Id Ie16251c3, first landing, android-security-14.0.0_r5 and _r6), system/stack/gatt/att_protocol.cc:attp_build_value_cmd. It introduces size_t size_now (starting at 1 for the opcode) and a local CHECK_SIZE() macro: when size_now > payload_size, the macro logs 'payload size too small', calls osi_free(p_buf) and returns nullptr. CHECK_SIZE is invoked before the opcode write, after adding 1 for the pair-length byte, after adding 2 for the handle, after adding 2 for the offset, and after adding len for the value. pair_len becomes size_t and is no longer written up front. Instead it is backfilled at the end through p_pair_len, after a 'pair_len > UINT8_MAX' check that frees the buffer and returns nullptr. The value branch gains an extra 'payload_size > size_now' condition, and truncation now uses size_now instead of p_buf->len. p_buf->len is set once at the end from size_now.",
      "Defect in the first landing: in the GATT_RSP_READ_BY_TYPE branch it sets 'p_pair_len = p;' without advancing p (the removed UINT8_TO_STREAM used to advance it). As a result, the handle and the fields after it are written one byte early, the backfilled pair length overwrites the first handle byte, and the last byte counted in size_now is never written.",
      "Commit 06f9a5f1526b (Change-Id I291fd665, 'Reland', android-security-14.0.0_r6, also lists Bug 315127634) changes the same file and function and is diffed against the same pre-fix base. It uses the same size_now/CHECK_SIZE/backfill scheme, with three differences: 'p_pair_len = p++;' reserves the byte correctly; logging switches to LOG_ERROR(...); and the extra 'payload_size > size_now' condition is dropped. CHECK_SIZE already guarantees size_now <= payload_size, so payload_size - size_now cannot go negative. The reland adds 'Test: atest net_test_stack_gatt'. Per index search, stack_gatt_test.cc has tests (attp_build_value_cmd_no_p_data, _full_p_data, _partial_p_data, _p_data_null) that exercise the function through a legacy::testing declaration."
     ],
     "completeness": [
      "Every write site inside attp_build_value_cmd (opcode, pair length, handle, offset, value) is now preceded by a size check against payload_size, for every opcode path the function handles.",
      "The underflow is removed structurally: because CHECK_SIZE runs after each header increment, payload_size - size_now is non-negative when the value length is clamped.",
      "The pair_len > UINT8_MAX case now fails the build (nullptr) instead of silently truncating. The final cast of p_buf->len to uint16_t is bounded by payload_size (a uint16_t), so it cannot truncate.",
      "The fix changes only this function. The callers that consume its return value are not in the diff, so the material does not show whether every caller tolerates a nullptr return.",
      "attp_build_opcode_cmd (shown in context) allocates a fixed 1-byte payload and is unaffected. Other builders in att_protocol.cc are not shown."
     ],
     "behavior_changes": [
      "attp_build_value_cmd can now return nullptr, where previously it always returned a buffer. This happens when payload_size is smaller than the header bytes the opcode requires, or when the Read By Type pair length would exceed 255.",
      "New error logs: 'payload size too small' and a 'pair_len greater than' UINT8_MAX message.",
      "The first landing (Ie16251c3) produced malformed GATT_RSP_READ_BY_TYPE PDUs because p was not advanced past the pair-length byte. The reland (I291fd665) restores the correct layout."
     ],
     "preconditions": [
      "attp_build_value_cmd must be invoked either with a payload_size smaller than the fixed header bytes for the given op_code (1 opcode + optional 1 pair-length + 2 handle + optional 2 offset), or with a len/payload combination that makes payload_size - p_buf->len negative.",
      "The function is static in att_protocol.cc. Its production callers are not in the material; per index search, only the stack_gatt_test.cc unit tests are shown."
     ],
     "per_major": {
      "14": "Fixed via two landings: Ie16251c3 (bd2d00da33f0 in android-security-14.0.0_r5, also b140db65f6bc in _r6), followed by the corrected Reland I291fd665 (06f9a5f1526b in android-security-14.0.0_r6). The android-security-14.0.0_r29 code shows the reland form ('p_pair_len = p++;', LOG_ERROR), which is consistent with the 7/8 line match of the patched region.",
      "15": "Not affected (not listed by the bulletin). 7/8 lines of the patched region are present at android-security-15.0.0_r17.",
      "16": "Not affected (not listed by the bulletin). 7/8 lines of the patched region are present at android-security-16.0.0_r8.",
      "17": "Not affected (not listed by the bulletin). 7/8 lines of the patched region are present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Backport the Reland (Change-Id I291fd665, 06f9a5f1526b), not the first landing Ie16251c3. The first version omits the p++ when it reserves the Read By Type pair-length byte, so it emits malformed PDUs. If Ie16251c3 is already present, apply the reland on top. The net effect is 'p_pair_len = p++;', LOG_ERROR, and no extra 'payload_size > size_now' condition.",
      "Because the function can now return nullptr, check in the target branch that every caller of attp_build_value_cmd handles a null result (the callers are not shown in the material). On older branches the LOG_ERROR macro may need to become LOG(ERROR), as in the first landing."
     ],
     "confidence": "medium",
     "unknowns": [
      "The material does not show the production callers of attp_build_value_cmd, or how payload_size and len reach it from remote traffic (including whether payload_size derives from the negotiated ATT MTU).",
      "Whether callers were separately updated to handle a nullptr return is not shown.",
      "Why both b140db65f6bc (original) and 06f9a5f1526b (reland) appear in android-security-14.0.0_r6. The 'Reland' title implies an intervening revert, but none is shown.",
      "Whether Bug 315127634 tracks the missing p++ defect is not stated.",
      "Which form of the code is present in Android 15-17 is not shown beyond the 7/8 line match."
     ],
     "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."
     }
    },
    "CVE-2024-23717": {
     "cve": "CVE-2024-23717",
     "summary": "Removes the p_dev_rec->is_device_authenticated() conjunct from access_secure_service_from_temp_bond() in system/stack/btm/btm_sec.cc. The helper now flags any remote-initiated access to a service requiring incoming authentication from a temporarily bonded device, not only when the device record is already marked authenticated.",
     "component": "platform/packages/modules/Bluetooth, system/stack/btm (BTM security manager, btm_sec.cc)",
     "weakness": "Incorrect authorization condition (security check bypass due to an over-restrictive predicate)",
     "root_cause": "access_secure_service_from_temp_bond() is the utility that tests whether an access to a secure service from a temporary bond is happening. Before the fix it returned true only when all four of these held: the request was not locally initiated, security_req had BTM_SEC_IN_AUTHENTICATE, p_dev_rec->is_device_authenticated() was true, and p_dev_rec->is_bond_type_temporary() was true. Because of the is_device_authenticated() conjunct, the helper did not detect a temporarily bonded remote device whose record was not marked authenticated. The commit describes this as a security bypass, and the bulletin rates it Critical EoP.",
     "fix_analysis": [
      "system/stack/btm/btm_sec.cc:access_secure_service_from_temp_bond: deletes `p_dev_rec->is_device_authenticated() &&` from the return expression. The predicate becomes `!locally_initiated && (security_req & BTM_SEC_IN_AUTHENTICATE) && p_dev_rec->is_bond_type_temporary()`.",
      "Effect: the helper now returns true for every remote-initiated request that requires incoming authentication on a device whose bond type is temporary, whatever its authenticated state."
     ],
     "completeness": [
      "The fix changes only the predicate in access_secure_service_from_temp_bond(). The function is static, so its callers are in btm_sec.cc. They are not shown in the material and are not changed by this commit.",
      "The check is still limited to !locally_initiated and BTM_SEC_IN_AUTHENTICATE. As before, this helper does not evaluate locally initiated connections or requirements other than incoming authentication.",
      "The commit does not change how is_bond_type_temporary() is set. The fix depends on the bond type being recorded correctly as temporary."
     ],
     "behavior_changes": [
      "The helper returns true in more cases: it now includes temporarily bonded, remote-initiated, IN_AUTHENTICATE requests where the device record is not flagged authenticated. The caller-side effect, most likely a stricter denial of access, is not shown in the material.",
      "The diff adds no new APIs or error codes."
     ],
     "preconditions": [
      "A remote (not locally initiated) peer whose tBTM_SEC_DEV_REC has a temporary bond type requests a service whose security requirements include BTM_SEC_IN_AUTHENTICATE.",
      "The device record's authenticated flag is not set when the check runs (this is the state the old predicate missed).",
      "The material does not show which pairing flow is needed."
     ],
     "per_major": {
      "14": "Same fix: commit 618374db66c0 in android-security-14.0.0_r6 (cherry-pick of internal 62944f39f502, Change-Id I48df2c2d77810077e97d4131540277273d441998). At android-security-14.0.0_r29 the function body shows the fixed predicate without is_device_authenticated(), and 5/6 lines of the patched region are present.",
      "15": "Not affected per the bulletin. At android-security-15.0.0_r17, 4/6 lines of the patched region are present. The code is not shown, so check that is_device_authenticated() is absent from the predicate.",
      "16": "Not affected per the bulletin. At android-security-16.0.0_r8, 4/6 lines of the patched region are present. Check the predicate as for 15.",
      "17": "Not affected per the bulletin. At android-security-17.0.0_r1, 4/6 lines of the patched region are present. Check the predicate as for 15."
     },
     "backport_notes": [
      "Single commit with a one-line logic change in a static helper in btm_sec.cc. To apply it, remove the is_device_authenticated() conjunct. If a fork has inline copies of this predicate, check each one.",
      "Bluetooth is a mainline module (com.android.btservices) from Android 13 onward (general platform knowledge). The commit's Test line builds com.android.btservices."
     ],
     "confidence": "medium",
     "unknowns": [
      "The material does not include the call sites of access_secure_service_from_temp_bond() or the action taken when it returns true.",
      "The material does not show which pairing or bonding flow leaves a temporary bond record without the authenticated flag set.",
      "The bulletin lists Android 13 as affected, but no Android 13 commit is provided, so it is unknown whether 13 received the same change.",
      "Why only 4/6 lines of the patched region match on 15, 16 and 17, and what the predicate looks like there."
     ],
     "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-2023-40081": {
     "cve": "CVE-2023-40081",
     "summary": "SystemUI's MediaDataManager now asks UriGrantsManagerService, through a new hidden binder method checkGrantUriPermission_ignoreNonSystem, whether the media app's uid may read a resumable media artwork URI before SystemUI loads that bitmap.",
     "component": "platform/frameworks/base, SystemUI media controls (MediaDataManager) plus UriGrantsManagerService / IUriGrantsManager",
     "weakness": "missing permission check (confused deputy: a privileged process reads an app-supplied content URI without verifying the app's own access)",
     "root_cause": "In packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt, the resumption path (the \"adding track for $userId from browser\" code that builds MediaData from a MediaDescription) called loadBitmapFromUri(desc.iconUri!!) directly when desc.iconBitmap was null. It never checked whether the originating app (appUid/packageName) had read access to that URI.",
     "fix_analysis": [
      "core/java/android/app/IUriGrantsManager.aidl: adds a new hidden binder method, int checkGrantUriPermission_ignoreNonSystem(int sourceUid, String targetPkg, in Uri uri, int modeFlags, int userId).",
      "services/core/java/com/android/server/uri/UriGrantsManagerService.java:checkGrantUriPermission_ignoreNonSystem: new implementation. It first calls the new private helper isCallerIsSystemOrPrivileged(), which accepts SYSTEM_UID, ROOT_UID, or a caller holding INTERACT_ACROSS_USERS_FULL (checked via ActivityManager.checkComponentPermission). For a non-privileged caller it returns Process.INVALID_UID without throwing. Otherwise it clears the calling identity, delegates to the existing checkGrantUriPermissionUnlocked(callingUid, targetPkg, uri, modeFlags, userId) and restores the identity in finally. Per its javadoc, that method throws SecurityException if the grant is not allowed.",
      "packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt: in the resumption path, the lookups currentEntry = mediaEntries.get(packageName) and appUid = currentEntry?.appUid ?: Process.INVALID_UID now happen before the artwork load. loadBitmapFromUri(desc.iconUri!!) is replaced by loadBitmapFromUriForUser(desc.iconUri!!, userId, appUid, packageName).",
      "MediaDataManager.kt:loadBitmapFromUriForUser (new): calls UriGrantsManager.getService().checkGrantUriPermission_ignoreNonSystem(appUid, packageName, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, userId)). It calls loadBitmapFromUri(uri) only if that call does not throw. On SecurityException it logs \"Failed to get URI permission\" and returns null.",
      "packages/SystemUI/tests/.../MediaDataManagerTest.kt: adds static mocks for UriGrantsManager and ImageDecoder. It also adds two tests, testResumeMediaLoaded_hasArtPermission_artLoaded and testResumeMediaLoaded_noArtPermission_noArtLoaded, which check that artwork is loaded only when the check does not throw."
     ],
     "completeness": [
      "The fix covers only the resumable media path in MediaDataManager.kt. The generic loadBitmapFromUri helper is kept, and the diff does not show its other call sites, so the material does not show whether those sites have a separate check.",
      "The grant check uses appUid = currentEntry?.appUid ?: Process.INVALID_UID. If mediaEntries has no entry for packageName, the check runs with callingUid = -1. The material does not show how checkGrantUriPermissionUnlocked handles that value.",
      "checkGrantUriPermission_ignoreNonSystem fails open for non-privileged callers: it returns INVALID_UID instead of throwing. The SystemUI caller ignores the return value and stops only on SecurityException, so the check is effective only if SystemUI passes isCallerIsSystemOrPrivileged(). The material does not show SystemUI's permissions.",
      "The check uses only FLAG_GRANT_READ_URI_PERMISSION, which matches the read-only use (bitmap decode)."
     ],
     "behavior_changes": [
      "Resumable media artwork given by URI is now dropped (artwork is null and Log.e reports \"Failed to get URI permission\") when the check throws SecurityException for the media app's uid.",
      "system_server gains the new hidden binder method IUriGrantsManager.checkGrantUriPermission_ignoreNonSystem. It returns -1 for callers that are not system or root and lack INTERACT_ACROSS_USERS_FULL. For other callers it delegates to checkGrantUriPermissionUnlocked.",
      "One extra binder call to system_server happens for each resumable-media artwork load that uses iconUri."
     ],
     "preconditions": [
      "SystemUI media resumption adds an entry through the MediaDataManager resumption path (the \"adding track ... from browser\" branch that reads a MediaDescription).",
      "The MediaDescription has no iconBitmap but has an iconUri set by the app."
     ],
     "per_major": {
      "14": "same fix: commit 162be1ccbbb0 in android-security-14.0.0_r3 (cherry-pick of 470f62bc8954, Change-Id Ie79915d3d1712f08dc2e8dfbd5bc7fd32bb308a3). At android-security-14.0.0_r29, 8/8 lines of the patched region are present.",
      "15": "not affected (not listed by the bulletin). The patched region (8/8 lines) is present at android-security-15.0.0_r17.",
      "16": "not affected (not listed by the bulletin). The patched region (8/8 lines) is present at android-security-16.0.0_r8.",
      "17": "not affected (not listed by the bulletin). The patched region (8/8 lines) is present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "The fix spans three parts that depend on each other and should land together: the AIDL method in IUriGrantsManager.aidl, its implementation in UriGrantsManagerService.java (system_server), and the SystemUI caller in MediaDataManager.kt. The mediaEntries/appUid lookup must also move above the artwork load, as in the diff. The SystemUI file path may differ on other branches: per index search, an Android 14 tree contains media/controls/domain/pipeline/MediaDataManager.kt.",
      "The new tests use ExtendedMockito static mocking of UriGrantsManager and ImageDecoder, so the target branch's SystemUI tests need that test dependency."
     ],
     "confidence": "high",
     "unknowns": [
      "How checkGrantUriPermissionUnlocked behaves when callingUid is Process.INVALID_UID (no existing media entry for the package).",
      "Whether other callers of loadBitmapFromUri in MediaDataManager.kt have an equivalent URI permission check.",
      "Whether SystemUI passes isCallerIsSystemOrPrivileged(), i.e. holds INTERACT_ACROSS_USERS_FULL; otherwise the check returns -1 and never throws.",
      "The exact fix commits and file paths on the Android 12, 12L and 13 branches; the material contains only the Android 14 commit."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 8,
      "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-0045": {
     "cve": "CVE-2024-0045",
     "summary": "Adds an SMP command length validation at the start of smp_proc_sec_req in system/stack/smp/smp_act.cc. A Security Request command with an invalid length is now rejected with SMP_INVALID_PARAMETERS instead of being parsed, which addresses an out-of-bounds read when auth_req is read from the payload.",
     "component": "platform/packages/modules/Bluetooth, system/stack/smp (BLE Security Manager Protocol, built as com.android.btservices)",
     "weakness": "Missing length/bounds check on a received SMP command before reading its payload (out-of-bounds read)",
     "root_cause": "smp_proc_sec_req (system/stack/smp/smp_act.cc) unconditionally dereferenced p_data->p_data as a tBTM_LE_AUTH_REQ to get auth_req. It did not first check that the received Security Request command had a valid length, so a malformed command could cause a read beyond the valid command data (commit title: OOB bug in smp_proc_sec_req; bulletin type ID, information disclosure).",
     "fix_analysis": [
      "system/stack/smp/smp_act.cc:smp_proc_sec_req: before auth_req is read, the function now calls smp_command_has_invalid_length(p_cb). If that reports an invalid length, it builds a tSMP_INT_DATA with status = SMP_INVALID_PARAMETERS, posts SMP_AUTH_CMPL_EVT to the SMP state machine via smp_sm_event, and returns without touching p_data->p_data.",
      "The rest of the function (btm_ble_link_sec_check and the sec_req_act switch) is unchanged and now runs only for commands that pass the length check.",
      "Single commit, 7 lines added. The commit does not define smp_command_has_invalid_length; it uses it as an existing function."
     ],
     "completeness": [
      "Covers only the Security Request handler smp_proc_sec_req.",
      "The fix depends on smp_command_has_invalid_length(p_cb) correctly assessing the received command length. The helper is not modified and its definition is not in the material.",
      "The commit changes no other code paths or handlers. The material does not show whether other SMP handlers that dereference p_data->p_data have the same guard."
     ],
     "behavior_changes": [
      "A Security Request with an invalid length now causes SMP_AUTH_CMPL_EVT to be posted with status SMP_INVALID_PARAMETERS. The function returns early, so no encryption or pairing action is taken from that request.",
      "Security Requests that pass the length check are processed as before."
     ],
     "preconditions": [
      "Bluetooth LE enabled and an LE link to a remote device that can send SMP commands.",
      "The SMP state machine must dispatch the received Security Request to smp_proc_sec_req. Per index search, the only other user found is the test mock in system/test/mock/mock_stack_smp_act.h."
     ],
     "per_major": {
      "14": "same fix: commit 16c3f8dc40b2 in android-security-14.0.0_r6 (cherry-pick of an internal change, Merged-In I400cfa3523c6d8b25c233205748c2db5dc803d1d). All 5 lines of the patched region are present at android-security-14.0.0_r29.",
      "15": "not affected (not listed by the bulletin). The patched region is fully present (5/5 lines) at android-security-15.0.0_r17.",
      "16": "not affected (not listed by the bulletin). The patched region is fully present (5/5 lines) at android-security-16.0.0_r8.",
      "17": "not affected (not listed by the bulletin). 4/5 lines of the patched region are present at android-security-17.0.0_r1; the material does not show the difference."
     },
     "backport_notes": [
      "Self-contained 7-line insertion in smp_act.cc. The target tree must already have smp_command_has_invalid_length, SMP_INVALID_PARAMETERS, SMP_AUTH_CMPL_EVT and smp_sm_event, because the commit adds none of them."
     ],
     "confidence": "high",
     "unknowns": [
      "The material does not include the definition of smp_command_has_invalid_length or show how the expected length for the Security Request command is derived.",
      "The material does not show whether other SMP handlers are guarded the same way.",
      "What the SMP state machine does after receiving SMP_AUTH_CMPL_EVT with SMP_INVALID_PARAMETERS is not shown.",
      "The exact difference in the patched region at android-security-17.0.0_r1 is not shown.",
      "The bulletin lists Android 13 as affected, but the provided per-major facts do not show whether it got the same change.",
      "The material does not show whether user interaction is needed to trigger the issue, or which device role sends the triggering command."
     ],
     "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-0046": {
     "cve": "CVE-2024-0046",
     "summary": "Adds a check in the install-existing-package path of InstallPackageHelper so that a request carrying INSTALL_INSTANT_APP is rejected with INSTALL_FAILED_INVALID_URI when the target package is a system app or an updated system app.",
     "component": "platform/frameworks/base, PackageManagerService / InstallPackageHelper (install existing package as user)",
     "weakness": "Missing validation (no check that the target of an instant-app install-existing request is not a system / updated-system package)",
     "root_cause": "In services/core/java/com/android/server/pm/InstallPackageHelper.java, the method that installs an already-present package for a user (the one whose cross-user check is labelled \"installExistingPackage for user\") computed `instantApp` from the INSTALL_INSTANT_APP install flag. After confirming the PackageSetting existed, it went on to install the package for the user without checking whether it was a system or updated-system package. The only instant-app related gate was `snapshot.canViewInstantApps(...)`, which is about whether the caller can see instant apps, not about what kind of package the target is. So a caller that passed the INSTALL_PACKAGES / INSTALL_EXISTING_PACKAGES permission check could have a system app installed for a user as an instant app. The commit title says this should be disallowed.",
     "fix_analysis": [
      "InstallPackageHelper.java (install-existing path, inside `synchronized (mPm.mLock)` right after the `pkgSetting == null || pkgSetting.getPkg() == null` check): adds `if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp())) return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender);`. This rejects the request before the canViewInstantApps check and before any state change (setInstalled / setHidden / writePackageRestrictionsLPr).",
      "The check runs under mPm.mLock against the PackageSetting just read from mPm.mSettings.",
      "At android-security-14.0.0_r29 the same condition is extended with `|| isPackageDeviceAdmin || isProtectedPackage` (local booleans computed before the lock from mPm.isPackageDeviceAdmin and mPm.mProtectedPackages.isPackageStateProtected). That extension is not part of commit 022aff702e66; it comes from a later change that the material does not include."
     ],
     "completeness": [
      "The fix covers only the install-existing path in InstallPackageHelper.java. It rejects instant installs when the PackageSetting is system or updated-system.",
      "The commit itself does not cover device-admin or protected packages. The r29 tree shows those were added to the same condition later.",
      "The regular APK install path (a new install session with INSTALL_INSTANT_APP) is not touched by this commit. The material does not show whether an equivalent check exists there, so no conclusion is drawn.",
      "The check uses the PackageSetting flags, not per-user state. It does not depend on whether the user already has the package installed."
     ],
     "behavior_changes": [
      "Install-existing requests with INSTALL_INSTANT_APP that target a system or updated-system package now fail with PackageManager.INSTALL_FAILED_INVALID_URI (a code this method already returns for other rejections) instead of succeeding.",
      "No change for non-instant (full app) install-existing requests or for non-system packages."
     ],
     "preconditions": [
      "Caller must pass the INSTALL_PACKAGES / INSTALL_EXISTING_PACKAGES permission check (lines 641-645 of the context) and enforceCrossUserPermission for the target user.",
      "Target user must not be restricted by UserManager.DISALLOW_INSTALL_APPS.",
      "installFlags must include PackageManager.INSTALL_INSTANT_APP.",
      "The target package must already exist in mPm.mSettings with a non-null getPkg(), and must be a system or updated-system package for the new check to apply."
     ],
     "per_major": {
      "14": "same fix: commit 022aff702e66 in android-security-14.0.0_r6 (Change-Id Idd89a6dd72f0e68259095f677185f0494391025c). At android-security-14.0.0_r29 the patched region is present (5/5 lines), and the condition has been extended with isPackageDeviceAdmin || isProtectedPackage by a later change.",
      "15": "not affected per the bulletin; the patched region is present (5/5 lines) at android-security-15.0.0_r17.",
      "16": "not affected per the bulletin; the patched region is present (5/5 lines) at android-security-16.0.0_r8.",
      "17": "not affected per the bulletin; the patched region is present (5/5 lines) at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Single 3-line insertion. The only dependencies are PackageSetting.isSystem()/isUpdatedSystemApp() and the local `instantApp` boolean already present in the method. If backporting from the r29 tree, drop the isPackageDeviceAdmin/isProtectedPackage terms unless those locals exist in the target."
     ],
     "confidence": "high",
     "unknowns": [
      "The enclosing method signature is not shown in the context. The method is identified only by its \"installExistingPackage for user\" cross-user permission label.",
      "The concrete security impact of a system app being marked instant for a user is not described in the material beyond the commit title and the bulletin's EoP/High rating.",
      "The bulletin lists 12, 12L and 13 as affected, but the material does not include the fixes or the code location for those branches.",
      "The later commit that added isPackageDeviceAdmin/isProtectedPackage to the condition is not identified in the material.",
      "Whether the extended condition is present on 15, 16 and 17 is not shown; only the 5/5 line presence of the patched region is reported."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 2,
      "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-0047": {
     "cve": "CVE-2024-0047",
     "summary": "Three frameworks/base commits make UserManagerService persist device policy global and local user restrictions under distinct XML tags, read the pre-userVersion-10 local restriction format correctly on upgrade, and force DevicePolicyEngine to re-sync global and per-user restriction state into UserManager whenever a DPC sets or clears a user restriction.",
     "component": "platform/frameworks/base, UserManagerService (services/core pm) and DevicePolicyEngine (services/devicepolicy)",
     "weakness": "Logic error in state persistence: the same XML tag (TAG_DEVICE_POLICY_RESTRICTIONS) was written for both global and local device policy restrictions, so they were misclassified on read-back; plus a missing format-version check when reading pre-v10 local restrictions",
     "root_cause": "In UserManagerService.writeUserLP, both mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL) (global) and getRestrictions(userInfo.id) (local) were serialized under TAG_DEVICE_POLICY_RESTRICTIONS. readUserLP parses that tag as legacyLocalRestrictions rather than as globalRestrictions/localRestrictions. The commit message of f51673939874 states that on certain Android 14 builds global restrictions set by the DPC can go into UserManager's local restriction store, a state where they \"cannot be unset in future\". Separately, when upgrading from userVersion 9 (Android 13), readUserLP parsed TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS with UserRestrictionsUtils.readRestrictions, but the v9 format stores local restrictions as restrictions_user sub tags grouped by source user id, so they were misread (commit message: read as base restrictions).",
     "fix_analysis": [
      "Commit 3cd8a2c783fc, services/core/java/com/android/server/pm/UserManagerService.java:writeUserLP: writes the USER_ALL restrictions with TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS and the per-user restrictions with TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS, matching the tags readUserLP parses into globalRestrictions and localRestrictions. setUserRestrictionInner is made package-visible with @VisibleForTesting; a new test testWriteReadDevicePolicyUserRestrictions in UserManagerServiceUserInfoTest round-trips a global and a local restriction.",
      "Commit bd5cc7f03256, UserManagerService.java:readUserLP(int id, int userVersion) and readUserLP(int id, InputStream is, int userVersion): the caller in the user list reader passes mUserVersion. When userVersion < 10 and the tag is TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS, the block is parsed with RestrictionsSet.readRestrictions(parser, TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS) and flattened with mergeAll(); otherwise the flat UserRestrictionsUtils.readRestrictions(parser) path is kept. A v9 fixture user_100_v9.xml and test testUserRestrictionsUpgradeFromV9 assert the restrictions land as user restrictions, not base restrictions.",
      "Commit f51673939874, services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java: adds maybeForceEnforcementRefreshLocked, shouldForceEnforcementRefresh (true only when the PolicyKey is a UserRestrictionPolicyKey) and forceEnforcementRefreshLocked, which under a cleared calling identity reads the resolved global PolicyState and calls enforcePolicy(definition, value, USER_ALL), then for every user from mUserManager.getUsers() reads the resolved local PolicyState and calls enforcePolicy for that user (defaulting to BooleanPolicyValue(false) when the policy has no state at that scope). It is invoked in four places: the local and global policy set paths (when !skipEnforcePolicy) and the local and global policy removal paths, so both UserManager restriction scopes are overwritten from policy engine state on each DPC set/clear. All throwables are caught and logged."
     ],
     "completeness": [
      "The writer fix covers both restriction scopes written by writeUserLP; readUserLP already distinguished the global, local and legacy tags, so new files round-trip correctly.",
      "The upgrade fix is gated on userVersion < 10 and only changes parsing of TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS; TAG_DEVICE_POLICY_RESTRICTIONS continues to be read as legacyLocalRestrictions. The material does not show how legacyLocalRestrictions is applied, so how files already written with the wrong tag are handled on read is not shown.",
      "The DevicePolicyEngine resync repairs UserManager state only for the specific user restriction policy being set or cleared and only when a DPC touches it through the set/remove paths (set paths skipped when skipEnforcePolicy is true); restrictions that are never set or cleared again are not resynced by this code.",
      "The resync iterates mUserManager.getUsers(); whether this covers every user whose file may hold stale state is not shown in the material."
     ],
     "behavior_changes": [
      "Per-user files now store device policy restrictions under TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS and TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS instead of two TAG_DEVICE_POLICY_RESTRICTIONS elements.",
      "readUserLP gained a userVersion parameter (internal and @VisibleForTesting signatures changed).",
      "Every DPC set or clear of a user restriction now triggers enforcePolicy for USER_ALL and for each user returned by mUserManager.getUsers(), with the calling identity cleared; failures are logged at error level and swallowed."
     ],
     "preconditions": [
      "A device owner or profile owner sets global and/or local user restrictions through DevicePolicyEngine, which UserManagerService persists via writeUserLP and reloads via readUserLP.",
      "For the upgrade path: the device's user list has userVersion < 10 (Android 13 format) with device_policy_local_restrictions present when the Android 14 code reads it."
     ],
     "per_major": {
      "14": "same fix: three cherry-picked commits (3cd8a2c783fc, bd5cc7f03256, f51673939874) in android-security-14.0.0_r6; at android-security-14.0.0_r29 6/8 lines of the patched region are present",
      "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 6/8 lines of the patched region are present",
      "17": "not affected per the bulletin; at android-security-17.0.0_r1 6/8 lines of the patched region are present"
     },
     "backport_notes": [
      "Apply in order 3cd8a2c783fc (writer tags, also adds the test helper setUserRestrictions), then bd5cc7f03256 (depends on the prior test and on RestrictionsSet.readRestrictions/mergeAll and mUserVersion being available), then f51673939874 (DevicePolicyEngine, separate file; requires UserRestrictionPolicyKey, BooleanPolicyValue and the policy engine). No fork comparison was provided in the material."
     ],
     "confidence": "medium",
     "unknowns": [
      "The exact DoS consequence of restrictions becoming unclearable is not described beyond the bulletin type and the commit message.",
      "How legacyLocalRestrictions (TAG_DEVICE_POLICY_RESTRICTIONS) is applied later in readUserLP, and therefore the full effect of files written by unpatched builds, is not shown.",
      "The names of the DevicePolicyEngine methods into which maybeForceEnforcementRefreshLocked was inserted are not shown in the diff hunks.",
      "Which commit the per-major '6/8 lines present' metric refers to, and why two lines differ at the latest tags."
     ],
     "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."
     }
    },
    "CVE-2024-0048": {
     "cve": "CVE-2024-0048",
     "summary": "Schedules a 15 minute MESSAGE_TIMED_OUT message for every AccountManagerService.Session at construction, so that a session still open at timeout runs onTimedOut(), which calls getResponseAndClose() and reports an error to the caller.",
     "component": "platform/frameworks/base, services/core accounts (AccountManagerService, system_server)",
     "weakness": "Missing timeout / unbounded lifetime of per-request Session objects (resource lifecycle issue); the bulletin classifies the impact as EoP",
     "root_cause": "The Session constructor registers each session in mSessions (mSessions.put(toString(), this)) and links to the response binder's death. AccountManagerService already had MESSAGE_TIMED_OUT, Session.cancelTimeout() and Session.onTimedOut(), but the constructor did not schedule a timeout. As a result, a session that did not complete had no time bound set at creation.",
     "fix_analysis": [
      "services/core/java/com/android/server/accounts/AccountManagerService.java: adds the constant TIMEOUT_DELAY_MS = 1000 * 60 * 15 (15 minutes) next to the MESSAGE_TIMED_OUT definition.",
      "AccountManagerService.Session constructor: calls the new scheduleTimeout() after mSessions.put(toString(), this) and before linkToDeath on the response.",
      "AccountManagerService.Session.scheduleTimeout (new): sends mHandler.obtainMessage(MESSAGE_TIMED_OUT, this) with sendMessageDelayed(..., TIMEOUT_DELAY_MS). The existing cancelTimeout() removes these messages with removeMessages(MESSAGE_TIMED_OUT, this).",
      "AccountManagerService.Session.onTimedOut (existing): calls getResponseAndClose() and reports AccountManager.ERROR_CODE_REMOTE_EXCEPTION to the response. The fix only adds a verbose log line here."
     ],
     "completeness": [
      "Every Session object gets the timeout, because it is scheduled in the Session constructor.",
      "It only bounds how long a session lives. It does not limit how many sessions one caller can have outstanding within the 15 minute window.",
      "The actual cleanup depends on the existing onTimedOut/getResponseAndClose path, which the diff does not change. The material does not show that path's body or where cancelTimeout() is called on normal completion.",
      "The timeout is a hard-coded constant and cannot be configured."
     ],
     "behavior_changes": [
      "An AccountManager session still open after 15 minutes is closed through Session.onTimedOut, and the client response receives onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, ...).",
      "Authenticators that take longer than 15 minutes to answer will hit this timeout.",
      "New verbose log line 'Session.onTimedOut' under TAG when verbose logging is enabled.",
      "One additional delayed message per session is queued on mHandler."
     ],
     "preconditions": [
      "A client must cause AccountManagerService to create a Session. The Session constructor is the patched point.",
      "The session must not complete, so that it stays registered in mSessions."
     ],
     "per_major": {
      "14": "same fix: commit 813900c458e9 (Merged-In Ib4cebf1750fc6324dc1c8853e0d716ea5e8ec073) in android-security-14.0.0_r6; all 8/8 patched lines are present at android-security-14.0.0_r29.",
      "15": "not affected (not listed by the bulletin); android-security-15.0.0_r17 contains the patched code (8/8 lines).",
      "16": "not affected (not listed by the bulletin); android-security-16.0.0_r8 contains the patched code (8/8 lines).",
      "17": "not affected (not listed by the bulletin); android-security-17.0.0_r1 contains the patched code (8/8 lines)."
     },
     "backport_notes": [
      "Single commit adding 10 lines to one file. It uses the existing MESSAGE_TIMED_OUT, mHandler, cancelTimeout and onTimedOut. The constant block around the insertion point differs between tags (r29 has MAXIMUM_PASSWORD_LENGTH and STORAGE_LIMIT_PER_USER next to it), so the hunk context may need manual adjustment. Check on each branch that MessageHandler routes MESSAGE_TIMED_OUT to Session.onTimedOut."
     ],
     "confidence": "medium",
     "unknowns": [
      "The concrete trigger, and why Google rates the impact as EoP, are not in the material (bugs 303905130 and 316893159 are not included).",
      "Where cancelTimeout() is called on normal completion, the body of getResponseAndClose(), and how MessageHandler dispatches MESSAGE_TIMED_OUT are not in the material.",
      "Fix commits and status for Android 12, 12L and 13 (listed as affected by the bulletin) are not in the material.",
      "Whether anything scheduled MESSAGE_TIMED_OUT for sessions before this fix is not shown."
     ],
     "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."
     }
    },
    "CVE-2024-0049": {
     "cve": "CVE-2024-0049",
     "summary": "Adds isValidOMXParam() validation at the start of the six VP8/VP9/Android-VPx OMX get/set parameter handlers in the libstagefright software VPx encoders. When the caller-supplied parameter struct fails validation, they now return OMX_ErrorBadParameter and log a SafetyNet event.",
     "component": "platform/frameworks/av, media/libstagefright software VPx OMX encoders (SoftVP8Encoder, SoftVP9Encoder, SoftVPXEncoder)",
     "weakness": "Missing validation of a caller-supplied OMX parameter struct before its fields are accessed. This likely allows out-of-bounds read/write when the struct is undersized.",
     "root_cause": "SoftVP8Encoder::internalGetParameter/internalSetParameter and SoftVP9Encoder::internalGetParameter/internalSetParameter cast the raw OMX_PTR param to OMX_VIDEO_PARAM_VP8TYPE or OMX_VIDEO_PARAM_VP9TYPE. The handlers that receive the cast struct (internalGetVp8Params, internalSetVp8Params, internalGetVp9Params, internalSetVp9Params, and also internalGetAndroidVpxParams and internalSetAndroidVpxParams, which take OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE) immediately read nPortIndex. They then read or write type-specific fields (eProfile, eLevel, nDCTPartitions, nTileColumns, nKeyFrameInterval, a memcpy into nTemporalLayerBitrateRatio, etc.) without first validating the struct with isValidOMXParam(). A parameter buffer that does not match the expected struct can therefore be accessed beyond its bounds.",
     "fix_analysis": [
      "media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp: SoftVP8Encoder::internalGetVp8Params and SoftVP8Encoder::internalSetVp8Params now call isValidOMXParam(vp8Params) before any field access. On failure they log android_errorWriteLog(0x534e4554, \"273936274\" / \"273937171\") and return OMX_ErrorBadParameter.",
      "media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp: SoftVP9Encoder::internalGetVp9Params and SoftVP9Encoder::internalSetVp9Params get the same isValidOMXParam(vp9Params) guard, with bug tags 273936553 / 273937136.",
      "media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp: SoftVPXEncoder::internalGetAndroidVpxParams and SoftVPXEncoder::internalSetAndroidVpxParams get the isValidOMXParam(vpxAndroidParams) guard, with bug tags 273936601 / 273937551. It sits before the nPortIndex check and before the memcpy into nTemporalLayerBitrateRatio.",
      "The fix is a single commit (29 added lines, no deletions). The validation lives inside the type-specific handlers rather than in the internalGetParameter/internalSetParameter switch, so every dispatch path into these handlers is covered."
     ],
     "completeness": [
      "Covers all six type-specific handlers, in both get and set directions: OMX_IndexParamVideoVp8, OMX_IndexParamVideoVp9 and the Android VPx encoder parameters, across the VP8, VP9 and shared VPX encoder classes.",
      "The fix guards only these VPx-specific handlers. In the shown context, SoftVPXEncoder::internalSetBitrateParams (and the tail of the matching get handler) dereferences bitrate->nPortIndex and other fields, and no isValidOMXParam call is visible in that function. The material does not show whether the SoftVPXEncoder::internalGetParameter/internalSetParameter dispatcher validates the struct.",
      "The bug tag 273937551 used in internalSetAndroidVpxParams is not among the Bug: lines of the commit message. This is cosmetic and does not affect the check."
     ],
     "behavior_changes": [
      "OMX getParameter/setParameter calls to the software VP8/VP9 encoders now return OMX_ErrorBadParameter, instead of being processed, when a VPx-type parameter struct fails isValidOMXParam.",
      "Each rejected call emits a SafetyNet log event (android_errorWriteLog with tag 0x534e4554 and the per-handler bug id).",
      "No change for well-formed parameter structs."
     ],
     "preconditions": [
      "The caller can issue OMX getParameter or setParameter against a software VPx encoder component (SoftVP8Encoder or SoftVP9Encoder, which derive from SoftVPXEncoder) with index OMX_IndexParamVideoVp8 or OMX_IndexParamVideoVp9, or with the parameters handled by the Android VPx handlers. The VP8/VP9 dispatch is shown in the context. The dispatch to the Android VPx handlers in SoftVPXEncoder is not shown.",
      "The supplied parameter struct is not a correctly sized OMX_VIDEO_PARAM_VP8TYPE / OMX_VIDEO_PARAM_VP9TYPE / OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE.",
      "These software OMX components run in the media codec process and are reachable through the OMX/IOMX service interface (general platform knowledge)."
     ],
     "per_major": {
      "14": "same fix: commit 6a4f0a82bbf3 landed in android-security-14.0.0_r6 (linked by bug id). At android-security-14.0.0_r29 all 8/8 patched lines are present.",
      "15": "not affected: the bulletin does not list Android 15. The patched region is present (8/8 lines at android-security-15.0.0_r17).",
      "16": "not affected: the bulletin does not list Android 16. SoftVP8Encoder.cpp, SoftVP9Encoder.cpp and SoftVPXEncoder.cpp are absent at android-security-16.0.0_r8.",
      "17": "not affected: the bulletin does not list Android 17. The three patched files are absent at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Single self-contained commit. It only depends on isValidOMXParam() and android_errorWriteLog already being available to these files (both are used elsewhere in libstagefright OMX components, general platform knowledge). Insert the guard as the first statement of each of the six handlers, before the nPortIndex check. The bulletin lists 12, 12L and 13 as affected, so the same change applies there if the files are present."
     ],
     "confidence": "high",
     "unknowns": [
      "The material does not include the definition of isValidOMXParam. Its semantics (an nSize check against sizeof the parameter type) are inferred from general platform knowledge.",
      "The material does not show whether SoftVPXEncoder::internalGetParameter/internalSetParameter already validate other parameter types (e.g. OMX_VIDEO_PARAM_BITRATETYPE) before dispatch, or how it dispatches to the Android VPx handlers.",
      "The POCs referenced in the commit message are not provided.",
      "Which process hosts these components on a given device is not shown in the material."
     ],
     "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."
     }
    },
    "CVE-2024-0050": {
     "cve": "CVE-2024-0050",
     "summary": "Adds isValidOMXParam() validation of the client-supplied DescribeHDR10PlusInfoParams structure in SoftVideoDecoderOMXComponent::getConfig and SoftVideoDecoderOMXComponent::internalSetConfig before the structure is used.",
     "component": "platform/frameworks/av, libstagefright OMX software video decoder base class (media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp)",
     "weakness": "Missing input validation / missing size (bounds) check on an OMX parameter structure",
     "root_cause": "In SoftVideoDecoderOMXComponent.cpp, the kDescribeHdr10PlusInfoIndex handlers in getConfig() and internalSetConfig() cast the caller-supplied OMX_PTR params directly to DescribeHDR10PlusInfoParams. They then used it without the isValidOMXParam() check that sibling cases perform (e.g. DescribeHDRStaticInfoParams in getConfig, lines 589-594 at r29). getConfig() then wrote outParams->nParamSizeUsed and memcpy'd info->data() into outParams->nValue, based on outParams->nParamSize. internalSetConfig() went on to its frameConfig / HDR10+ handling. In neither case was the structure's declared size checked.",
     "fix_analysis": [
      "media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp:SoftVideoDecoderOMXComponent::getConfig, case kDescribeHdr10PlusInfoIndex: after params is cast to DescribeHDR10PlusInfoParams* outParams, adds `if (!isValidOMXParam(outParams)) return OMX_ErrorBadParameter;`. The check runs before nParamSizeUsed is written and before the memcpy into nValue. It sits inside the existing supportDescribeHdr10PlusInfo() guard and the mHdr10PlusOutputs.size() > 0 branch.",
      "media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp:SoftVideoDecoderOMXComponent::internalSetConfig, case kDescribeHdr10PlusInfoIndex: after params is cast to const DescribeHDR10PlusInfoParams* inParams, adds the same isValidOMXParam(inParams) check returning OMX_ErrorBadParameter. The check runs before the `if (*frameConfig)` append logic.",
      "Single commit, 8 added lines, no other logic changed."
     ],
     "completeness": [
      "Covers both the get and set paths for kDescribeHdr10PlusInfoIndex in the shared software decoder base class. This matches the isValidOMXParam pattern already used by other cases in getConfig (e.g. DescribeHDRStaticInfoParams).",
      "The fix validates only the structure header via isValidOMXParam. It does not check that outParams->nParamSize fits within outParams->nSize, so the variable-length memcpy into nValue is still bounded by the client-declared nParamSize. The code at android-security-14.0.0_r29 contains a later, separate check (`offsetof(DescribeHDR10PlusInfoParams, nValue) + outParams->nParamSize > outParams->nSize`, logged as b/329641908) that closes this gap. That check is not part of this CVE's commit.",
      "Only SoftVideoDecoderOMXComponent.cpp is touched. Derived or vendor components that reimplement getConfig/internalSetConfig are not covered by this commit."
     ],
     "behavior_changes": [
      "getConfig(kDescribeHdr10PlusInfoIndex) returns OMX_ErrorBadParameter when the supplied DescribeHDR10PlusInfoParams fails isValidOMXParam(). This applies only when HDR10+ support is enabled and HDR10+ outputs are pending.",
      "setConfig (via internalSetConfig) with kDescribeHdr10PlusInfoIndex returns OMX_ErrorBadParameter when the structure fails isValidOMXParam().",
      "No change for well-formed parameters."
     ],
     "preconditions": [
      "A caller able to issue OMX getConfig/setConfig with kDescribeHdr10PlusInfoIndex against a software video decoder derived from SoftVideoDecoderOMXComponent. For getConfig, supportDescribeHdr10PlusInfo() must also return true.",
      "For getConfig, mHdr10PlusOutputs must be non-empty. Otherwise OMX_ErrorUnderflow is returned before the patched code is reached.",
      "internalSetConfig is reached from SimpleSoftOMXComponent::setConfig in frameworks/av/media/libstagefright/omx/SimpleSoftOMXComponent.cpp (per index search)."
     ],
     "per_major": {
      "14": "same fix: commit 23a035af9be9 in android-security-14.0.0_r6 (cherry-pick of a542f2c50700, Change-Id I707745594a9196d8d85d4c4bb498eba3c6198b42). All 8 patched lines are present at android-security-14.0.0_r29, along with a later, additional nParamSize-vs-nSize check (b/329641908) in getConfig.",
      "15": "not affected per the bulletin; the 8 patched lines are present at android-security-15.0.0_r17.",
      "16": "not affected per the bulletin; the 8 patched lines are present at android-security-16.0.0_r8.",
      "17": "not affected per the bulletin; the 8 patched lines are present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Self-contained 8-line change that relies only on the isValidOMXParam() template already used elsewhere in the same file. Apply it inside the kDescribeHdr10PlusInfoIndex cases, immediately after the DescribeHDR10PlusInfoParams casts. Consider also carrying the later b/329641908 nParamSize-vs-nSize check visible at android-security-14.0.0_r29."
     ],
     "confidence": "high",
     "unknowns": [
      "The material does not show the concrete memory-safety consequence or the trigger used in the bug reports (273935108, 281065553).",
      "The material does not show whether the Android 12/12L/13 branches listed as affected received the same commit.",
      "The guards preceding the kDescribeHdr10PlusInfoIndex case in internalSetConfig and the fields it reads after the check are not shown.",
      "Whether vendor or emulator derivatives (e.g. device/generic/goldfish-opengl GoldfishVideoDecoderOMXComponent.cpp) implement the kDescribeHdr10PlusInfoIndex case is 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-0051": {
     "cve": "CVE-2024-0051",
     "summary": "Adds an end-of-list check to the outQueue search loop in SoftMPEG4::onQueueFilled. If the current output header is not found, the decoder now returns instead of walking past the end of the output buffer list.",
     "component": "platform/frameworks/av, libstagefright software OMX MPEG4/H.263 decoder (media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp)",
     "weakness": "Missing bounds / end-of-container check on a list iterator (out of bounds read and write)",
     "root_cause": "In SoftMPEG4::onQueueFilled, after a frame is decoded, the code searches outQueue (List<BufferInfo *>) for the BufferInfo whose mHeader equals outHeader, using `while ((*it)->mHeader != outHeader) ++it;`. The loop had no `it != outQueue.end()` guard. If outHeader was not in outQueue, the iterator moved past the end and was dereferenced. The code then used the resulting pointer as a BufferInfo: it wrote `outInfo->mOwnedByUs = false` and called `outQueue.erase(it)`. The commit message calls this an out of bounds read and write.",
     "fix_analysis": [
      "media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp:SoftMPEG4::onQueueFilled: the loop condition becomes `it != outQueue.end() && (*it)->mHeader != outHeader`, so the iterator is never dereferenced at end().",
      "Same function: `if (it == outQueue.end()) return;` is added after the loop. When the header is not found, the function now returns early. It no longer dereferences `*it`, writes mOwnedByUs, erases from outQueue or calls notifyFillBufferDone."
     ],
     "completeness": [
      "The fix covers the one unguarded search loop in SoftMPEG4::onQueueFilled. It is a defensive check. It does not change the upstream condition that leaves outHeader missing from outQueue, and the material does not show that condition.",
      "On the not-found path, the function returns after the input buffer has already been consumed (inQueue.erase / notifyEmptyBufferDone). By then, the outHeader fields (nTimeStamp, nFlags, nOffset, nFilledLen) have also been written. The fix does not undo these side effects or signal an error.",
      "Per index search, the other SoftOMX decoders shown (SoftFlacDecoder, SoftMP3, SoftVorbis, SoftVPX) take `*outQueue.begin()` directly instead of searching the list. The same loop pattern does not appear elsewhere in the material."
     ],
     "behavior_changes": [
      "When the current output header is not in outQueue, onQueueFilled now returns silently: no notifyFillBufferDone for that frame, no error event, and mNumSamplesOutput is not incremented.",
      "No change in behavior when the header is present in outQueue."
     ],
     "preconditions": [
      "The software OMX MPEG4/H.263 decoder (SoftMPEG4) must be in use and processing input through onQueueFilled.",
      "The output header chosen for the decoded frame must be missing from outQueue at lookup time. The material does not show which sequence of port/buffer operations causes this; the commit message only refers to a POC in the bug.",
      "Bulletin severity: High, type EoP. The material gives no further detail on reachability."
     ],
     "per_major": {
      "14": "same fix: commit 3bedd18fd3f4 in android-security-14.0.0_r6 (Change-Id Ic230d10048193a785f185dc6a7de6f455f9318c1). At android-security-14.0.0_r29, 3/4 lines of the patched region are present.",
      "15": "not affected (not listed by the bulletin). At android-security-15.0.0_r17, 3/4 lines of the patched region are present, so the fixed code is in 15.",
      "16": "not affected / code absent: media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp does not exist at android-security-16.0.0_r8.",
      "17": "not affected / code absent: the patched file does not exist at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "A single, self-contained commit that changes one loop in SoftMPEG4::onQueueFilled. The bulletin also lists 12, 12L and 13 as affected. The added `++it;` line has one extra leading space compared with the surrounding code; keep this in mind when doing line-based presence checks."
     ],
     "confidence": "high",
     "unknowns": [
      "How outHeader is chosen earlier in onQueueFilled, and the exact condition under which it is missing from outQueue (the start of the function is not in the material).",
      "Why only 3 of 4 patched-region lines are reported present at the 14 and 15 tags.",
      "Whether SoftMPEG4.cpp was removed in Android 16 as part of a broader removal of OMX software codecs or for another reason (the material only shows the file is absent).",
      "Details of the POC, and the concrete memory impact beyond the 'out of bounds read and write' stated in the commit message."
     ],
     "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-0052": {
     "cve": "CVE-2024-0052",
     "summary": "Makes the Health Connect change-log read path apply the same exercise-route access rules as the normal read path. ExerciseSessionRecord routes returned through getChangeLogs are now limited to the caller's own sessions unless the caller holds READ_EXERCISE_ROUTE.",
     "component": "platform/packages/modules/HealthFitness (Health Connect service), change logs / ExerciseSessionRecord route storage",
     "weakness": "Missing authorization check (ownership / extra permission) on a secondary data read path (information disclosure)",
     "root_cause": "HealthConnectServiceImpl.getChangeLogs read the upserted records through ReadTransactionRequest(Map<Integer, List<UUID>>, long startDateAccess). That constructor called RecordHelper.getReadTableRequest(uuids, startDateAccess), which called ExerciseSessionRecordHelper.getExtraDataReadRequests(uuids, startDateAccess). The override only checked isExerciseRouteFeatureEnabled() and built the route read request with a WHERE clause on UUID and start time. It never received the caller package name or the READ_EXERCISE_ROUTE grant state, so it did not restrict routes to sessions owned by the caller. The readRecords path (getExtraDataReadRequests(request, packageName, startDateAccess, extraPermsState)) already enforced self-read when READ_EXERCISE_ROUTE was not granted. As a result, change-log responses could include exercise routes written by other apps.",
     "fix_analysis": [
      "service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java:getChangeLogs: gets callerPackageName (Objects.requireNonNull(attributionSource.getPackageName())) and computes recordTypeToInsertedUuids first. It then calls mDataPermissionEnforcer.collectExtraReadPermissionToStateMapping(recordTypeToInsertedUuids.keySet(), attributionSource) to get the extra read permission grant state, and passes callerPackageName and that map into the new ReadTransactionRequest constructor.",
      "service/java/com/android/server/healthconnect/permission/DataPermissionEnforcer.java:collectExtraReadPermissionToStateMapping: the parameter changes from a single int recordTypeId to Set<Integer> recordTypeIds. The method collects the distinct extra read permissions of all involved record helpers and maps each one to isPermissionGranted(). The readRecords call site in HealthConnectServiceImpl is adapted to pass Set.of(request.getRecordType()).",
      "service/java/com/android/server/healthconnect/storage/request/ReadTransactionRequest.java: the UUID-map constructor now takes (String packageName, Map<Integer, List<UUID>> recordTypeToUuids, long startDateAccess, Map<String, Boolean> extraPermsState) and forwards packageName and extraPermsState to RecordHelper.getReadTableRequest.",
      "service/java/com/android/server/healthconnect/storage/datatypehelpers/RecordHelper.java: getReadTableRequest(packageName, uuids, startDateAccess, extraPermsState) and getExtraDataReadRequests(packageName, uuids, startDateAccess, extraPermsState) both gain the packageName and extraPermsState parameters. The base getExtraDataReadRequests still returns an empty list.",
      "service/java/com/android/server/healthconnect/storage/datatypehelpers/ExerciseSessionRecordHelper.java: adds getExerciseRouteReadAccessType(packageName, extraPermsState). It returns ROUTE_READ_ACCESS_TYPE_NONE when the feature is disabled, or when READ_EXERCISE_ROUTE is not granted and the package has no app-info id. It returns ROUTE_READ_ACCESS_TYPE_ALL when READ_EXERCISE_ROUTE is granted (looked up with getOrDefault(..., false)), and ROUTE_READ_ACCESS_TYPE_OWN otherwise. The change-log override getExtraDataReadRequests(packageName, uuids, ...) returns no route request for NONE. For OWN it adds addWhereInLongsClause(APP_INFO_ID_COLUMN_NAME, List.of(appId)), so only routes of sessions written by the caller are read. The readRecords override is refactored to use the same helper, with enforceSelfRead = (access type == OWN).",
      "service/java/com/android/server/healthconnect/storage/datatypehelpers/AppInfoHelper.java:getAppInfoId: returns DEFAULT_LONG for a null packageName, so a null package resolves to no route access.",
      "framework/java/android/health/connect/datatypes/ExerciseSessionRecord.java:toRecordInternal: now calls recordInternal.setHasRoute(hasRoute()), so the has_route flag is carried into the internal record whether or not the route object is present.",
      "Tests: ExerciseRouteAccessTest adds CTS cases for readRecords, using both filters and ids: own route, another app's route without and with READ_EXERCISE_ROUTE, and mixed sessions. For getChangeLogs it adds cases for the caller's own route and for another app's route with READ_EXERCISE_ROUTE. TestUtils adds READ_EXERCISE_ROUTE_PERMISSION and truncates the start time to millis. The RecentAccessViewModelTest and HealthConnectUiTestHelper changes are unrelated test adjustments bundled in the cherry-pick."
     ],
     "completeness": [
      "Covers the change-log read path for ExerciseSessionRecord routes, which previously had no ownership or READ_EXERCISE_ROUTE check. The readRecords path already enforced these rules and is only refactored to share getExerciseRouteReadAccessType.",
      "For the OWN case the route restriction is applied in SQL (APP_INFO_ID_COLUMN_NAME IN (callerAppId)). Other apps' sessions still appear in the change log, but without route data. The readRecords CTS tests assert that hasRoute stays true with a null route for other apps' sessions. No change-log test asserts this for the no-permission case.",
      "In the material, only ExerciseSessionRecordHelper overrides getExtraDataReadRequests. Other record types inherit the empty default, so no other extra-data path is changed.",
      "The READ_EXERCISE_ROUTE lookup now uses getOrDefault(READ_EXERCISE_ROUTE, false), so a missing key counts as not granted. Before the fix, the readRecords override unboxed extraPermsState.get() directly.",
      "When isExerciseRouteFeatureEnabled() is false, neither path returns a route (unchanged behavior)."
     ],
     "behavior_changes": [
      "getChangeLogs responses no longer include ExerciseRoute data for sessions written by other apps unless the caller holds android.permission.health.READ_EXERCISE_ROUTE. The caller's own routes are still returned.",
      "getChangeLogs now calls Objects.requireNonNull on the AttributionSource package name before scheduling work.",
      "DataPermissionEnforcer.collectExtraReadPermissionToStateMapping takes a Set<Integer> of record types and can evaluate permissions for several record types in one call.",
      "AppInfoHelper.getAppInfoId(null) returns DEFAULT_LONG.",
      "ExerciseSessionRecord.toRecordInternal propagates hasRoute() into the internal record."
     ],
     "preconditions": [
      "The caller is an app with Health Connect read access to ExerciseSessionRecord that uses the change-log API (a ChangeLogTokenRequest for ExerciseSessionRecord, then getChangeLogs).",
      "Another app has written an ExerciseSessionRecord with an ExerciseRoute after the change-log token was issued.",
      "isExerciseRouteFeatureEnabled() returns true in ExerciseSessionRecordHelper.",
      "The caller does not hold the READ_EXERCISE_ROUTE signature permission (holders may read all routes by design)."
     ],
     "per_major": {
      "14": "Same fix: commit 178f4824574f in android-security-14.0.0_r6, a cherry-pick of 69c320af3eff (Change-Id I5ab3835a2ff451ef4ed18863858bb86af6a455c8). At android-security-14.0.0_r29 the patched region is fully present (8/8 lines).",
      "15": "Not affected per the bulletin. At android-security-15.0.0_r17, 6/8 lines of the patched region are present. The material does not show the differences.",
      "16": "Not affected per the bulletin. At android-security-16.0.0_r8, 6/8 lines of the patched region are present. The material does not show the differences.",
      "17": "Not affected per the bulletin. At android-security-17.0.0_r1, 6/8 lines of the patched region are present. The material does not show the differences."
     },
     "backport_notes": [
      "The fix changes method signatures in RecordHelper.getReadTableRequest / getExtraDataReadRequests, ReadTransactionRequest and DataPermissionEnforcer.collectExtraReadPermissionToStateMapping. Any downstream RecordHelper subclass that overrides the UUID-based getExtraDataReadRequests must be updated to the new 4-argument form. Both HealthConnectServiceImpl call sites (readRecords and getChangeLogs) must be adapted together. HealthFitness ships as a mainline module, so the service code is normally updated through the module rather than the platform image (general platform knowledge).",
      "The RecentAccessViewModelTest.kt and HealthConnectUiTestHelper.kt hunks are unrelated test adjustments and can be dropped if they do not apply."
     ],
     "confidence": "high",
     "unknowns": [
      "The material does not show whether isExerciseRouteFeatureEnabled() is enabled by default on affected builds.",
      "The material does not show the code in the Android 15/16/17 branches (6/8 patched lines present) or which two lines differ.",
      "The material does not say whether the ExerciseSessionRecord.toRecordInternal setHasRoute change is needed for the security behavior or only for test correctness.",
      "No CTS test in the material checks change-log behavior for another app's route when the caller lacks READ_EXERCISE_ROUTE."
     ],
     "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-0053": {
     "cve": "CVE-2024-0053",
     "summary": "PrintManagerService.getCustomPrinterIcon now checks URI-based custom printer icons returned by a print service and returns null for any icon whose URI encodes a user id whose profile parent is not getCurrentUserId().",
     "component": "platform/frameworks/base, print service (services/print, PrintManagerService)",
     "weakness": "Missing user-boundary validation of a user-scoped content URI supplied by a third-party print service (information disclosure across users)",
     "root_cause": "PrintManagerImpl.getCustomPrinterIcon returned userState.getCustomPrinterIcon(printerId) unmodified, inside a clearCallingIdentity block. Per the commit message, a third-party print plugin service can pass another user's User Icon URI. Because Settings holds INTERACT_ACROSS_USERS_FULL, this enables an exploit across the user boundary. For Icon.TYPE_URI and TYPE_URI_ADAPTIVE_BITMAP, the URI's encoded user info was not checked against the caller or the current profile group.",
     "fix_analysis": [
      "services/print/java/com/android/server/print/PrintManagerService.java: PrintManagerImpl.getCustomPrinterIcon now stores the Icon from userState.getCustomPrinterIcon(printerId) and returns validateIconUserBoundary(icon). This is still inside the Binder.clearCallingIdentity/restoreCallingIdentity block.",
      "New private method PrintManagerImpl.validateIconUserBoundary(Icon): if the icon is non-null and of type Icon.TYPE_URI or Icon.TYPE_URI_ADAPTIVE_BITMAP, it reads icon.getUri().getEncodedUserInfo(). If that is null, the URI is treated as calling into the calling user's space and the icon is returned unchanged.",
      "If an encoded user is present, it is parsed with Integer.parseInt and passed through resolveCallingUserEnforcingPermissions(userId). Then, under mLock, resolveCallingProfileParentLocked(resolvedUserId) is compared to getCurrentUserId(). On mismatch the method returns null; otherwise it returns the original icon.",
      "Icons of other types are returned unchanged."
     ],
     "completeness": [
      "Only the getCustomPrinterIcon return path is validated. The icon stored in UserState is not sanitized when the print service reports it.",
      "Only the user-info component of the URI is checked; the authority and path are not restricted. The commit calls this a lightweight solution.",
      "Integer.parseInt(encodedUser) is not guarded, so non-numeric user info would throw NumberFormatException instead of being rejected.",
      "The check compares the profile parent of the URI's resolved user against getCurrentUserId(), not strictly against the calling user."
     ],
     "behavior_changes": [
      "getCustomPrinterIcon returns null for URI-type icons whose encoded user's profile parent differs from getCurrentUserId(), so those printers show no custom icon.",
      "Non-integer user info in an icon URI makes the Binder call throw instead of returning the icon.",
      "resolveCallingUserEnforcingPermissions is now called on the URI-encoded user id, after clearCallingIdentity. Its effect in that context is not shown."
     ],
     "preconditions": [
      "An installed, enabled third-party print service reports a custom printer icon of type TYPE_URI or TYPE_URI_ADAPTIVE_BITMAP whose URI encodes another user's id.",
      "getCustomPrinterIcon is called and the returned URI is resolved by a component holding cross-user permission. The commit message names Settings as holding INTERACT_ACROSS_USERS_FULL.",
      "Another user exists on the device whose content is addressable through such a URI."
     ],
     "per_major": {
      "14": "same fix: commit bf68f31ff7fa in android-security-14.0.0_r6 (cherry-pick of c58f2b7b262eee49130f47d72247615f07af4a81). At android-security-14.0.0_r29, 4/5 lines of the patched region are present.",
      "15": "not affected (not listed by the bulletin). 4/5 lines of the patched region are present at android-security-15.0.0_r17.",
      "16": "not affected (not listed by the bulletin). 4/5 lines of the patched region are present at android-security-16.0.0_r8.",
      "17": "not affected (not listed by the bulletin). 4/5 lines of the patched region are present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "The change is confined to PrintManagerImpl in one file. It uses existing helpers in the same class (resolveCallingUserEnforcingPermissions, resolveCallingProfileParentLocked, getCurrentUserId) and the mLock field.",
      "Only 4/5 lines of the patched region match on every latest security tag. Before applying, check how the region differs and that the helpers exist with the same signatures."
     ],
     "confidence": "medium",
     "unknowns": [
      "Which line of the patched region differs on the latest security tags (14 r29, 15 r17, 16 r8, 17 r1) is not shown.",
      "The bodies of resolveCallingUserEnforcingPermissions, resolveCallingProfileParentLocked and getCurrentUserId are not in the material. So it cannot be determined whether the first can throw for the URI-encoded user id after clearCallingIdentity.",
      "How UserState.getCustomPrinterIcon obtains and caches the icon from the print service is not shown.",
      "Which component consumes and loads the returned icon URI is not shown beyond the commit message's mention of Settings."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 8,
      "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-03-01",
  "latest_version": "1.1",
  "latest_revision": {
   "version": "1.1",
   "date": "July 29, 2024",
   "notes": "Updated CVE tables."
  },
  "revisions": [
   {
    "version": "1.0",
    "date": "March 4, 2024",
    "notes": "Bulletin Published."
   },
   {
    "version": "1.1",
    "date": "July 29, 2024",
    "notes": "Updated CVE tables."
   }
  ],
  "tracked_since": "2026-09-30",
  "changes_since_tracking": [],
  "out_of_scope_rows": {
   "Arm components": 2,
   "MediaTek components": 9,
   "Qualcomm closed-source components": 7,
   "Qualcomm components": 5
  },
  "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."
 }
}