{
 "month": "2024-10",
 "generated": "2026-10-06T12:05+00:00",
 "majors": {
  "14": {
   "counts": {
    "announced": 7,
    "certain": 7,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [
    {
     "cve": "CVE-2024-0044",
     "osv_id": "ASB-A-307532206",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "PackageInstallerService session creation now rejects (nulls out) app and installer package names that are over-long or contain characters not accepted by FrameworkParsingPackageUtils.validateName, instead of only checking their length.",
      "confidence": "high",
      "backport_notes": [
       "Apply 954b2874b85b before 836750619a8b: the second commit depends on the isValidPackageName helper and the FrameworkParsingPackageUtils import introduced by the first, and its hunk context (the 'Validate requested installer package name' block) comes from the first.",
       "The helper relies on android.content.pm.parsing.FrameworkParsingPackageUtils.validateName(String, boolean, boolean); confirm that class and signature exist on the target branch before porting."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 4,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r6",
      "date": "2024-03-04",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "954b2874b85b6cd0d6bb12cd677cdf22e5dbd77b",
       "tag": "android-security-14.0.0_r6",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      },
      {
       "project": "platform/frameworks/base",
       "sha": "836750619a8bce0bf78fe0549f9990e294671563",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 2,
     "first_commit_before_announcement_days": 211,
     "multi_tag_fix": true,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-40672",
     "osv_id": "ASB-A-327645387",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "ChooserActivity.onCreate in the IntentResolver module now reads Settings.Global.SECURE_FRP_MODE and, when it is 1, logs, calls super.onCreate and immediately finishes, so the share sheet cannot be launched while Factory Reset Protection enforcement is active.",
      "confidence": "high",
      "backport_notes": [
       "Self-contained 7-line change at the top of ChooserActivity.onCreate plus one import. It depends on the Settings.Global.SECURE_FRP_MODE constant.",
       "No 'Fix in fork' comparison was provided, so no per-file fork verdict can be given."
      ],
      "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_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/IntentResolver",
       "sha": "ccd29124d0d2276a3071c0418c14dec188cd3727",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/IntentResolver"
     ]
    },
    {
     "cve": "CVE-2024-40673",
     "osv_id": "ASB-A-309938635",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "RCE"
     ],
     "status": "resolved",
     "brief": {
      "summary": "libcore's native ZipFile open path (ZIP_Put_In_Cache0 in ojluni/src/main/native/zip_util.c) now rejects any zip file whose first 4 bytes are neither a local file header signature (LOCSIG) nor an end-of-central-directory signature (ENDSIG). This aligns java.util.ZipFile with libziparchive except for empty archives.",
      "confidence": "high",
      "backport_notes": [
       "The fix is a self-contained 11-line insertion that uses LOCSIG_AT/ENDSIG_AT, ZFILE_Close and freeZip, which zip_util.c already has. It must go inside the `readFullyAt(..., 4, 0)` success block, after zip->locsig is set.",
       "The commit notes that the udc-dev branch uses ART module prebuilts, which is why tests were skipped. libcore's ojluni code is part of the ART mainline module (general platform knowledge)."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 10,
       "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_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/libcore",
       "sha": "b17fd2f8fe468e7d32e713b442f610cd33e4e7a9",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/libcore"
     ]
    },
    {
     "cve": "CVE-2024-40674",
     "osv_id": "ASB-A-343714914",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "DoS"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds a maximum length check (32 characters plus the two enclosing quotes) for quoted plaintext SSIDs in WifiConfigurationUtil.validateSsid, which previously only length-checked unquoted hex SSIDs.",
      "confidence": "high",
      "backport_notes": [
       "Single self-contained commit touching only validateSsid and its constants; it removes SSID_UTF_8_MIN_LEN, SSID_UTF_8_MAX_LEN and SSID_HEX_MIN_LEN, so a fork that references those constants elsewhere should keep them or adjust. Wifi is a mainline module, so the fix may also arrive via a module update rather than the platform tag (general platform knowledge)."
      ],
      "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_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/modules/Wifi",
       "sha": "debc548ac085ba1ab0582172b97d965e9a1ea43a",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/modules/Wifi"
     ]
    },
    {
     "cve": "CVE-2024-40675",
     "osv_id": "ASB-A-318683126",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "DoS"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Intent.parseUri now throws URISyntaxException(\"uri end not found\") when a name=value field in the new-format Intent URI loop has no ';' after it, instead of continuing with semi == -1.",
      "confidence": "high",
      "backport_notes": [
       "Self-contained 3-line insertion after `int semi = uri.indexOf(';', i);` in Intent.parseUri. The method already throws URISyntaxException (line 7859 context), so no signature change is needed. Forks with a customized parseUri loop should add the check before any use of `semi`."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 7,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "c6b5490ec659b5854fd429f453f75de5befa6359",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-40676",
     "osv_id": "ASB-A-349780950",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "AccountManagerService.checkKeyIntent now rejects authenticator-supplied KEY_INTENT Intents whose data URI scheme is \"content\", returning false before the resolved activity is accepted.",
      "confidence": "high",
      "backport_notes": [
       "The fix is a single three-line insertion in checkKeyIntent, directly after 'if (resolveInfo == null) return false;'. It needs only the Intent already extracted from the bundle and the existing resolveActivityAsUser call.",
       "On trees where the patched region does not fully match (Android 17: 3/4 lines), check by inspection that the '\"content\".equals(intent.getScheme())' rejection is present rather than re-applying the diff blindly."
      ],
      "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_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "e8a53246607b52b15269f97aef9ba7e928ba2473",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-40677",
     "osv_id": "ASB-A-327748846",
     "source": "osv",
     "announced": "2024-10-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "The Settings fragment AdvancedPowerUsageDetail (App battery usage detail page) now overrides shouldSkipForInitialSUW() to return true, so the page is not allowed to launch before the setup flow completes. This is described as an FRP bypass defense.",
      "confidence": "medium",
      "backport_notes": [
       "A single self-contained override. Its only dependency is that the target branch's Settings base fragment already provides and enforces the shouldSkipForInitialSUW() hook. If a branch lacks the hook, the override alone does nothing and the enforcement must be ported too."
      ],
      "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_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r13",
      "date": "2024-10-07",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/packages/apps/Settings",
       "sha": "db26138f07db830e3fb78283d37de3c0296d93cb",
       "tag": "android-security-14.0.0_r13",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/packages/apps/Settings"
     ]
    }
   ],
   "tags": [
    "android-security-14.0.0_r13"
   ],
   "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-0044": {
     "cve": "CVE-2024-0044",
     "summary": "PackageInstallerService session creation now rejects (nulls out) app and installer package names that are over-long or contain characters not accepted by FrameworkParsingPackageUtils.validateName, instead of only checking their length.",
     "component": "platform/frameworks/base, services/core PackageManager / PackageInstallerService (session creation)",
     "weakness": "Improper input validation: caller-supplied package-name strings (appPackageName, installerPackageName) were only length-checked, not validated for allowed characters, before being accepted and written to disk by the installer.",
     "root_cause": "In services/core/java/com/android/server/pm/PackageInstallerService.java, the session-creation path set params.appPackageName to null only if it was longer than SessionParams.MAX_PACKAGE_NAME_LENGTH, and used params.installerPackageName as requestedInstallerPackageName only if it was shorter than that limit. The separate installerPackageName argument was not validated at all. The surrounding comment says package name and label length are restricted so that really long strings aren't written to disk, but nothing checked that these strings were syntactically valid package names, so arbitrary character content could flow into the installer/app package name used by the session.",
     "fix_analysis": [
      "Commit 954b2874b85b (android-security-14.0.0_r6), PackageInstallerService.java: adds a private static isValidPackageName(String) that returns false if the name exceeds SessionParams.MAX_PACKAGE_NAME_LENGTH or if FrameworkParsingPackageUtils.validateName(packageName, requireSeparator=false, requireFilename=true) returns an error message; imports android.content.pm.parsing.FrameworkParsingPackageUtils.",
      "Same commit, session-creation path: replaces the length-only check on params.appPackageName with isValidPackageName (invalid -> null); adds an explicit check that nulls params.installerPackageName when invalid; requestedInstallerPackageName becomes params.installerPackageName if non-null else the installerPackageName argument.",
      "Commit 836750619a8b (android-security-14.0.0_r13), same method: adds a second check that nulls the installerPackageName method argument when it fails isValidPackageName, so the fallback value used for requestedInstallerPackageName (and passed later to mAppOps.checkPackage for non-system callers) is also validated; changes 'var' to 'String' for requestedInstallerPackageName (no semantic effect)."
     ],
     "completeness": [
      "From the code: all three package-name inputs visible in this method are now validated with the same helper: params.appPackageName, params.installerPackageName, and the installerPackageName argument.",
      "The validation is applied only at session creation in PackageInstallerService; the material does not show whether other paths that record or change installer names are validated, so coverage of those is unknown.",
      "params.appLabel is only trimmed to PackageItemInfo.MAX_SAFE_LABEL_LENGTH (unchanged); no character validation is applied to it, which is consistent with it being a label rather than a package name.",
      "Invalid values are silently replaced by null rather than rejected with an error, so a caller does not get feedback that its name was dropped."
     ],
     "behavior_changes": [
      "Package names containing characters rejected by FrameworkParsingPackageUtils.validateName (requireSeparator=false, requireFilename=true) are now treated as absent (null) for appPackageName, params.installerPackageName and the installerPackageName argument; the bare name 'android' remains accepted per the in-code comment.",
      "params.installerPackageName is now mutated to null when invalid (previously it was left untouched and only skipped as the requested installer when too long).",
      "For non-root/shell/system callers an invalid installerPackageName argument is now null when mAppOps.checkPackage(callingUid, installerPackageName) runs; the resulting behavior of that call is not shown in the material."
     ],
     "preconditions": [
      "Caller reaches the PackageInstallerService session-creation path (the IPackageInstaller session creation entry) and supplies an invalid appPackageName, installerPackageName in SessionParams, or installerPackageName argument.",
      "Context shows that for callers other than root/shell/adopted-shell/SYSTEM_UID the installerPackageName argument is subsequently checked against the calling uid via mAppOps.checkPackage; the exact caller class needed to trigger the issue is not stated in the material."
     ],
     "per_major": {
      "14": "Resolved via two commits on the android-security-14.0.0 branch: 954b2874b85b (r6, adds isValidPackageName and validates params.appPackageName/params.installerPackageName) and 836750619a8b (r13, validates the installerPackageName argument). Patched region present at android-security-14.0.0_r29 (7/8 lines).",
      "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": [
      "Apply 954b2874b85b before 836750619a8b: the second commit depends on the isValidPackageName helper and the FrameworkParsingPackageUtils import introduced by the first, and its hunk context (the 'Validate requested installer package name' block) comes from the first.",
      "The helper relies on android.content.pm.parsing.FrameworkParsingPackageUtils.validateName(String, boolean, boolean); confirm that class and signature exist on the target branch before porting."
     ],
     "confidence": "high",
     "unknowns": [
      "The exact consequence of an invalid installer/app package name being accepted (what downstream consumer of the name was affected) is not shown in the material.",
      "The enclosing method name is not shown in the diff header beyond the class; the code is the session-creation path using SessionParams, installerPackageName and callingUid.",
      "Behavior of mAppOps.checkPackage when installerPackageName has been nulled by the new check is not shown.",
      "Whether the 12, 12L and 13 branches received the same two-commit sequence is not shown in the material.",
      "Why only 7/8 lines of the patched region match at the latest tags, and how the code reached 15-17, is not shown."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 4,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-40672": {
     "cve": "CVE-2024-40672",
     "summary": "ChooserActivity.onCreate in the IntentResolver module now reads Settings.Global.SECURE_FRP_MODE and, when it is 1, logs, calls super.onCreate and immediately finishes, so the share sheet cannot be launched while Factory Reset Protection enforcement is active.",
     "component": "platform/packages/modules/IntentResolver, ChooserActivity (share sheet)",
     "weakness": "Missing authorization/state check (share sheet reachable while the device is in secure FRP mode)",
     "root_cause": "ChooserActivity.onCreate built the share sheet for an android.intent.action.CHOOSER intent without checking the FRP state (Settings.Global.SECURE_FRP_MODE). The commit message shows the sheet can be launched with `am start -a android.intent.action.CHOOSER ...`, so it was reachable while the device was still FRP-locked. The bulletin rates this as a High severity EoP.",
     "fix_analysis": [
      "java/src/com/android/intentresolver/ChooserActivity.java:onCreate: the new first statement reads Settings.Global.getInt(getContentResolver(), Settings.Global.SECURE_FRP_MODE, 0). If the value is 1, it logs \"Sharing disabled due to active FRP lock.\" at error level, calls super.onCreate(savedInstanceState), calls finish() and returns. All of this happens before Tracer.INSTANCE.markLaunched(), latency tracking, or any resolver/UI setup.",
      "java/src/com/android/intentresolver/ChooserActivity.java: adds `import android.provider.Settings;`.",
      "The default is 0 when the setting is absent, so behavior does not change when SECURE_FRP_MODE is unset."
     ],
     "completeness": [
      "Gates only ChooserActivity.onCreate in packages/modules/IntentResolver. The check runs at the top of onCreate, before any share-sheet setup in that method.",
      "The parent class ResolverActivity (ChooserActivity extends ResolverActivity) gets no equivalent check in this commit. The material does not say whether the plain resolver should also be blocked under FRP.",
      "The check is a single read at creation time and is not re-evaluated later in the activity lifecycle. The material does not show whether that matters.",
      "No test is added; the commit says it was verified manually."
     ],
     "behavior_changes": [
      "When Settings.Global.SECURE_FRP_MODE == 1, any launch of ChooserActivity finishes immediately with no UI and emits the error-level log line \"Sharing disabled due to active FRP lock.\".",
      "No change when the setting is 0 or unset."
     ],
     "preconditions": [
      "Device is in secure FRP mode (Settings.Global.SECURE_FRP_MODE set to 1).",
      "Something can start an android.intent.action.CHOOSER intent that resolves to the IntentResolver module's ChooserActivity (the commit message shows this with an adb `am start` command)."
     ],
     "per_major": {
      "14": "Same fix: commit ccd29124d0d2 merged in android-security-14.0.0_r13 (cherry-pick of 94d1e1e4e953). At android-security-14.0.0_r29 all 8/8 lines of the patched region are present.",
      "15": "Not affected (not listed by the bulletin). At android-security-15.0.0_r17, 7/8 lines of the patched region are present; the exact form is not shown.",
      "16": "Not affected (not listed by the bulletin). At android-security-16.0.0_r8, 7/8 lines of the patched region are present; the exact form is not shown.",
      "17": "Not affected (not listed by the bulletin). At android-security-17.0.0_r1, 7/8 lines of the patched region are present; the exact form is not shown."
     },
     "backport_notes": [
      "Self-contained 7-line change at the top of ChooserActivity.onCreate plus one import. It depends on the Settings.Global.SECURE_FRP_MODE constant.",
      "No 'Fix in fork' comparison was provided, so no per-file fork verdict can be given."
     ],
     "confidence": "high",
     "unknowns": [
      "Which component or user can send the CHOOSER intent during FRP in practice (the material only shows an adb trigger).",
      "Whether a legacy frameworks/base com.android.internal.app.ChooserActivity is still present and reachable on Android 14, and whether it would need an equivalent guard (the index shows only frameworks/base ResolverActivity and the coretests ChooserActivityTest).",
      "The exact textual difference behind the 7/8 line match on Android 15/16/17.",
      "Whether ResolverActivity (non-chooser) was intended to be gated as well."
     ],
     "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-40673": {
     "cve": "CVE-2024-40673",
     "summary": "libcore's native ZipFile open path (ZIP_Put_In_Cache0 in ojluni/src/main/native/zip_util.c) now rejects any zip file whose first 4 bytes are neither a local file header signature (LOCSIG) nor an end-of-central-directory signature (ENDSIG). This aligns java.util.ZipFile with libziparchive except for empty archives.",
     "component": "platform/libcore, ojluni native zip support (java.util.ZipFile, zip_util.c)",
     "weakness": "Missing input validation, which led java.util.ZipFile and libziparchive to interpret the same zip file differently (parser differential)",
     "root_cause": "In ZIP_Put_In_Cache0, the code read the first 4 bytes of the file only to record whether a local file header signature was present (zip->locsig = LOCSIG_AT(errbuf)). It then kept opening the archive whatever the result. The commit message cites the zip specification (APPNOTE 4.3.6 / 4.3.1): a non-empty zip must begin with a local file header, and an empty one with the end-of-central-directory record. According to the commit, libziparchive enforces this but ZipFile's native parser (zip_util.c) did not. So files with an invalid header at offset zero were accepted by ZipFile and rejected by libziparchive.",
     "fix_analysis": [
      "ojluni/src/main/native/zip_util.c:ZIP_Put_In_Cache0: the change goes inside the existing block that runs when readFullyAt(zfd, errbuf, 4, 0) succeeds, after zip->locsig is set. A new Android-changed block checks `!LOCSIG_AT(errbuf) && !ENDSIG_AT(errbuf)`. If neither signature is present, it sets *pmsg to \"Entry at offset zero has invalid LFH signature.\" (when pmsg is non-NULL), calls ZFILE_Close(zfd) and freeZip(zip), and returns NULL. This happens before the IO_Lseek length check and the rest of the open processing.",
      "It is a single commit, and the diff has no Java-side changes. The commit message says tests were skipped in this branch because udc-dev uses ART module prebuilts but builds tests from source."
     ],
     "completeness": [
      "The check only inspects the 4 bytes at offset zero. It accepts any file that starts with LOCSIG or ENDSIG and does no further validation of the header.",
      "The check is inside `if (readFullyAt(...) != -1)`. If that read fails, the new rejection is skipped and the existing later length/error handling applies.",
      "Files starting with ENDSIG (empty archives) are still accepted, although the commit message says libziparchive rejects them. The commit explicitly describes the alignment as \"modulo empty zip files\".",
      "The check is only in ZIP_Put_In_Cache0. According to the index search, ZipFile_open consults ZIP_Get_From_Cache first. The material does not show how that cache path behaves."
     ],
     "behavior_changes": [
      "Opening a file through java.util.ZipFile whose first 4 bytes are not LOCSIG or ENDSIG now fails, with the native error message \"Entry at offset zero has invalid LFH signature.\"",
      "Files that have data before the first local file header at offset zero are now rejected by ZipFile.",
      "Empty archives (starting with the end-of-central-directory record) are still accepted."
     ],
     "preconditions": [
      "A file is opened through java.util.ZipFile. According to the index search, ZipFile_open (libcore/ojluni/src/main/native/ZipFile.c) is a caller. The context shows a wrapper that calls ZIP_Put_In_Cache0.",
      "The file is not returned by ZIP_Get_From_Cache, and readFullyAt of the first 4 bytes succeeds.",
      "The file's first 4 bytes are neither LOCSIG nor ENDSIG."
     ],
     "per_major": {
      "14": "Same fix: commit b17fd2f8fe46 was cherry-picked into android-security-14.0.0_r13 (Ignore-AOSP-First). All 4 lines of the patched region are present at android-security-14.0.0_r29.",
      "15": "Not affected according to the bulletin. The patched region (4/4 lines) is present in ojluni/src/main/native/zip_util.c at android-security-15.0.0_r17.",
      "16": "Not affected according to the bulletin. ojluni/src/main/native/zip_util.c is absent at android-security-16.0.0_r8.",
      "17": "Not affected according to the bulletin. ojluni/src/main/native/zip_util.c is absent at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "The fix is a self-contained 11-line insertion that uses LOCSIG_AT/ENDSIG_AT, ZFILE_Close and freeZip, which zip_util.c already has. It must go inside the `readFullyAt(..., 4, 0)` success block, after zip->locsig is set.",
      "The commit notes that the udc-dev branch uses ART module prebuilts, which is why tests were skipped. libcore's ojluni code is part of the ART mainline module (general platform knowledge)."
     ],
     "confidence": "high",
     "unknowns": [
      "The material does not show how the ZipFile/libziparchive parsing mismatch leads to the bulletin's RCE classification, or what the concrete trigger is.",
      "The referenced tests (CtsLibcoreTestCases, CtsLibcoreOjTestCases) are not in the diff.",
      "The material does not show whether or how the same change was applied to Android 12, 12L and 13, which the bulletin lists as affected.",
      "Why the file is absent in Android 16/17 is not shown.",
      "How the fix reaches devices that update ART through the mainline module, as opposed to the platform build, is not shown.",
      "How ZIP_Get_From_Cache entries are created and checked is not shown."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 10,
      "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-40674": {
     "cve": "CVE-2024-40674",
     "summary": "Adds a maximum length check (32 characters plus the two enclosing quotes) for quoted plaintext SSIDs in WifiConfigurationUtil.validateSsid, which previously only length-checked unquoted hex SSIDs.",
     "component": "platform/packages/modules/Wifi, WifiConfiguration validation (service/java/com/android/server/wifi/WifiConfigurationUtil.java)",
     "weakness": "missing bounds/length check on externally supplied input (improper input validation)",
     "root_cause": "WifiConfigurationUtil.validateSsid only enforced an upper length bound for unquoted (hex) SSIDs: `if (!ssid.startsWith(\"\\\"\") && ssid.length() > SSID_HEX_MAX_LEN)`. Quoted plaintext SSIDs (strings starting with `\"`) had no upper length check in this code, so a caller could set an arbitrarily long SSID in a WifiConfiguration that passed validate(). The constants SSID_UTF_8_MIN_LEN and SSID_UTF_8_MAX_LEN existed but were not used in that branch (the diff removes them). The bulletin rates the impact as DoS; the material does not show which downstream consumer fails on an over-long SSID.",
     "fix_analysis": [
      "service/java/com/android/server/wifi/WifiConfigurationUtil.java:validateSsid: the single hex-only condition is split into two branches. If ssid.startsWith(\"\\\"\"), the method now returns false with log 'validateSsid failed: plaintext ssid ... longer than 32 chars' when ssid.length() > SSID_PLAINTEXT_MAX_LEN (new constant, 32 + ENCLOSING_QUOTES_LEN = 34). Otherwise the pre-existing hex check (ssid.length() > SSID_HEX_MAX_LEN = 64) is kept unchanged.",
      "Constants cleanup in the same file: SSID_UTF_8_MIN_LEN, SSID_UTF_8_MAX_LEN and SSID_HEX_MIN_LEN are removed; SSID_PLAINTEXT_MAX_LEN is introduced. SSID_HEX_MAX_LEN is retained.",
      "service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java: renames testValidateNegativeCases_MalformedAsciiSsidString to testValidateNegativeCases_MalformedPlaintextSsidString and adds testValidateNegativeCases_TooLongPlaintextSsidString, which asserts that a quoted 33-character SSID fails validate(config, SUPPORTED_FEATURES_ALL, VALIDATE_FOR_ADD)."
     ],
     "completeness": [
      "Covers both SSID encodings handled by validateSsid: quoted plaintext (new 34-char cap including quotes) and unquoted hex (existing 64-char cap).",
      "The new check counts Java String characters (ssid.length()), not encoded bytes; the commit message justifies the 32 limit by the minimum of 1 byte per character for any SSID encoding. A quoted SSID of up to 32 multi-byte characters still passes this check; whether the subsequent WifiSsid parsing (the `WifiSsid wifiSsid; try {` block immediately after) enforces the 32-byte limit is not shown in the material.",
      "The check applies only to code paths that go through WifiConfigurationUtil.validate/validateSsid; SSIDs set via other entry points that do not call this validator are not affected by this change (none are shown in the material)."
     ],
     "behavior_changes": [
      "WifiConfigurationUtil.validate now returns false (with an error log) for quoted plaintext SSIDs longer than 32 characters (34 including quotes); such configurations are rejected where they were previously accepted.",
      "Log message text for the plaintext case: 'validateSsid failed: plaintext ssid <ssid> longer than 32 chars'."
     ],
     "preconditions": [
      "A WifiConfiguration with a quoted (plaintext) SSID longer than 32 characters must reach WifiConfigurationUtil.validate (the new test exercises VALIDATE_FOR_ADD), i.e. the caller must be able to submit a WifiConfiguration to the Wifi service; the exact external entry points and the required caller privileges are not shown in the material."
     ],
     "per_major": {
      "14": "same fix: commit debc548ac085 in android-security-14.0.0_r13 (cherry-pick of 4a7564305147); at android-security-14.0.0_r29, 5/8 lines of the patched region are present, and the shown code contains the SSID_PLAINTEXT_MAX_LEN constant.",
      "15": "not affected per the bulletin; at android-security-15.0.0_r17, 5/8 lines of the patched region are present.",
      "16": "not affected per the bulletin; at android-security-16.0.0_r8, 5/8 lines of the patched region are present.",
      "17": "not affected per the bulletin; at android-security-17.0.0_r1, 5/8 lines of the patched region are present."
     },
     "backport_notes": [
      "Single self-contained commit touching only validateSsid and its constants; it removes SSID_UTF_8_MIN_LEN, SSID_UTF_8_MAX_LEN and SSID_HEX_MIN_LEN, so a fork that references those constants elsewhere should keep them or adjust. Wifi is a mainline module, so the fix may also arrive via a module update rather than the platform tag (general platform knowledge)."
     ],
     "confidence": "high",
     "unknowns": [
      "Which downstream component fails (and how) when an over-long plaintext SSID is accepted; the bulletin only gives the type as DoS.",
      "Whether the WifiSsid parsing after the new check enforces the 32-byte limit for multi-byte UTF-8 plaintext SSIDs.",
      "The concrete external callers (Binder entry points) that route into WifiConfigurationUtil.validate and their permission requirements.",
      "Which 3 of the 8 patched-region lines are absent at the latest tags of 14 through 17.",
      "When the upstream commit 4a7564305147 landed in the 15+ branches."
     ],
     "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-40675": {
     "cve": "CVE-2024-40675",
     "summary": "Intent.parseUri now throws URISyntaxException(\"uri end not found\") when a name=value field in the new-format Intent URI loop has no ';' after it, instead of continuing with semi == -1.",
     "component": "platform/frameworks/base, core/java/android/content/Intent.java (Intent URI parsing, parseUri)",
     "weakness": "Missing validation of an indexOf() result (-1) in a parsing loop (improper input validation; the bulletin classes it as DoS)",
     "root_cause": "In Intent.parseUri, the loop over the new-format Intent URI body (`while (i >= 0 && !uri.startsWith(\"end\", i))`) computes `int semi = uri.indexOf(';', i)` and did not check for -1 before going on with the iteration. When a field is not terminated by ';', parsing went on with semi == -1 instead of rejecting the input. The bulletin rates the result as a High-severity DoS. The material does not show the exact failure mode, because the code that advances the loop is outside the shown context.",
     "fix_analysis": [
      "core/java/android/content/Intent.java:parseUri: right after `int semi = uri.indexOf(';', i);`, the fix adds `if (semi < 0) throw new URISyntaxException(uri, \"uri end not found\");`. Parsing now stops as soon as a field terminator is missing, before any later use of `semi` in the loop body.",
      "Single commit (c6b5490ec659) with 3 inserted lines and no other files touched. Test: atest IntentTest."
     ],
     "completeness": [
      "The fix covers only the new-format parsing loop in parseUri. Every field type handled inside that loop (action=, category=, type=, identifier=, ...) is covered, because the check runs before any field dispatch.",
      "This commit does not modify the old-format path `getIntentOld(uri, flags)` (line 7831). The material does not show its parsing code, so whether it has a similar issue is unknown.",
      "The `eq` handling (`if (eq < 0) eq = i-1;`) is unchanged. With the new check, `semi` is always >= i after the check."
     ],
     "behavior_changes": [
      "Intent.parseUri now throws URISyntaxException with the message \"uri end not found\" for new-format intent URIs whose field list is missing a terminating ';'.",
      "Well-formed URIs, where every field is followed by ';', are not affected by the added check."
     ],
     "preconditions": [
      "A caller passes a string to Intent.parseUri that reaches the new-format parsing loop and has a field with no ';' after it.",
      "The material does not show which platform components parse untrusted intent URIs this way."
     ],
     "per_major": {
      "14": "same fix: commit c6b5490ec659 in android-security-14.0.0_r13 (linked by bug_id 318683126). All 4/4 lines of the patched region are present at android-security-14.0.0_r29.",
      "15": "not affected (the bulletin does not list it). The patched region (4/4 lines) is present at android-security-15.0.0_r17.",
      "16": "not affected (the bulletin does not list it). The patched region (4/4 lines) is present at android-security-16.0.0_r8.",
      "17": "not affected (the bulletin does not list it). The patched region (4/4 lines) is present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Self-contained 3-line insertion after `int semi = uri.indexOf(';', i);` in Intent.parseUri. The method already throws URISyntaxException (line 7859 context), so no signature change is needed. Forks with a customized parseUri loop should add the check before any use of `semi`."
     ],
     "confidence": "high",
     "unknowns": [
      "The exact failure mode with semi == -1 (for example how the loop advances `i`) is not in the shown context. Only the bulletin's DoS classification is known.",
      "Whether getIntentOld has a similar missing check is not shown.",
      "Which platform or system components call parseUri on untrusted input is not shown in the material.",
      "How such malformed input was handled before the fix (for example a hang or an exception) is not shown."
     ],
     "meta": {
      "generated": "2026-10-04",
      "author_model": "claude-fable-5-1",
      "review_model": "claude-opus-5-5",
      "review_corrections": 7,
      "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
     }
    },
    "CVE-2024-40676": {
     "cve": "CVE-2024-40676",
     "summary": "AccountManagerService.checkKeyIntent now rejects authenticator-supplied KEY_INTENT Intents whose data URI scheme is \"content\", returning false before the resolved activity is accepted.",
     "component": "platform/frameworks/base, services/core AccountManagerService (account authenticator KEY_INTENT validation)",
     "weakness": "Insufficient validation of an authenticator-supplied Intent: a content-scheme data URI was not rejected by the security check",
     "root_cause": "checkKeyIntent(int authUid, Bundle bundle) in services/core/java/com/android/server/accounts/AccountManagerService.java is the policy gate for Intents that an account authenticator supplies under AccountManager.KEY_INTENT. Its doc comment says the goal is to stop an authenticator from tricking users into launching arbitrary intents. Before the fix, the method checked the parcel shape (checkKeyIntentParceledCorrectly), set an empty ClipData so that no URIs inside it would be promoted for grants, resolved the activity, and required the target to be either an exported system activity or signature-compatible with the authenticator. It never inspected the Intent's own data URI. An Intent with a \"content\" scheme data URI therefore passed the check and was stored back into the bundle (bundle.putParcelable(KEY_INTENT, intent)) with its component pinned to the resolved activity.",
     "fix_analysis": [
      "services/core/java/com/android/server/accounts/AccountManagerService.java:checkKeyIntent: three lines are added after the pm.resolveActivityAsUser(...) null check and before resolveInfo.activityInfo is read: if (\"content\".equals(intent.getScheme())) return false;. Any KEY_INTENT whose data URI scheme is content is now rejected, whichever activity it resolves to and whether or not the target shares a signature with the authenticator.",
      "No other code is changed. The existing ClipData reset, activity resolution, isExportedSystemActivity / hasSignatureCapability checks and component pinning stay as they were."
     ],
     "completeness": [
      "The check is a single exact string comparison on intent.getScheme(), so only the data URI scheme is examined. Intents with no data URI, or with any other scheme, are unaffected and still go through the existing target-activity checks.",
      "The check sits after resolveActivityAsUser. An Intent that does not resolve already returned false, so the new rule only adds a rejection for resolvable content-scheme Intents.",
      "Only checkKeyIntent is modified. The material does not show whether every consumer of KEY_INTENT in AccountManagerService goes through checkKeyIntent.",
      "The parceling check just above the new code writes an EventLog 0x534e4554 entry when it rejects. The new rejection writes no log or event."
     ],
     "behavior_changes": [
      "checkKeyIntent now returns false for a KEY_INTENT carrying a content:// data URI, even when the target activity is a system activity or shares the authenticator's signature.",
      "The new rejection path adds no log, exception or error code."
     ],
     "preconditions": [
      "An account authenticator returns a Bundle containing AccountManager.KEY_INTENT, and AccountManagerService runs checkKeyIntent on it with the authenticator's uid (authUid).",
      "The Intent must resolve to an activity for the user (resolveActivityAsUser returns non-null). Before the fix, it also had to resolve to an exported system activity or a signature-compatible package to be accepted.",
      "The bulletin rates this High severity EoP. The material does not describe what launching such an Intent leads to."
     ],
     "per_major": {
      "14": "same fix: commit e8a53246607b (cherry-pick of c1e79495a49b, Change-Id I8b23191d3d60036ca7ddf0ef7dcba6b38fb27b3c) in android-security-14.0.0_r13. At android-security-14.0.0_r29, 4/4 lines of the patched region are present.",
      "15": "not affected (per the bulletin). At android-security-15.0.0_r17, 4/4 lines of the patched region are present.",
      "16": "not affected (per the bulletin). At android-security-16.0.0_r8, 4/4 lines of the patched region are present.",
      "17": "not affected (per the bulletin). At android-security-17.0.0_r1, 3/4 lines of the patched region are present. The material does not show which line differs or why."
     },
     "backport_notes": [
      "The fix is a single three-line insertion in checkKeyIntent, directly after 'if (resolveInfo == null) return false;'. It needs only the Intent already extracted from the bundle and the existing resolveActivityAsUser call.",
      "On trees where the patched region does not fully match (Android 17: 3/4 lines), check by inspection that the '\"content\".equals(intent.getScheme())' rejection is present rather than re-applying the diff blindly."
     ],
     "confidence": "high",
     "unknowns": [
      "What a content-scheme KEY_INTENT specifically allowed when launched. The bulletin gives only High / EoP, and the commit message only says 'Block intents with content data scheme'.",
      "What callers do when checkKeyIntent returns false, which callers in AccountManagerService consume KEY_INTENT, and whether all of them go through checkKeyIntent.",
      "Which line of the patched region differs at android-security-17.0.0_r1, and why.",
      "Whether Android 12, 12L and 13 (listed as affected by the bulletin) received the same change. The material only covers Android 14 and later."
     ],
     "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-40677": {
     "cve": "CVE-2024-40677",
     "summary": "The Settings fragment AdvancedPowerUsageDetail (App battery usage detail page) now overrides shouldSkipForInitialSUW() to return true, so the page is not allowed to launch before the setup flow completes. This is described as an FRP bypass defense.",
     "component": "platform/packages/apps/Settings, fuelgauge (App battery usage detail, AdvancedPowerUsageDetail)",
     "weakness": "Missing state check: the fragment did not opt into the Settings guard that skips pages during initial setup, so it could be shown before setup completed (FRP bypass).",
     "root_cause": "AdvancedPowerUsageDetail extends DashboardFragment and did not override shouldSkipForInitialSUW() to return true. Per the commit message and test, the app battery usage app info page could therefore be launched (via ADB in the test) during setup after a factory reset, which defeats Factory Reset Protection. The base-class default and its enforcement are not shown in the material.",
     "fix_analysis": [
      "src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java: adds an override `protected boolean shouldSkipForInitialSUW() { return true; }` between onResume() and onPause(). This opts the fragment into an existing Settings hook. The base-class code that acts on the hook is not in the diff.",
      "tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java: adds shouldSkipForInitialSUW_returnTrue, which asserts that the override returns true."
     ],
     "completeness": [
      "Covers only the AdvancedPowerUsageDetail fragment. The fix is a single boolean override and relies entirely on the base fragment enforcing shouldSkipForInitialSUW(). That enforcement is not shown in the material.",
      "The commit touches no other fuelgauge or Settings pages. The material does not show whether other fragments reachable during setup lack the same override.",
      "The commit is marked RESTRICT AUTOMERGE and is a cherry-pick of commit 419a6a907902. It adds no logic beyond the override."
     ],
     "behavior_changes": [
      "While the setup flow has not completed, launching the App battery usage detail page (AdvancedPowerUsageDetail) now closes the page instead of showing it. Commit test: 'launch app battery usage app info via ADB during Setup -> verify app closes'.",
      "After setup completes, behavior is expected to be unchanged, but this depends on base-class code that is not shown."
     ],
     "preconditions": [
      "Device is in the initial setup flow (for example after a factory reset, before setup completes).",
      "The AdvancedPowerUsageDetail page can be launched during setup. The commit message describes launching it via ADB."
     ],
     "per_major": {
      "14": "same fix: commit db26138f07db (RESTRICT AUTOMERGE cherry-pick of 419a6a907902) in android-security-14.0.0_r13. At android-security-14.0.0_r29, all 4 lines of the patched region are present.",
      "15": "not affected per the bulletin. At android-security-15.0.0_r17, 3 of the 4 lines of the patched region are present. The material does not show whether the override is fully present or which commit carried it.",
      "16": "not affected per the bulletin. At android-security-16.0.0_r8, 3 of the 4 lines of the patched region are present. Whether the override is fully present is not shown.",
      "17": "not affected per the bulletin. At android-security-17.0.0_r1, 3 of the 4 lines of the patched region are present. Whether the override is fully present is not shown."
     },
     "backport_notes": [
      "A single self-contained override. Its only dependency is that the target branch's Settings base fragment already provides and enforces the shouldSkipForInitialSUW() hook. If a branch lacks the hook, the override alone does nothing and the enforcement must be ported too."
     ],
     "confidence": "medium",
     "unknowns": [
      "The base-class code that acts on shouldSkipForInitialSUW() is not in the material: where it is checked, which setup or provisioning state it tests, and how it closes the page.",
      "The exact intent or entry point used to launch the page during setup is not shown beyond 'via ADB' in the commit message.",
      "Which commit, if any, carried the fix into the 15, 16 and 17 lines, and why one of the four patched lines differs there, is not shown."
     ],
     "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."
     }
    }
   }
  },
  "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-10-01",
  "latest_version": "1.0",
  "latest_revision": {
   "version": "1.0",
   "date": "October 7, 2024",
   "notes": "Bulletin Published."
  },
  "revisions": [
   {
    "version": "1.0",
    "date": "October 7, 2024",
    "notes": "Bulletin Published."
   }
  ],
  "tracked_since": "2026-09-30",
  "changes_since_tracking": [],
  "out_of_scope_rows": {
   "Imagination Technologies": 7,
   "MediaTek components": 8,
   "Qualcomm closed-source components": 1,
   "Qualcomm components": 3
  },
  "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."
 }
}