CVE-2025-48556 AI-generated analysis
platform/frameworks/base, core/java/android/app/NotificationChannel (notification framework)
NotificationChannel.setId() and setConversationId() now pass their string arguments through the existing getTrimmedString() helper so mId, mParentId and mConversationId are capped at MAX_TEXT_LENGTH instead of being stored unbounded.
Root cause
NotificationChannel already limits some text fields to MAX_TEXT_LENGTH: setDescription uses getTrimmedString(), and an existing parcel round-trip test (NotificationChannelTest lines 204-215) shows that an unparceled channel has id, name, description, parent id, group and conversation id bounded to MAX_TEXT_LENGTH. The setters setId(String) (@hide) and setConversationId(String parentChannelId, String conversationId) assigned their arguments directly to mId, mParentId and mConversationId, so a channel built or mutated through these setters could hold ids longer than MAX_TEXT_LENGTH. The bulletin rates the issue as a High-severity EoP; the material does not show the concrete downstream consequence of the oversized ids.
How the fix works
- core/java/android/app/NotificationChannel.java:setId - `mId = id;` becomes `mId = getTrimmedString(id);`, truncating ids longer than MAX_TEXT_LENGTH to their first MAX_TEXT_LENGTH characters (null passes through unchanged).
- core/java/android/app/NotificationChannel.java:setConversationId - `mParentId = parentChannelId;` and `mConversationId = conversationId;` become `getTrimmedString(parentChannelId)` / `getTrimmedString(conversationId)`, applying the same cap to both conversation fields.
- core/tests/coretests/src/android/app/NotificationChannelTest.java - adds testSetId_longStringIsTrimmed and testSetConversationId_longStringsAreTrimmed, each feeding MAX_TEXT_LENGTH + 10 character strings and asserting the getters return exactly the first MAX_TEXT_LENGTH characters.
- No new helper is introduced; the fix reuses the private getTrimmedString(String) already present (lines 556-561 in the r17 context, used by setDescription at line 553).
Completeness
- Covers the three fields reachable through setId and setConversationId (mId, mParentId, mConversationId).
- setGroup(String groupId) in the same class still assigns `this.mGroup = groupId;` without getTrimmedString (r17 context lines 601-603); group is shown bounded only after a parcel round trip, so the setter path for the group id is left as it was.
- The fix truncates rather than rejects: an oversized id silently becomes a shorter id, with no error to the caller.
Behavior changes
- setId() and setConversationId() silently truncate arguments longer than MAX_TEXT_LENGTH; getId(), getParentChannelId() and getConversationId() then return the truncated value rather than the string the caller supplied.
- Two ids that differ only beyond MAX_TEXT_LENGTH now collapse to the same stored id when set through these setters.
- No new exceptions or error codes; null input is returned as is by getTrimmedString.
Per major
- Android 14: not affected (not listed by the bulletin); no fix commit linked; android-security-14.0.0_r29 shows 7/8 lines of the patched region
- Android 15: same fix: platform/frameworks/base fc5d9b6ef530 in android-security-15.0.0_r10 (cherry-pick of a9a1b4365b8d, Change-Id Id721d3123ee8d38753f550fe57ba0f5d15d743ac); patched region present at android-security-15.0.0_r17
- Android 16: same fix: platform/frameworks/base 0da1ac9dda56 in android-security-16.0.0_r1, identical hunks with different line offsets (setId at ~650, setConversationId at ~894); patched region present at android-security-16.0.0_r8
- Android 17: not affected (not listed by the bulletin); android-security-17.0.0_r1 shows 7/8 lines of the patched region
Unknowns
- Which caller path consumed the untrimmed mId/mParentId/mConversationId and how an oversized id led to the EoP described by the bulletin; the material only shows the setter-level fix.
- Why Android 14 is listed as not affected even though the patched region largely matches there; the per-major data does not show a 14 commit.
- Who calls setId and setConversationId in practice; no relevant callers were surfaced by the index search.
- Whether parcel-path trimming of these fields happens in the Parcel constructor or in writeToParcel.