{
 "month": "2024-12",
 "generated": "2026-10-06T12:05+00:00",
 "majors": {
  "14": {
   "counts": {
    "announced": 6,
    "certain": 6,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [
    {
     "cve": "CVE-2024-43097",
     "osv_id": "ASB-A-350118416",
     "source": "osv",
     "announced": "2024-12-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "In Skia's SkRegion.cpp, RunArray::resizeToAtLeast now computes the 50% growth headroom with SkSafeMath::addInt and clamps the new element count to SK_MaxS32 on overflow, instead of letting `count += count >> 1` overflow a signed int before it is passed to realloc and stored as fCount.",
      "confidence": "medium",
      "backport_notes": [
       "The patch uses SkSafeMath (addInt, bool conversion) and SK_MaxS32 in SkRegion.cpp without adding an #include. When backporting, confirm that SkSafeMath is reachable from SkRegion.cpp in the target tree."
      ],
      "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_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/external/skia",
       "sha": "8d355fe1d0795fc30b84194b87563f75c6f8f2a7",
       "tag": "android-security-14.0.0_r15",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/external/skia"
     ]
    },
    {
     "cve": "CVE-2024-43762",
     "osv_id": "ASB-A-340239088",
     "source": "osv",
     "announced": "2024-12-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds ServiceConnection.onNullBinding() overrides to three service connections in the app widget stack (RemoteViewsAdapter and two anonymous connections in AppWidgetServiceImpl), so that a service whose onBind() returns null gets unbound.",
      "confidence": "medium",
      "backport_notes": [
       "A single commit that only adds code, with no dependencies. It adds onNullBinding overrides next to the existing onServiceConnected/onServiceDisconnected methods. The material does not show the enclosing method of the second AppWidgetServiceImpl hunk (near original line 2014); find it by the same onServiceConnected/unbindService(this) structure.",
       "ServiceConnection.onNullBinding is a default interface method added in API 28, so the override compiles on Android 12 through 14 (general platform knowledge)."
      ],
      "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_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "ae43ac7f3d3d5112b0f54b5315a15b08208acf9c",
       "tag": "android-security-14.0.0_r15",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-43764",
     "osv_id": "BUL-CVE-2024-43764",
     "source": "bulletin",
     "announced": "2024-12-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "SystemUI's ClipboardListener now checks KeyguardManager.isDeviceLocked() before showing the interactive clipboard overlay, falling back to the non-interactive \"copied\" toast when the device is locked.",
      "confidence": "high",
      "backport_notes": [
       "The fix adds a constructor-injected KeyguardManager, so the target branch's SystemUI Dagger graph must be able to provide KeyguardManager (SystemUI normally exposes framework system services through its FrameworkServicesModule) (general platform knowledge). Any tests or other code that construct ClipboardListener directly must be updated to the new signature, as ClipboardListenerTest was."
      ],
      "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_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "70eb75df7d342429c3ee225feb7c011df727442f",
       "tag": "android-security-14.0.0_r15",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "",
      "platform/frameworks/base"
     ]
    },
    {
     "cve": "CVE-2024-43767",
     "osv_id": "ASB-A-352631932",
     "source": "osv",
     "announced": "2024-12-01",
     "severity": "High",
     "types": [
      "RCE"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds a check in SkBlurMF.cpp prepare_to_draw_into_mask() so it returns false when SkMask::computeImageSize() returns 0 (the size overflow signal, per the commit title), so no SkMask image is allocated with that size.",
      "confidence": "medium",
      "backport_notes": [
       "Self-contained 3-line change with no dependencies shown. It applies where prepare_to_draw_into_mask() in src/core/SkBlurMF.cpp has the computeImageSize() then AllocImage() sequence.",
       "external/skia is not a mainline module and ships with the platform image, so the fix must be in the device build (general platform knowledge)."
      ],
      "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_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/external/skia",
       "sha": "796c2040f641bb287dba66c9823ce45e9f8b5807",
       "tag": "android-security-14.0.0_r15",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/external/skia"
     ]
    },
    {
     "cve": "CVE-2024-43768",
     "osv_id": "ASB-A-349678452",
     "source": "osv",
     "announced": "2024-12-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Adds an integer-overflow bounds check to Skia's zlib allocator callback skia_alloc_func in src/pdf/SkDeflate.cpp so that nullptr is returned when items * size would not fit in size_t, instead of passing a wrapped-around size to sk_calloc_throw.",
      "confidence": "high",
      "backport_notes": [
       "Single-commit, 8-line change confined to skia_alloc_func plus one include; the only merge friction reported was the include block. The fix depends on SkTFitsIn being available.",
       "No fork comparison was provided in the material, so no per-file fork verdict can be reported."
      ],
      "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_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/external/skia",
       "sha": "b5543cb8c6b95623743016055220378efe73eb93",
       "tag": "android-security-14.0.0_r15",
       "provenance": "security_tag",
       "method": "bug_id",
       "confidence": "certain",
       "evidence": null,
       "similarity": null
      }
     ],
     "n_public_commits": 1,
     "projects": [
      "platform/external/skia"
     ]
    },
    {
     "cve": "CVE-2024-43769",
     "osv_id": "ASB-A-360807442",
     "source": "osv",
     "announced": "2024-12-01",
     "severity": "High",
     "types": [
      "EoP"
     ],
     "status": "resolved",
     "brief": {
      "summary": "Reworks PackageManagerService.isPackageDeviceAdmin so the device management role holder (DMRH) counts as an admin only on users that are organization-managed. When the DMRH is a system package, it is treated as an admin on all users whenever any user is both managed and has it as role holder. Per the commit comment, this addresses 'uninstall updates' on an unmanaged user breaking management on other users.",
      "confidence": "medium",
      "backport_notes": [
       "Single-file, single-function change. It depends on DevicePolicyManagerInternal.isUserOrganizationManaged(int), mInjector.getLocalService, snapshotComputer().getPackageStateInternal and PackageStateInternal.isSystem() existing on the target branch. Check these before porting to older branches such as 13, which the bulletin also lists as affected.",
       "The commit references the test DevicePolicyManagementRoleHolderTest (a.d.c.), which is not part of this diff."
      ],
      "meta": {
       "generated": "2026-10-04",
       "author_model": "claude-fable-5-1",
       "review_model": "claude-opus-5-5",
       "review_corrections": 7,
       "note": "AI-generated from the bulletin, the fixing diffs and their code context, then checked claim by claim by a second model. Statements marked '(general platform knowledge)' are not taken from the material."
      }
     },
     "method": [
      "bug_id"
     ],
     "confidence": "certain",
     "first_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "last_fix": {
      "tag": "android-security-14.0.0_r15",
      "date": "2024-12-02",
      "provenance": "security_tag"
     },
     "public_commits": [
      {
       "project": "platform/frameworks/base",
       "sha": "619ffc299bf33566ba6daee8301ee0fc96e015f4",
       "tag": "android-security-14.0.0_r15",
       "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_r15"
   ],
   "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-43097": {
     "cve": "CVE-2024-43097",
     "summary": "In Skia's SkRegion.cpp, RunArray::resizeToAtLeast now computes the 50% growth headroom with SkSafeMath::addInt and clamps the new element count to SK_MaxS32 on overflow, instead of letting `count += count >> 1` overflow a signed int before it is passed to realloc and stored as fCount.",
     "component": "platform/external/skia, src/core/SkRegion.cpp (RunArray run storage used by SkRegion)",
     "weakness": "Signed integer overflow in an allocation-size computation (missing overflow check).",
     "root_cause": "RunArray (src/core/SkRegion.cpp) is a grow-only buffer of SkRegionPriv::RunType. resizeToAtLeast(int count) added 50% headroom with `count += count >> 1` in plain int arithmetic. For a large enough requested count this addition overflows the signed int, so the value passed to fMalloc.realloc() and stored in fCount no longer reflects the requested size. operator[] checks bounds only with SkASSERT (debug builds), so release-build indexing relies on fCount being correct. The commit describes the issue as speculative, with no repro case.",
     "fix_analysis": [
      "src/core/SkRegion.cpp:RunArray::resizeToAtLeast: `count += count >> 1` is replaced with an SkSafeMath instance; `newCount = safe.addInt(count, count >> 1)` does the addition with overflow tracking.",
      "If no overflow is reported (`safe` is true), the grown value is used. Otherwise count is clamped to SK_MaxS32, which is never smaller than the requested int count.",
      "The resulting count is used for fMalloc.realloc(count) and stored in fCount. The memcpy from the stack buffer still copies the old fCount elements."
     ],
     "completeness": [
      "resizeToAtLeast is the only RunArray method shown that reallocates fMalloc and updates fCount, and the headroom addition is its only arithmetic on count.",
      "The fix does not add runtime bounds checking to operator[] (still SkASSERT only) and does not validate the count requested by callers. A clamped request for SK_MaxS32 elements is left to fMalloc.realloc to handle (the class comment says RunArray uses sk_realloc_throw).",
      "Single-commit fix; only src/core/SkRegion.cpp changed."
     ],
     "behavior_changes": [
      "When the 50% growth computation would overflow, the requested capacity becomes SK_MaxS32 elements instead of an overflowed value. Such a large request is left to the allocator, which per the class comment throws on failure.",
      "For sizes that do not overflow, the arithmetic result is unchanged."
     ],
     "preconditions": [
      "An SkRegion operation must grow a RunArray with a count large enough that count + (count >> 1) exceeds INT_MAX (roughly count > 1.43e9).",
      "Per index search, frameworks/base/libs/hwui/jni/Region.cpp calls SkRegion::op from Region_op0 and Region_op1, and scale_rgn unions rects into a temporary SkRegion. The material does not show whether these paths reach the overflowing size.",
      "The operation sequence that produces such a count is not shown; the commit calls the issue speculative with no repro."
     ],
     "per_major": {
      "14": "same fix: commit 8d355fe1d079 in android-security-14.0.0_r15 (Bug 350118416). The patched resizeToAtLeast is visible in the code at android-security-14.0.0_r29; the line check reports 6/8 lines of the patched region present.",
      "15": "not affected per bulletin; 6/8 lines of the patched region present at android-security-15.0.0_r17.",
      "16": "not affected per bulletin; 6/8 lines of the patched region present at android-security-16.0.0_r8.",
      "17": "not affected per bulletin; 6/8 lines of the patched region present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "The patch uses SkSafeMath (addInt, bool conversion) and SK_MaxS32 in SkRegion.cpp without adding an #include. When backporting, confirm that SkSafeMath is reachable from SkRegion.cpp in the target tree."
     ],
     "confidence": "medium",
     "unknowns": [
      "Which SkRegion operation sequence can push the run count high enough to overflow; the commit states there is no repro case.",
      "Whether AutoTMalloc::realloc takes a signed or unsigned count, i.e. what an overflowed value did on affected builds, and whether an out-of-bounds access actually followed.",
      "Why only 6/8 lines of the patched region match in the 14 to 17 tags.",
      "How the fix was applied to Android 12, 12L and 13 (listed as affected but no per-major data provided)."
     ],
     "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-43762": {
     "cve": "CVE-2024-43762",
     "summary": "Adds ServiceConnection.onNullBinding() overrides to three service connections in the app widget stack (RemoteViewsAdapter and two anonymous connections in AppWidgetServiceImpl), so that a service whose onBind() returns null gets unbound.",
     "component": "platform/frameworks/base, AppWidget service (services/appwidget AppWidgetServiceImpl) and core/java/android/widget/RemoteViewsAdapter",
     "weakness": "Missing handling of the ServiceConnection.onNullBinding callback: in AppWidgetServiceImpl the bind is released only from onServiceConnected, so a null binding is never unbound (unreleased binding).",
     "root_cause": "The ServiceConnection objects in AppWidgetServiceImpl called mContext.unbindService(this) only from onServiceConnected(), and the RemoteViewsAdapter connection did not override onNullBinding(). When the target service's onBind() returns null, the framework calls onNullBinding() instead of onServiceConnected(), so no unbind took place. In AppWidgetServiceImpl.destroyRemoteViewsService the bind uses mContext.bindServiceAsUser(intent, conn, BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE_WHILE_AWAKE, widget.provider.id.getProfile()) under Binder.clearCallingIdentity(), so a null-binding service was left bound with those flags. The second anonymous ServiceConnection in AppWidgetServiceImpl (hunk near line 2014) and the RemoteViewsAdapter connection also lacked onNullBinding. The bulletin rates this as a High severity EoP.",
     "fix_analysis": [
      "core/java/android/widget/RemoteViewsAdapter.java, inner ServiceConnection/Handler.Callback class (next to onServiceDisconnected): adds onNullBinding(ComponentName), which calls enqueueDeferredUnbindServiceMessage(). This reuses the deferred-unbind path that the MSG_REQUEST_BIND and MSG_NOTIFY_DATA_SET_CHANGED handlers already use.",
      "services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java:destroyRemoteViewsService: the anonymous ServiceConnection gains onNullBinding(ComponentName), which immediately calls mContext.unbindService(this), the same call onServiceConnected makes after cb.onDestroy(intent).",
      "services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java, second anonymous ServiceConnection (hunk near original line 2014; the material does not show the enclosing method): the same onNullBinding override calling mContext.unbindService(this).",
      "The change only adds code (15 lines, nothing removed) and does not change onServiceConnected or onServiceDisconnected."
     ],
     "completeness": [
      "Covers the null-binding case for all three ServiceConnection implementations in the diff; each one now releases the binding when onBind() returns null.",
      "onServiceDisconnected stays a no-op in both AppWidgetServiceImpl connections, and none of the three connections overrides onBindingDied. The material does not show whether those paths matter for this issue.",
      "No change to how or when the binds are started (flags, clearCallingIdentity, profile selection) in AppWidgetServiceImpl; the fix only makes sure the binding is released after a null binding."
     ],
     "behavior_changes": [
      "A service whose onBind() returns null is now unbound right away by AppWidgetServiceImpl, or through the deferred unbind message in RemoteViewsAdapter, instead of staying bound.",
      "In RemoteViewsAdapter, a null binding now schedules the same deferred unbind used after normal operations; callers see no new error."
     ],
     "preconditions": [
      "An app exposes a service, targeted by the intent the widget stack binds to, whose onBind() returns null.",
      "AppWidgetServiceImpl path: destroyRemoteViewsService(intent, widget) runs for that widget (the bind uses the widget provider's profile user with cleared calling identity), or the second bind site near line 2014 is reached.",
      "RemoteViewsAdapter path: a host process binds the collection service through AppWidgetManager.bindRemoteViewsService (MSG_REQUEST_BIND) and the service returns a null binder."
     ],
     "per_major": {
      "14": "same fix: commit ae43ac7f3d3d in android-security-14.0.0_r15 (cherry-pick of d406f4708e39, Change-Id I12fccb572e159a73785aa33a4f5204e094ccd1b7); all 6 lines of the patched region are present at android-security-14.0.0_r29.",
      "15": "not affected (not listed by the bulletin); all 6 lines of the patched region are present at android-security-15.0.0_r17.",
      "16": "not affected (not listed by the bulletin); all 6 lines of the patched region are present at android-security-16.0.0_r8.",
      "17": "not affected (not listed by the bulletin); all 6 lines of the patched region are present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "A single commit that only adds code, with no dependencies. It adds onNullBinding overrides next to the existing onServiceConnected/onServiceDisconnected methods. The material does not show the enclosing method of the second AppWidgetServiceImpl hunk (near original line 2014); find it by the same onServiceConnected/unbindService(this) structure.",
      "ServiceConnection.onNullBinding is a default interface method added in API 28, so the override compiles on Android 12 through 14 (general platform knowledge)."
     ],
     "confidence": "medium",
     "unknowns": [
      "The enclosing method of the second AppWidgetServiceImpl hunk (near line 2014), and which service it binds, are not shown in the material.",
      "The material does not describe the concrete privilege-escalation consequence of the leaked binding beyond the bulletin's High/EoP rating and the commit's mention of a PoC app.",
      "The per-major facts provided do not say whether the fix was also applied to the Android 12, 12L and 13 branches."
     ],
     "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-43764": {
     "cve": "CVE-2024-43764",
     "summary": "SystemUI's ClipboardListener now checks KeyguardManager.isDeviceLocked() before showing the interactive clipboard overlay, falling back to the non-interactive \"copied\" toast when the device is locked.",
     "component": "platform/frameworks/base, SystemUI clipboard overlay (packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java)",
     "weakness": "Missing authorization/state check (interactive UI exposing intents shown while device is locked)",
     "root_cause": "In ClipboardListener.onPrimaryClipChanged(), the decision to show the interactive clipboard overlay (via mOverlayProvider / ClipboardOverlayController) was gated only on user setup completion (isUserSetupComplete()) and on clipData being non-null and non-empty. It did not consider the device lock state. Per the commit message, in some situations the clipboard UI could be entered while the device was locked, and the intents it provides could be accessed from there. The commit message states users should not be able to access intents from this state.",
     "fix_analysis": [
      "packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java: a KeyguardManager field (mKeyguardManager) is added and injected through the constructor (new parameter between ClipboardManager and UiEventLogger).",
      "ClipboardListener.onPrimaryClipChanged(): the existing guard becomes `mKeyguardManager.isDeviceLocked() || !isUserSetupComplete() || clipData == null || clipData.getItemCount() == 0`. When the device is locked the code takes the same branch as the not-setup-complete case: if shouldShowToast(clipData) it shows the toast (ClipboardToast.showCopiedToast, logging CLIPBOARD_TOAST_SHOWN), and the new test verifies that the overlay provider is not used.",
      "packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java: adds a mocked KeyguardManager to the constructor call and a new test, test_deviceLocked_showsToast. The test verifies that with isDeviceLocked()==true only the toast is shown and the overlay provider has zero interactions."
     ],
     "completeness": [
      "The check is added to the existing guard in onPrimaryClipChanged that decides between toast and interactive overlay, so it is evaluated on each clip change that reaches that guard (an earlier early-return in the method is unchanged).",
      "Uses isDeviceLocked() rather than isKeyguardLocked(). Per the commit message this is intentional: a keyguard that is up but trivially dismissable still gets the interactive overlay.",
      "The check is evaluated only at clip-change time. The diff adds no handling for the device becoming locked after an overlay is already displayed, and the visible code does not show such a path.",
      "The toast path is still taken when locked (if shouldShowToast permits), so a 'copied' toast can still appear while locked. Only the interactive overlay is blocked."
     ],
     "behavior_changes": [
      "When the device is locked (credential required) and something is copied, SystemUI shows only the copied toast (CLIPBOARD_TOAST_SHOWN event) instead of the interactive clipboard overlay.",
      "The ClipboardListener constructor signature changes (adds KeyguardManager), which affects dependency injection and any direct instantiation, such as tests."
     ],
     "preconditions": [
      "The device is locked in the sense of KeyguardManager.isDeviceLocked() (PIN/password/biometric required), per the commit message.",
      "A primary clip change is delivered to SystemUI's ClipboardListener (a CoreStartable) while in that state, with user setup complete and non-empty ClipData. The exact situation that makes this possible is described only in the referenced bug (b/317048495)."
     ],
     "per_major": {
      "14": "same fix: commit 70eb75df7d34 in android-security-14.0.0_r15 (cherry-pick of 2976ca86d5c5); patched region fully present (8/8 lines) at android-security-14.0.0_r29.",
      "15": "not affected per bulletin; the patched region lines are present (8/8) at android-security-15.0.0_r17.",
      "16": "not affected per bulletin; patched region present (8/8 lines) at android-security-16.0.0_r8.",
      "17": "not affected per bulletin; patched region present (8/8 lines) at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "The fix adds a constructor-injected KeyguardManager, so the target branch's SystemUI Dagger graph must be able to provide KeyguardManager (SystemUI normally exposes framework system services through its FrameworkServicesModule) (general platform knowledge). Any tests or other code that construct ClipboardListener directly must be updated to the new signature, as ClipboardListenerTest was."
     ],
     "confidence": "high",
     "unknowns": [
      "The concrete situation in which clipboard UI could be entered while locked (referenced bug b/317048495) is not described in the material.",
      "The bulletin lists Android 13 as affected, but no Android 13 fix commit, branch status or code is provided, so whether the change applies unchanged there is not shown.",
      "Behavior if the device locks while an overlay is already showing is not visible in the provided code."
     ],
     "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-43767": {
     "cve": "CVE-2024-43767",
     "summary": "Adds a check in SkBlurMF.cpp prepare_to_draw_into_mask() so it returns false when SkMask::computeImageSize() returns 0 (the size overflow signal, per the commit title), so no SkMask image is allocated with that size.",
     "component": "platform/external/skia, core blur mask filter (src/core/SkBlurMF.cpp)",
     "weakness": "missing size/overflow check before buffer allocation (integer overflow in the mask size computation, per commit title)",
     "root_cause": "prepare_to_draw_into_mask() sets mask->fBounds from bounds.roundOut(), sets fRowBytes = SkAlign4(width) and fFormat = kA8_Format, then calls mask->computeImageSize() and passes the result straight to SkMask::AllocImage(), checking only for a nullptr return. The commit title (\"Check for size overflow before allocating SkMask data\") and the added size == 0 check indicate that computeImageSize() returns 0 when the size overflows, and the code did not test for this. The caller draw_rrect_into_mask() then installs the mask pixels into an SkBitmap and draws into it with an SkCanvas positioned by mask->fBounds. The authors describe the fix as speculative and the issue as not reproducible.",
     "fix_analysis": [
      "src/core/SkBlurMF.cpp:prepare_to_draw_into_mask(): the fix inserts `if (size == 0) { return false; }` after `const size_t size = mask->computeImageSize();` and before `SkMask::AllocImage(size, SkMask::kZeroInit_Alloc)`.",
      "draw_rrect_into_mask() already returns false when prepare_to_draw_into_mask() fails, so the new early return stops it before installMaskPixels() and canvas drawing.",
      "Single commit with 3 added lines: a RESTRICT AUTOMERGE cherry-pick (Change-Id I74c081a7b849f13194ec7807b7a748d1919c1bb2), reviewed upstream at skia-review 894478."
     ],
     "completeness": [
      "Covers the allocation in prepare_to_draw_into_mask(), which draw_rrect_into_mask() calls. The FIXME comment says draw_rrect_into_mask duplicates code in draw_rects_into_mask, but the material does not show whether draw_rects_into_mask uses this helper.",
      "The fix relies on computeImageSize() returning 0 on overflow. It does not validate the fBounds dimensions itself, and the body of computeImageSize() is not in the material.",
      "The commit does not touch SkBlurMask::BoxBlur/BlurRect/BlurRRect (called from filterMask/filterRectMask/filterRRectMask). The material does not show their allocation logic.",
      "The bulletin lists Android 12, 12L and 13 as affected, but the material only shows the Android 14 cherry-pick."
     ],
     "behavior_changes": [
      "prepare_to_draw_into_mask() now returns false whenever computeImageSize() returns 0, and draw_rrect_into_mask() then returns false instead of allocating and drawing. Whether non-overflow cases (such as empty bounds) also produce 0, and how higher-level callers handle the failure, is not shown.",
      "No API change; this is an internal early return."
     ],
     "preconditions": [
      "A blur mask filter (SkBlurMaskFilterImpl) path in SkBlurMF.cpp reaches draw_rrect_into_mask() and prepare_to_draw_into_mask().",
      "The rounded-out bounds must be large enough for the size computation in SkMask::computeImageSize() to overflow (per commit title). The trigger geometry is not shown, and the authors state the issue was not reproducible.",
      "Per index search, only RenderEngine blur tests in frameworks/native (RenderEngineTest.cpp) were found. These are not shown to be callers of this function, so the platform entry points are not established by the material."
     ],
     "per_major": {
      "14": "same fix: RESTRICT AUTOMERGE cherry-pick 796c2040f641 in android-security-14.0.0_r15. At android-security-14.0.0_r29, all 5 lines of the patched region are present.",
      "15": "not affected per bulletin. src/core/SkBlurMF.cpp is absent at android-security-15.0.0_r17.",
      "16": "not affected per bulletin. src/core/SkBlurMF.cpp is absent at android-security-16.0.0_r8.",
      "17": "not affected per bulletin. src/core/SkBlurMF.cpp is absent at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Self-contained 3-line change with no dependencies shown. It applies where prepare_to_draw_into_mask() in src/core/SkBlurMF.cpp has the computeImageSize() then AllocImage() sequence.",
      "external/skia is not a mainline module and ships with the platform image, so the fix must be in the device build (general platform knowledge)."
     ],
     "confidence": "medium",
     "unknowns": [
      "The implementations of SkMask::computeImageSize() and SkMask::AllocImage() are not in the material. That computeImageSize() returns 0 on overflow is inferred from the commit title and the check, not shown.",
      "Whether draw_rects_into_mask() also uses prepare_to_draw_into_mask() is not shown.",
      "Which Android-side callers (e.g. HWUI/RenderEngine blur paths) reach this path with attacker-influenced geometry is not shown.",
      "Whether and how the fix was applied to Android 12, 12L and 13, and what the code looks like there, is not in the material.",
      "The commit states the issue was not reproducible and the fix is speculative. The concrete memory-safety consequence is not demonstrated in the material.",
      "The reason SkBlurMF.cpp is absent on Android 15 and later is not shown."
     ],
     "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-43768": {
     "cve": "CVE-2024-43768",
     "summary": "Adds an integer-overflow bounds check to Skia's zlib allocator callback skia_alloc_func in src/pdf/SkDeflate.cpp so that nullptr is returned when items * size would not fit in size_t, instead of passing a wrapped-around size to sk_calloc_throw.",
     "component": "platform/external/skia, PDF backend (src/pdf/SkDeflate.cpp, zlib allocator callback skia_alloc_func)",
     "weakness": "Integer overflow in allocation size computation (missing bounds check on multiplication)",
     "root_cause": "skia_alloc_func<T>(void*, T items, T size), the zlib allocator callback in src/pdf/SkDeflate.cpp, computed SkToSizeT(items) * SkToSizeT(size) and passed the product straight to sk_calloc_throw. Nothing checked that size fits in size_t or that items * size fits in size_t, so an overflowing product could wrap and request a smaller allocation than requested.",
     "fix_analysis": [
      "src/pdf/SkDeflate.cpp:skia_alloc_func: first checks SkTFitsIn<size_t>(size) and returns nullptr if size does not fit in size_t (relevant when zlib's T is wider than size_t).",
      "src/pdf/SkDeflate.cpp:skia_alloc_func: computes maxItems = SIZE_MAX / size and returns nullptr if maxItems < items, i.e. if items * size would overflow size_t. Only then does it call sk_calloc_throw(SkToSizeT(items) * SkToSizeT(size)).",
      "Adds #include \"include/private/base/SkTFitsIn.h\" for SkTFitsIn; the commit message notes the only cherry-pick conflict was in the header includes."
     ],
     "completeness": [
      "Covers the single multiplication in skia_alloc_func, the only allocation site in the diff; skia_free_func is unchanged.",
      "The new code divides SIZE_MAX by size without first checking size != 0; the material does not show whether zlib can call the allocator with size 0, so this is noted only as a code observation.",
      "The check does not separately verify that items fits in size_t; it relies on the comparison maxItems < items (performed in the wider of the two types) to reject oversize items before SkToSizeT(items) is evaluated.",
      "No other zlib allocator callbacks within skia are shown in the material."
     ],
     "behavior_changes": [
      "Allocation requests from zlib whose items*size would overflow size_t (or whose size does not fit in size_t) now receive nullptr from skia_alloc_func instead of a wrapped-around, too-small allocation.",
      "For non-overflowing requests behavior is unchanged (sk_calloc_throw of the exact product)."
     ],
     "preconditions": [
      "Code path: Skia's PDF backend deflate code in src/pdf/SkDeflate.cpp, where skia_alloc_func serves as the zlib allocator callback.",
      "zlib must invoke the allocator with items and size whose product exceeds size_t range (or with size exceeding size_t when T is wider); how those parameters are influenced is not shown in the material."
     ],
     "per_major": {
      "14": "same fix: b5543cb8c6b9 in android-security-14.0.0_r15 (reviewed on skia-review 888996, cherry-picked from googleplex commit 4ac6d5834d4d...), with a conflict only in the header includes of src/pdf/SkDeflate.cpp; at android-security-14.0.0_r29 all 8/8 patched lines are present.",
      "15": "not affected per the bulletin; the patched region (8/8 lines) is present at android-security-15.0.0_r17.",
      "16": "not affected per the bulletin; the patched region (8/8 lines) is present at android-security-16.0.0_r8.",
      "17": "not affected per the bulletin; the patched region (8/8 lines) is present at android-security-17.0.0_r1."
     },
     "backport_notes": [
      "Single-commit, 8-line change confined to skia_alloc_func plus one include; the only merge friction reported was the include block. The fix depends on SkTFitsIn being available.",
      "No fork comparison was provided in the material, so no per-file fork verdict can be reported."
     ],
     "confidence": "high",
     "unknowns": [
      "How the overflowing items/size values are reached from untrusted input (which PDF generation API or content) is not shown.",
      "How zlib and SkDeflateWStream handle a nullptr return from the allocator, and how an undersized buffer would have been used before the fix, are not shown.",
      "Whether zlib can ever call the allocator with size == 0 (which would make SIZE_MAX / size a division by zero) is not shown.",
      "Whether SkTFitsIn.h lives at include/private/base/SkTFitsIn.h in older Skia snapshots is not shown; backports may need to check the include path.",
      "The bulletin lists Android 12, 12L and 13 as affected, but the material only provides the Android 14 commit; the commits for 12/12L/13 are 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-43769": {
     "cve": "CVE-2024-43769",
     "summary": "Reworks PackageManagerService.isPackageDeviceAdmin so the device management role holder (DMRH) counts as an admin only on users that are organization-managed. When the DMRH is a system package, it is treated as an admin on all users whenever any user is both managed and has it as role holder. Per the commit comment, this addresses 'uninstall updates' on an unmanaged user breaking management on other users.",
     "component": "platform/frameworks/base, PackageManagerService (device admin / DMRH check used for package protection)",
     "weakness": "incomplete authorization check (DMRH protection evaluated only on the target user and without checking whether the user is organization-managed)",
     "root_cause": "In services/core/java/com/android/server/pm/PackageManagerService.java, isPackageDeviceAdmin(packageName, userId) checks whether a package counts as a device admin. For a specific userId it looped over that single user only, calling dpm.packageHasActiveAdmins and isDeviceManagementRoleHolder for that user. The DMRH check did not consider whether the user is actually organization-managed. It also did not account for a system package's APK version being shared across all users. Per the commit comment, 'uninstall updates' on an unmanaged user may therefore break management on other users.",
     "fix_analysis": [
      "PackageManagerService.java:isPackageDeviceAdmin: also obtains DevicePolicyManagerInternal via mInjector.getLocalService(DevicePolicyManagerInternal.class) and requires both dpm != null and dpmi != null before running the checks.",
      "PackageManagerService.java:isPackageDeviceAdmin: splits the user loop. The active-device-admin check (dpm.packageHasActiveAdmins) still runs over targetUsers (all users for USER_ALL, otherwise the single userId).",
      "PackageManagerService.java:isPackageDeviceAdmin: the DMRH check moves into a separate loop. It looks up the package via snapshotComputer().getPackageStateInternal(packageName) and returns false if the state is null. If packageState.isSystem() is true it iterates over allUsers (mUserManager.getUserIds()), otherwise over targetUsers. For each user it returns true only if isDeviceManagementRoleHolder(packageName, user) AND dpmi.isUserOrganizationManaged(user).",
      "Net effect: a system DMRH counts as an admin on every user as long as some user is organization-managed and has it as role holder. A DMRH on a user that is not organization-managed no longer counts as an admin (commit title: allow uninstalling DMRH when not used for management)."
     ],
     "completeness": [
      "The change works in both directions inside isPackageDeviceAdmin. It tightens protection of a system DMRH across users (shared APK) and loosens protection for a DMRH on users that are not managed.",
      "Only system packages (packageState.isSystem()) get the all-users DMRH scan. A non-system DMRH is still checked only on targetUsers, which matches the shared-APK reasoning in the commit comment.",
      "The device-owner/profile-owner checks earlier in the function (dpm.getDeviceOwnerComponent and the lines after it) are not changed by the diff.",
      "This commit does not change the callers of isPackageDeviceAdmin, and the material does not show them. Whether every uninstall-like path calls this function cannot be judged from the material.",
      "An existing code comment, TODO(b/261957226), asks for this logic to be centralised in DPM. This fix keeps the logic in PackageManagerService."
     ],
     "behavior_changes": [
      "A package that is DMRH on a user that is not organization-managed is no longer reported as a device admin (commit title: allow uninstalling DMRH when not used for management).",
      "A system package that is DMRH on an organization-managed user is now reported as a device admin for every user, including unmanaged ones.",
      "If the DevicePolicyManagerInternal local service is unavailable, the admin/DMRH checks are skipped (before, only dpm != null was required).",
      "If the package has no PackageStateInternal in the snapshot, the function returns false after the active-admin loop.",
      "Each call now also runs mUserManager.getUserIds() and a snapshot package-state lookup, even for a single-user query."
     ],
     "preconditions": [
      "A code path that calls isPackageDeviceAdmin for a package and a specific user (presumably uninstall; the callers are not shown in the material).",
      "A DMRH package that is a system package and is role holder on an organization-managed user, plus another user that is not organization-managed (per the commit comment).",
      "IDevicePolicyManager and DevicePolicyManagerInternal must both be available for the checks to run."
     ],
     "per_major": {
      "14": "same fix: commit 619ffc299bf3 is in android-security-14.0.0_r15; at android-security-14.0.0_r29 all 8 of 8 lines of the patched region are present.",
      "15": "not affected: not listed by the bulletin; at android-security-15.0.0_r17 all 8 of 8 lines of the patched region are present.",
      "16": "not affected: not listed by the bulletin; at android-security-16.0.0_r8, 7 of 8 lines of the patched region are present.",
      "17": "not affected: not listed by the bulletin; at android-security-17.0.0_r1, 7 of 8 lines of the patched region are present."
     },
     "backport_notes": [
      "Single-file, single-function change. It depends on DevicePolicyManagerInternal.isUserOrganizationManaged(int), mInjector.getLocalService, snapshotComputer().getPackageStateInternal and PackageStateInternal.isSystem() existing on the target branch. Check these before porting to older branches such as 13, which the bulletin also lists as affected.",
      "The commit references the test DevicePolicyManagementRoleHolderTest (a.d.c.), which is not part of this diff."
     ],
     "confidence": "medium",
     "unknowns": [
      "The exact trigger and the privilege gained (the bulletin only states High EoP; the commit comment describes 'uninstall updates' on an unmanaged user breaking management on other users).",
      "Which callers of isPackageDeviceAdmin exist and are reachable (index search found no callers), and how they act on its result.",
      "What the function returns when dpm or dpmi is null (code after the if block is not shown).",
      "Content of the Android 13 fix, if any, and the exact 1-line difference in the 16/17 branches."
     ],
     "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."
     }
    }
   }
  },
  "15": {
   "counts": {
    "announced": 0,
    "certain": 0,
    "probable": 0,
    "not_published": 0,
    "not_covered": 0,
    "awaiting": 0
   },
   "advisories": [],
   "tags": [
    "android-security-15.0.0_r3"
   ],
   "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-12-01",
  "latest_version": "1.0",
  "latest_revision": {
   "version": "1.0",
   "date": "December 2, 2024",
   "notes": "Bulletin Published"
  },
  "revisions": [
   {
    "version": "1.0",
    "date": "December 2, 2024",
    "notes": "Bulletin Published"
   }
  ],
  "tracked_since": "2026-09-30",
  "changes_since_tracking": [],
  "out_of_scope_rows": {
   "Imagination Technologies": 2,
   "MediaTek components": 1,
   "Qualcomm closed-source components": 4,
   "Qualcomm components": 1
  },
  "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."
 }
}