Unbounded TaskInfo serialization in ActivityTaskManagerService

Saturday, September 26, 2026
Unbounded TaskInfo serialization in ActivityTaskManagerService

Unbounded TaskInfo serialization in ActivityTaskManagerService leads to persistent-process (SystemUI) crash loop and device-level denial of service

Reporter: Manuel García Peña ("lostmon") — independent security researcher

Contact: lostmon.blogspot.com

Project reference: STA Research (Structured Text Amplification)

Date: 20 September 2026

Component: Android Open Source Project — frameworks/base (ActivityTaskManagerService, Task, TaskOrganizerController, TaskInfo)

Affected versions: Confirmed on Android 16 (device build below); the root cause traces to a serialization path that has been present, in incomplete form, since at least the March 2020 commit referenced in §5 — likely affects a broad range of Android versions. Requires confirmation by Google against the AOSP version matrix.

Test device: Redmi Note 14 5G (citrine_eea_global), build BP2A.250605.031.A3 / HyperOS 3.0 (OS3.0.302.0.WOQEUXM), Android 16.


This report is the Nth instance in the STA (Structured Text Amplification) series, a four-year line of research documenting a recurring class of defect in AOSP and adjacent systems: unbounded serialization or amplification of user-influenceable, variable-size fields across a translation boundary, followed by exhaustion of a downstream resource. Prior STA instances in AOSP include STA-015 (RecentTasksController/SystemUI) and STA-015-DL (SystemUI via Google Drive → browser → TaskPersister), both of which share the same root cause family as the present case: an oversized Task-related object crossing Binder into a persistent platform process. The present defect should therefore be read not as an isolated bug in Task.fillTaskInfo(), but as further evidence that AOSP's parcel/serialization model does not impose a default upper bound on attacker-influenceable fields. The remediation in §8 is formulated accordingly: a point fix for TaskInfo, and a structural proposal for frameworks/base.


1. Summary

Task.fillTaskInfo() serializes a Task's Intent data Uri and capturedLink field into TaskInfo/RootTaskInfo/RunningTaskInfo/RecentTaskInfo without any upper bound on size. This object is transferred over Binder both when the platform pushes task-organizer callbacks (ITaskOrganizer.onTaskInfoChanged, addStartingWindow) and when a client pulls task state (getFocusedRootTaskInfo, getTasks, getRecentTasks). When the underlying Intent/link data is large enough, the resulting Binder transaction exceeds the transaction buffer and fails with TransactionTooLargeException (push direction) or leaves the caller in a state where subsequent reads fail with DeadObjectException/DeadSystemException (pull direction, once system_server itself becomes unable to service the request).

SystemUI, a platform-critical, persistent process, does not degrade gracefully when these calls fail. The uncaught/unhandled exception propagates up through multiple independent SystemUI components that all query "current focused task" or "recent tasks," causing SystemUI to be killed and restarted repeatedly by ActivityManagerService ("Process com.android.systemui has crashed too many times, killing!"), which in turn triggers the platform's RescueParty self-healing subsystem through an escalating series of mitigations. Depending on how many times the trigger repeats, the outcome ranges from a forced device reboot to an OEM-level "safe mode" recovery requiring manual user intervention.

This is reachable with a single user tap on a link that opens in the default browser — no special permissions, no user interaction beyond a single tap, fully reproducible.


2. Affected code paths (AOSP frameworks/base)

PathDirectionAPI
services/core/java/com/android/server/wm/TaskOrganizerController.javaPushITaskOrganizer.onTaskInfoChanged, addStartingWindow
services/core/java/com/android/server/wm/ActivityTaskManagerService.javaPullgetFocusedRootTaskInfo
core/java/android/app/ActivityTaskManager.javaPullgetTasks, getRecentTasks
services/core/java/com/android/server/wm/Task.javaShared serialization pointfillTaskInfo(), trimIneffectiveInfo()
core/java/android/app/TaskInfo.javaShared serialization pointwriteTaskToParcel(), field capturedLink

All five paths converge on Task.fillTaskInfo(), which is the single point where the defect should be fixed.


3. Root cause

3.1 Task.fillTaskInfo() does not bound the Intent data Uri or capturedLink

void fillTaskInfo(TaskInfo info, boolean stripExtras, @Nullable TaskDisplayArea tda) {
    ...
    final Intent baseIntent = getBaseIntent();
    final int baseIntentFlags = baseIntent == null ? 0 : baseIntent.getFlags();
    info.baseIntent = baseIntent == null
            ? new Intent()
            : stripExtras ? baseIntent.cloneFilter() : new Intent(baseIntent);
    info.baseIntent.setFlags(baseIntentFlags);
    ...
    // capturedLink is not cleared or bounded here; it is only nulled in
    // trimIneffectiveInfo() for non-privileged callers.
}

3.2 The 2020 mitigation is incomplete — verified against source

Commit 66b08f0201877e6013058fda2f0263016338c770 ("Reduce parceled data size between system & sysui", Winson Chung, 3 March 2020, Bug: 150242007) changed:

- info.baseIntent = baseIntent == null ? new Intent() : new Intent(baseIntent);
+ info.baseIntent = baseIntent == null ? new Intent() : baseIntent.cloneFilter();

This removes Bundle extras and ClipData from the serialized baseIntent. It does not bound:

  • the Intent's data Uri (cloneFilter() explicitly preserves action, data, type, categories, flags, package, component);
  • the capturedLink field, which is a separate TaskInfo field entirely untouched by this commit and only cleared in trimIneffectiveInfo() for non-privileged callers — SystemUI and TaskOrganizer receive it unfiltered.

The test added in the same commit, testTaskInfo_expectNoExtras, only asserts that baseIntent.getExtras() is null/empty — it does not assert any bound on data-field length.

3.3 TaskInfo.writeTaskToParcel() has no length limit on variable-size fields

dest.writeTypedObject(baseIntent, 0);       // data Uri, post-cloneFilter, unbounded
dest.writeTypedObject(capturedLink, flags); // full Uri when not trimmed, unbounded

3.3 trimIneffectiveInfo() clears capturedLink only for non-privileged callers

info.capturedLink = null;
info.capturedLinkTimestamp = 0;

This clearing is applied only when the caller is not privileged. SystemUI and TaskOrganizer — precisely the components affected by this defect — are privileged callers and receive capturedLink unfiltered.

3.4 TaskInfo.writeTaskToParcel() has no length limit on variable-size fields

dest.writeTypedObject(baseIntent, 0);       // data Uri, post-cloneFilter, unbounded
dest.writeTypedObject(capturedLink, flags); // full Uri when not trimmed, unbounded

RootTaskInfo adds fixed-size bounds/children fields and then delegates the rest to the same writeTaskToParcel().

3.5 Confluence of push and pull paths

                    ├─ onTaskInfoChanged / addStartingWindow   (push, §5.1)
Task.fillTaskInfo ──┼─ getFocusedRootTaskInfo                  (pull, §5.2, variants A/B)
                    ├─ getTasks                                (pull, §5.2, variant C)
                    └─ getRecentTasks                          (pull, §5.2, variant E)

This explains why five structurally distinct SystemUI call sites (different classes, different threads, different public APIs) all fail with the same root cause: every one of them ultimately calls Task.fillTaskInfo()/writeTaskToParcel() on the same oversized Task object.

3.6 SystemUI does not degrade gracefully on ATMS binder failure

Independently of the above, the Binder client side of this contract — SystemUI's various components that call getFocusedRootTaskInfo/getTasks/getRecentTasks — does not catch DeadObjectException/DeadSystemException and fall back to a last-known-good state or a safe default. The exception propagates and crashes the calling component, and because these components (Dynamic Island top-activity tracking, notification shade token interactor, recents controller) are on SystemUI's main/critical threads, repeated failures cause ActivityManagerService to conclude the persistent process is unrecoverable and kill it outright.


4. Reproduction

  1. Construct an Intent/link whose data Uri (and/or any field that populates TaskInfo.capturedLink) is large — on the order of hundreds of kilobytes. In our reproduction this was delivered as a link inside an HTML document opened via a cloud-storage viewer, which the OS resolved to the default browser (Firefox, in our test — confirmed not to be the origin of the fault; see §7).
  2. The browser is launched as a new Task; system_server/ATMS retains this oversized data as part of the Task's baseIntent/captured-link state.
  3. As TaskOrganizerController dispatches pending task-info-changed / starting-window events for this task, and/or as SystemUI's focus/recents observers poll getFocusedRootTaskInfo/getTasks/getRecentTasks, the oversized TaskInfo is serialized to Binder.
  4. Observe TransactionTooLargeException (push) and/or DeadObjectException/DeadSystemException (pull) in dumpsys dropbox -p system_app_crash and/or logcat.
  5. Repeat exposure (re-opening the link while the browser remains foregrounded) escalates the failure into a sustained SystemUI crash loop.

We can provide the full sequence of bugreports (adb bugreport, 4 captures across 2 dates on the same device/build) documenting both directions with complete stack traces on request through the appropriate secure channel. We are withholding the exact payload construction from this initial report per responsible-disclosure practice; happy to share it privately with the assigned engineer.


5. Evidence (redacted stack excerpts)

5.1 Push — TransactionTooLargeException, kernel-confirmed (16-09-2026, 11:26–11:28, same device)

TaskOrganizerController: android.os.TransactionTooLargeException: data parcel size 365036 bytes
    at android.window.ITaskOrganizer$Stub$Proxy.onTaskInfoChanged(ITaskOrganizer.java:513)
    at com.android.server.wm.TaskOrganizerController$TaskOrganizerCallbacks.onTaskInfoChanged(TaskOrganizerController.java:191)
    ...
    at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:923)
    at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:173)

Kernel binder driver, independently confirming the same failure:

binder: 2124:3180 transaction async to 20444:0 failed 7086360/29201/-28, code 1 size 365788-48 line 3548
binder: 2124:2173 transaction async to 20444:0 failed 7086449/29201/-28, code 7 size 365036-40 line 3548

ActivityManager log line for the same event: pid 2124 system sent binder code 7 with flags 1 to frozen apps and got error -2147483646 — the target process (SystemUI) was in the platform's cached/frozen state at time of delivery, which appears to aggravate the failure.

5.2 Pull — complete evidence set: 25 recorded instances across 3 sessions, 5 distinct call sites

All 25 instances were extracted from dumpsys dropbox -p system_app_crash across three independent bugreports on the same device/build (19–20 September 2026). Every instance shares the same two root exceptions (DeadObjectException or DeadSystemException); they differ only in which SystemUI component happened to be polling task state at the moment system_server/ATMS became unable to service the request.

Frequency by call site:

VariantComponentAPIInstances
Ccom.android.systemui.shared.system.ActivityManagerWrapper.getRunningTask (via com.miui.systemui.functions.MiuiTopActivityObserver)getTasks12
Acom.android.systemui.statusbar.notification.policy.DynamicIslandTopActivityControllergetFocusedRootTaskInfo5
Bcom.miui.systemui.statusbar.shade.domain.interactor.ShadeStatusBarTokenInteractorgetFocusedRootTaskInfo5
Dcom.android.systemui.statusbar.notification.InstantAppNotifier(stack truncated by system, root cause DeadSystemException)2
Ecom.android.wm.shell.recents.RecentTasksController.getRecentTasksgetRecentTasks1

Complete timestamped log (25/25 instances, PID and exception type):

2026-09-19 23:32:04  PID 2858   DeadObjectException      Variant A
2026-09-19 23:39:14  PID 21592  DeadSystemException       Variant D
2026-09-19 23:39:28  PID 29332  DeadSystemException       Variant C
2026-09-19 23:39:40  PID 29982  DeadObjectException       Variant B
2026-09-19 23:39:49  PID 30266  DeadSystemException       Variant D
2026-09-19 23:39:56  PID 30579  DeadSystemException       Variant C
2026-09-19 23:42:14  PID 5351   DeadSystemException       Variant C
2026-09-20 00:25:16  PID 2847   DeadSystemException       Variant D
2026-09-20 00:25:24  PID 29311  DeadSystemException       Variant C
2026-09-20 00:25:30  PID 29616  DeadSystemException       Variant C
2026-09-20 00:25:33  PID 29806  DeadSystemException       Variant C
2026-09-20 00:25:39  PID 29952  DeadSystemException       Variant C
2026-09-20 00:25:46  PID 30137  DeadSystemException       Variant C
2026-09-20 14:10:27  PID 2558   DeadObjectException       Variant B
2026-09-20 14:10:44  PID 22995  DeadObjectException       Variant A
2026-09-20 14:10:47  PID 23667  DeadSystemException       Variant C
2026-09-20 14:10:55  PID 24079  DeadSystemException       Variant C
2026-09-20 14:11:09  PID 24700  DeadObjectException       Variant A
2026-09-20 14:11:20  PID 25138  DeadObjectException       Variant B
2026-09-20 14:32:12  PID 26950  DeadObjectException       Variant B
2026-09-20 14:32:28  PID 6263   DeadObjectException       Variant B
2026-09-20 14:32:31  PID 6809   DeadSystemException       Variant C
2026-09-20 14:32:46  PID 6983   DeadObjectException       Variant A
2026-09-20 14:32:52  PID 7317   DeadSystemException       Variant C
2026-09-20 14:33:01  PID 7535   DeadSystemException       Variant E

Entry #25 (14:33:01, RecentTasksController.getRecentTasks) is the last crash of the entire sequence, immediately before the device stabilized — the fault is not limited to "resolve current focus," it extends to enumerating the recent-tasks list in general, which we consider additional evidence that the defect is in the shared Task/TaskInfo state rather than in any single SystemUI component's handling of it.

Full stack — Variant A (DynamicIslandTopActivityController):

android.os.DeadObjectException: Transaction failed on small parcel; remote process
probably died, but this could also be caused by running out of binder buffer space
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(BinderProxy.java:736)
    at android.app.IActivityTaskManager$Stub$Proxy.getFocusedRootTaskInfo(IActivityTaskManager.java:3682)
    at com.android.systemui.statusbar.notification.policy.DynamicIslandTopActivityController
        $special$$inlined$mapNotNull$1$2.emit(...)
    at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(...)

Full stack — Variant B (ShadeStatusBarTokenInteractor):

android.os.DeadObjectException: Transaction failed on small parcel; remote process
probably died, but this could also be caused by running out of binder buffer space
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(BinderProxy.java:736)
    at android.app.IActivityTaskManager$Stub$Proxy.getFocusedRootTaskInfo(IActivityTaskManager.java:3682)
    at com.miui.systemui.statusbar.shade.domain.interactor.ShadeStatusBarTokenInteractor
        $special$$inlined$mapNotNull$1$2.emit(go/retraceme...:62)
    at com.miui.systemui.statusbar.shade.domain.interactor.ShadeStatusBarTokenInteractor
        $special$$inlined$filter$1$2.emit(go/retraceme...:64)
    at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(go/retraceme...:194)

Full stack — Variant C (ActivityManagerWrapper.getRunningTask, the most frequent — 12/25):

android.os.DeadSystemRuntimeException: android.os.DeadSystemException
    at android.app.ActivityTaskManager.getTasks(ActivityTaskManager.java:480)
    at android.app.ActivityTaskManager.getTasks(ActivityTaskManager.java:454)
    at com.android.systemui.shared.system.ActivityManagerWrapper.getRunningTask(...:5)
    at com.miui.systemui.functions.MiuiTopActivityObserver$$ExternalSyntheticLambda0.run(...:71)
    at android.os.Handler.handleCallback(Handler.java:1029)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loopOnce(Looper.java:274)
    at android.os.Looper.loop(Looper.java:369)
    at android.os.HandlerThread.run(HandlerThread.java:85)
Caused by: android.os.DeadSystemException
    ... 9 more

Full stack — Variant D (InstantAppNotifier):

android.os.DeadSystemRuntimeException: android.os.DeadSystemException
    at com.android.systemui.statusbar.notification.InstantAppNotifier$$ExternalSyntheticLambda0.run(...:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1100)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:1572)
Caused by: android.os.DeadSystemException
    ... 4 more

Full stack — Variant E (RecentTasksController.getRecentTasks, the final crash of the sequence):

android.os.DeadSystemRuntimeException: android.os.DeadSystemException
    at android.app.ActivityTaskManager.getRecentTasks(ActivityTaskManager.java:539)
    at com.android.wm.shell.recents.RecentTasksController.getRecentTasks(...:10)
    at com.android.wm.shell.recents.RecentTasksController$IRecentTasksImpl$$ExternalSyntheticLambda1.accept(...:11)
    at com.android.wm.shell.common.ExternalInterfaceBinder$$ExternalSyntheticLambda0.run(...:18)
    at com.android.wm.shell.common.ShellExecutor$$ExternalSyntheticLambda0.run(...:5)
    at android.os.Handler.handleCallback(Handler.java:1029)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loopOnce(Looper.java:274)
    at android.os.Looper.loop(Looper.java:369)
    at android.os.HandlerThread.run(HandlerThread.java:85)
Caused by: android.os.DeadSystemException
    ... 10 more

5.3 Terminating action (ActivityManagerService)

Captured live during the 20-09-2026 14:32 reproduction:

14:32:52.874  ActivityManager: Process com.android.systemui has crashed too many times, killing! Reason: crashed quickly
14:32:52.874  RescueParty: Checking available remediations for health check failure. failedPackage: com.android.systemui failureReason: 3 available impact: 50
14:32:52.884  RescueParty: Executing remediation. failedPackage: com.android.systemui failureReason: 3 mitigationCount: 3

RollbackPackageHealthObserver reports available impact: 0 for the same event — no Mainline/APEX rollback candidate exists for com.android.systemui on this build, so the platform's self-healing falls through entirely to the OEM's own escalation logic (documented in the companion Xiaomi report).


6. Impact

  • Class: Denial of service, platform-level.
  • User interaction: One tap on an attacker-controlled or attacker-influenced link.
  • Privileges required: None.
  • Effect: Forced lockscreen, sustained SystemUI crash loop, and — depending on repeat exposure — full device reboot or entry into an OEM-defined degraded/safe-mode recovery state requiring the user to manually restart the device. No code execution is claimed.
  • Reliability: Deterministic across 25/25 observed crash instances in our testing; consistent across two dates four days apart on the same build.

7. Note on browser involvement

We initially suspected the browser itself (Chrome) was implicated, based on a temporally-adjacent ANR in our first capture. On closer inspection of the activity-resume records across all sessions, the browser that actually receives the triggering intent in every case is Firefox (org.mozilla.fenix.IntentReceiverActivity). Firefox shows no crash, ANR, or tombstone of its own in any of the four bugreports we collected — it is the intent receiver, not a party to the defect. We flag this so the assigned engineer does not spend time chasing a red herring; the defect is entirely within the ATMS/SystemUI Binder contract described above.


8. Suggested remediation

  1. Introduce a length bound on the Intent data Uri and capturedLink in Task.fillTaskInfo() / TaskInfo.writeTaskToParcel() — truncate, hash, or replace with a placeholder above a reasonable threshold before serialization, extending the intent of commit 66b08f0 to cover these two fields.
  2. Have TaskOrganizerController measure/cap the serialized size of a TaskInfo before dispatching push callbacks, rather than relying on the caller to catch TransactionTooLargeException after the fact.
  3. Harden SystemUI's focus/recents observers (and any similar persistent-process client of these APIs) to catch DeadObjectException/DeadSystemException and fall back to last-known-good state instead of propagating the exception to a crash.

9. Attachments available on request

  • 4 full bugreport captures (device: Redmi Note 14 5G, build BP2A.250605.031.A3), dated 16-09-2026 and 20-09-2026 (×3).
  • Consolidated internal forensic report cross-referencing all four captures against AOSP source.

10. Researcher background

Independent security researcher (handle "lostmon"), President of the BojosXtu association (civic/educational digital-rights work). Blog: lostmon.blogspot.com.

De FileAllInformation a inotify: 19 años de metadatos como frontera desatendida

Thursday, September 24, 2026
De FileAllInformation a inotify: 19 años de metadatos como frontera desatendida
Investigación · Seguridad

De FileAllInformation a inotify: 19 años de metadatos como frontera desatendida

Cómo un desbordamiento de búfer que Microsoft tildó de «no explotable» en 2007 y una fuga de información que la industria llama «by-design» en 2026 son, en realidad, la misma historia contada dos veces.

Análisis técnico CVE-2007-4227 • CVE-2007-5145 • CVE-2025-68788 Lectura ~15 min

Hay fallos que no envejecen: se transforman. Dos investigaciones separadas por casi dos décadas —una de 2007 sobre Windows XP, otra de 2026 sobre Linux, Android, macOS y Windows— apuntan a la misma raíz: los metadatos de archivos son una frontera de seguridad que seguimos tratando como si fuera inocua. Y en ambos casos la respuesta del vendor fue esencialmente la misma: no es un problema.

La historia merece contarse completa. Cuando un proveedor decide que algo «no es explotable», no cierra el debate: solo lo pospone hasta que alguien encuentre el ángulo correcto. Diecinueve años después, ese ángulo apareció, y viene con cifras de precisión del 100% sobre SSH y una nominación a los Pwnie Awards por la peor respuesta de vendor del año.


Parte I — 2007: el desbordamiento que Microsoft minimizó

El descubrimiento

En marzo de 2007, el investigador conocido como Lostmon documentó un desbordamiento de búfer local en el Explorador de Windows. El detonante era engañosamente simple: una cadena demasiado larga en los atributos extendidos de un archivo. Campos como Author, Title, Subject o Comment se procesaban en buffers de tamaño fijo, y al desbordarse provocaban el crash del Explorador —y, con él, la pérdida de todo el trabajo no guardado en cualquier aplicación que estuviera consultando esos atributos.

Lo interesante no era el crash en sí, sino dónde ocurría. El análisis con Filemon (Sysinternals) reveló que el fallo no estaba en la interfaz gráfica ni en un parser de documentos, sino en las tripas del sistema de gestión de archivos:

  • GetFileAttributesExW / GetFileAttributesW en KERNEL32
  • NtQueryInformationFile, NtQueryDirectoryFile y NtSetInformationFile en ntdll.dll
  • Subfunciones FileAllInformation() (clase 0x68) y FileNameInformation() (clase 0x08), entre otras de la tabla FILE_INFORMATION_CLASS

La traza de Filemon era inequívoca:

explorer.exe:1700 IRP_MJ_QUERY_INFORMATION C:\...\explorer_overflow.txt\:SummaryInformation:$DATA
    BUFFER OVERFLOW FileAllInformation

El impacto, en palabras del propio investigador, era de «unknown impact»: un crash confirmado, con potencial desconocido. Lo que sí estaba claro era que el vector no requería abrir el archivo malformado —bastaba con abrir la carpeta, pasar el ratón por encima, o incluso borrarlo desde línea de comandos para que el Explorador cayera.

La reproducción paso a paso

El PoC original es tan sencillo que cualquiera puede reproducirlo en un Windows XP sin parchear:

  1. Crear un archivo explorer.txt.
  2. Clic derecho → Propiedades → pestaña Resumen.
  3. Rellenar todos los campos (Author, Title, Subject, Comment) con una cadena larga de «A».
  4. Aceptar y aplicar.
  5. Con Filemon filtrando por explorer.exe, abrir de nuevo las propiedades o pasar el ratón sobre el archivo.
  6. Observar cómo Filemon registra BUFFER OVERFLOW FileAllInformation.

El equivalente programático es igual de simple. Este script VBScript enumera los atributos extendidos de todos los archivos de una carpeta y hace caer al Windows Scripting Host en cuanto toca el atributo número 9 (Author) del archivo malformado:

Dim arrHeaders(35)
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace("C:\test")
For i = 0 to 34
    arrHeaders(i) = objFolder.GetDetailsOf(objFolder.Items, i)
Next
For Each strFileName in objFolder.Items
    For i = 0 to 34
        Wscript.Echo i & vbtab & arrHeaders(i) _
            & ": " & objFolder.GetDetailsOf(strFileName, i)
    Next
Next

Este detalle es importante: el fallo no está en el parser de Word ni de Office. Está en la capa común que consulta metadatos, la que cualquier aplicación de Windows usa cuando quiere mostrar información sobre un archivo.

La respuesta de Microsoft

La cronología del reporte fue la siguiente:

  • 12-03-2007Descubrimiento del fallo.
  • 19-03-2007Notificación privada a Microsoft.
  • 22-03-2007Respuesta del vendor.
  • 17-05-2007Divulgación privada a terceros (Secunia, OSVDB, etc.).
  • 04-06-2007Divulgación pública.

La respuesta textual de Microsoft fue:

«We have concluded our investigations on this matter and have found this crash to be un-exploitable. This vulnerability is very similar to another milworm posting (milw0rm.com/exploits/3419). As we have not been able to find an exploitable angle for this issue this crash will get tracking into the next available Service Pack fix.»

Traducción: no vamos a arreglarlo ahora porque no hemos encontrado cómo explotarlo. En términos de gestión de riesgo, eso es exactamente lo contrario de lo que debería hacerse. «No explotable hoy» no significa «inofensivo»; significa «todavía no hemos encontrado el ángulo».

Detalle que el vendor pasó por alto: el fallo no era exclusivo de documentos de Office. Cualquier programa que usara la API de Windows y ole32.dll para abrir archivos —Notepad++, la familia Macromedia/Adobe y muchos otros— crasheaba al listar la carpeta con el archivo malformado, perdiendo todo el trabajo no guardado. El problema era estructural, no puntual.


Parte II — 2007 (bis): el fallo era estructural, no puntual

Meses después del primer aviso, Lostmon publicó un segundo estudio que demostraba que el problema era sistémico. Analizó exploits públicos para múltiples formatos —WMF (BID 16167), JPG (BID 25207), GIF y DOC— y encontró el mismo patrón en todos:

Mismo punto de crash

Todos caían en FileAllInformation() dentro de ntdll.dll.

Mismo atributo

Todos crasheaban en el atributo número 9, Author.

Mismo disparador

Todos se activaban al consultar los atributos extendidos, no al parsear el contenido.

Mismo alcance

El vector no dependía del formato: bastaba con que el archivo tuviera metadatos malformados.

Es decir: el desbordamiento no vivía en los parsers de imagen o documento, sino en la capa común que consulta metadatos. El PoC EFA_test.vbs lo confirmaba de forma elegante: basta con enumerar las propiedades de los archivos de una carpeta vía Shell.Application para que Windows Scripting Host caiga.

La conclusión de 2007 era cristalina y quedó archivada junto al CVE: el problema no era un formato, era la disciplina de tratar los metadatos como datos de confianza.

Diecinueve años después, esa conclusión resuena con una precisión incómoda.


Parte III — 2026: File Notification Attacks

El paper

En noviembre de 2026, en la conferencia ACM CCS de La Haya, el grupo de la Universidad Técnica de Graz (TU Graz) presentó el paper «File Notification Attacks: Templating and Exploiting Side-Channel Leakage from the File-Notification Systems on Linux, Windows, and macOS», firmado por Sudheendra Raghav Neela, Xufan Zhao, Jeanette Angelika Wultsch, Hannes Weissteiner, Florian Draschbacher, Stefan Gast y Daniel Gruss.

La tesis es un eco directo del hallazgo de 2007. Los subsistemas de notificación de cambios —inotify (Linux, 2005), FileObserver (Android, 2008), ReadDirectoryChangesW (Windows, 2000) y FSEvents (macOS, 2007)— informan a las aplicaciones cuando un archivo se abre, cambia, escribe o borra. No revelan el contenido. Pero el nombre, la existencia y el timing de los cambios son un canal lateral explotable.

Y en Linux y Windows, esa información está disponible incluso sin permiso de lectura sobre los archivos vigilados. Eso es lo que convierte una función de conveniencia en una vulnerabilidad de seguridad.

Linux: el caso de /dev/input

El vector más demoledor es /dev/input. Vigilar ese directorio genera una notificación en cada pulsación de tecla, porque los ficheros de dispositivo son legibles aunque el observador no tenga permisos sobre ellos. De ahí salen dos ataques devastadores:

93,1–100% Precisión de tecleo local

Inter-keystroke timing local sobre siete usuarios distintos.

100% Precisión sobre SSH

Inter-keystroke timing remoto a través de SSH, sin acceso físico.

87,9% Website fingerprinting

Identificación de sitios visitados sobre el top 100.

Wayland UI redress

Ataque de redress sobre el prompt de autenticación de KDE Plasma 6.

La vulnerabilidad recibió el identificador CVE-2025-68788 y fue parcialmente corregida en diciembre de 2025 en los kernels 5.10.248, 5.15.198, 6.1.160, 6.6.120, 6.12.64 y 6.18.3. El parche impide generar eventos access y modify sobre ficheros especiales en /dev/.

Parcialmente, porque el problema de fondo —el modelo de permisos del observador— sigue ahí. El propio paper reconoce que las mitigaciones necesarias van más allá de este parche concreto.

Android: FileObserver atraviesa FUSE

En Android, FileObserver atraviesa la capa FUSE que debería aislar el almacenamiento por aplicación. El resultado, en palabras de Neela:

«FileObserver goes past the FUSE layer meant to isolate per app storage, so a permissionless app can watch (for example) WhatsApp's private folder and see, by filename and timestamp, exactly when photos, videos, and documents are sent, received, or deleted.»

Es decir: una app sin ningún permiso puede vigilar la carpeta privada de otra app y reconstruir, solo con nombres de archivo y timestamps, la actividad completa del usuario: cuándo envía una foto, cuándo recibe un documento, cuándo borra un vídeo. No hace falta leer el contenido; el patrón de eventos es suficiente.

A pesar de la divulgación responsable entre agosto y octubre de 2025, no hay mitigación implementada en Android a día de hoy.

Windows: vigilar C:\ lo revela todo

En Windows el panorama es igual de grave. Vigilar el directorio raíz C:\ reporta la ruta completa de cada archivo tocado en el sistema, de todos los usuarios, con independencia de los permisos. Con esa información se puede hacer, en tiempo real, un ataque de fingerprinting web:

97,8% de precisión identificando qué webs visita otro usuario en Firefox, en tiempo real, solo observando qué ficheros de caché se tocan.

La respuesta de Microsoft a la divulgación fue:

«This is by-design and it's an undocumented feature.»

Esa respuesta fue nominada al premio a la peor respuesta de vendor en los Pwnie Awards 2026. El paralelismo con 2007 —donde Microsoft dijo «un-exploitable»— es tan exacto que duele.

macOS: el caso menos grave (pero no inocuo)

Apple sale mejor parada: no se encontraron bypasses para leer directorios privados. Pero FSEvents sí permite monitorizar cambios en ficheros .plist que revelan información sensible sobre el sistema y el usuario:

  • Cambios en dispositivos de entrada/salida de audio.
  • Cambios en la configuración de energía.
  • Actualizaciones de dispositivos Bluetooth e impresoras.
  • Cambios de DNS iniciados por cable de red.
  • Eventos de montaje y desmontaje de volúmenes.
  • Instalaciones y desinstalaciones de aplicaciones.

No es un canal tan directo como el de Linux o Windows, pero sigue siendo una fuga de información sobre la actividad del usuario y del sistema que un atacante local puede explotar para construir un perfil.


El paralelismo incómodo

Puestos uno al lado del otro, los dos hallazgos son la misma historia contada con 19 años de diferencia:

2007 (CVE-2007-4227 CVE-2007-5145) 2026 (CVE-2025-68788 y familia)
Vector Metadatos extendidos malformados Notificaciones de cambios de archivo
Capa afectada ntdll.dll, FileAllInformation() inotify, FSEvents, ReadDirectoryChangesW, FileObserver
Fallo de fondo Overflow al parsear metadatos Infoleak al notificar metadatos
Asunción errónea Los metadatos son datos de confianza Saber que algo cambió es inofensivo
Alcance Cualquier tipo de archivo con metadatos Todos los SO modernos
Respuesta del vendor «un-exploitable» «by-design, undocumented feature»
Consecuencia Archivado para el siguiente Service Pack Nominación a los Pwnie Awards 2026

La lección de diseño es contundente: validar el tamaño al parsear (2007) y validar el permiso del observador al notificar (2026) son la misma disciplina. Ningún subsistema que hable de ficheros debería asumir que los metadatos son públicos.

Y hay una segunda lección, más incómoda: «no explotable» casi nunca significa «inofensivo». Significa «todavía no hemos encontrado el ángulo». En 2007 el ángulo era un crash; en 2026 es un canal lateral con 100% de efectividad sobre SSH. El coste de ignorar el aviso no desaparece: se acumula con intereses.


Qué debería cambiar

Los propios autores del paper plantean las mitigaciones necesarias. Son un buen punto de partida para cualquier equipo que diseñe subsistemas de ficheros, y un recordatorio de que los parches puntuales no sustituyen un cambio de modelo:

  1. Extender las comprobaciones de capacidad a la monitorización de los propios archivos y de cualquier archivo legible — no solo a los ficheros de dispositivo ya parcheados en Linux.
  2. En Windows, prohibir la monitorización de unidades completas. Vigilar C:\ no debería ser una operación sin privilegios.
  3. En Windows y macOS, introducir un sistema de permisos a nivel de kernel que contemple contexto, control de acceso, archivos y directorios propios, y minifilters.
  4. En Android, cerrar la fuga de FileObserver sobre FUSE, que hoy permite a una app sin permisos observar el almacenamiento privado de otra.
  5. Por defecto, no notificar. La seguridad de los metadatos debe ser opt-out, no opt-in.

A esto se podría añadir una sexta, heredada del hallazgo de 2007: validar siempre el tamaño de cualquier cadena que provenga de metadatos antes de copiarla a un buffer de tamaño fijo. Suena elemental, pero es exactamente lo que falló en FileAllInformation() hace diecinueve años, y es la clase de bug que sigue apareciendo en codebases modernas.


Conclusión

Diecinueve años después del primer aviso, el fix no es solo un parche técnico. Es un cambio de mentalidad: dejar de tratar los metadatos como información pública por defecto y empezar a tratarlos como lo que son —una superficie de ataque de pleno derecho, con implicaciones de privacidad y de seguridad medibles.

La curiosidad movió la mente en 2007. En 2026, los datos demuestran que tenía razón. La pregunta incómoda es cuántas veces más vamos a necesitar que alguien encuentre el ángulo explotable antes de que la industria decida que, quizá, los metadatos no eran tan inocuos después de todo.

Nota para equipos de desarrollo: si tu aplicación lee, escribe o notifica sobre metadatos de archivos, revisa dos cosas hoy mismo. Primero, que ningún buffer de tamaño fijo reciba datos que no controlas. Segundo, que los mecanismos de notificación que uses respeten el modelo de permisos del observador, no solo el del archivo observado. Son dos caras del mismo problema, y llevan veinte años sin resolverse.


Fuentes y referencias

#Cybersecurity #InfoSec #VulnerabilityResearch #SideChannels #inotify #CVE #Metadata #AppSec #Linux #Windows #Android #macOS #PwnieAwards #ACMSCCS

Three Vectors, One Root Cause — STA-003, STA-017, STA-020

Thursday, September 10, 2026

Chrome 152.0.7977.82 and Edge 152.0.4191.53 remain vulnerable to three distinct Structured Text Amplification (STA) vectors on Android 16. A full forensic bugreport captured on September 6, 2026 confirms the failure chain from oversized Bundle to Binder transaction failure to process termination. The September 2026 Android Security Bulletin contains no patches for the affected paths.


1. Executive Summary

Three STA vectors are confirmed reproducible in the two dominant Chromium-based browsers on Android:

Vector Trigger Chrome 152 Edge 2026 Impact
STA-003 Click Share on a crafted link CRASH CRASH Process termination
STA-017 Long-press on a crafted link ANR ANR UI freeze + force finish
STA-020 Focus address bar after crafted URL in history ANR ANR UI freeze + force finish

Architectural root cause: The demonstrated failure paths converge on Android platform components — libminikin.so for text processing and the IActivityTaskManager Binder boundary for oversized transactions. The evidence indicates that browser-level mitigations cannot fully address these platform-level execution paths.


2. Test Environment

ParameterValue
DeviceXiaomi Redmi Note 14 5G
OSAndroid 16, HyperOS 3.0.301.0 (build BP2A.250605.031.A3)
Chrome152.0.7977.82 (stable)
Edge152.0.4191.53 (stable)
Bugreportbugreport-2026-09-06-200012.zip
libminikin.so BuildId4fabe53671b5ead88314c00a1fd6d67d

3. STA-003 — Share Intent Crash

3.1 Trigger

The user clicks Share on a crafted link with an oversized URL. The browser constructs a share Intent carrying the oversized crafted content, which is propagated through the Android activity-start path and ultimately reaches the Binder transaction boundary.

Scope note: In the controlled reproduction, the variable extra content was identified as the crafted STA pattern. The corresponding extra key is redacted in the captured bugreport, so this article does not claim to read the exact extra key from the forensic dump itself.

3.2 Forensic evidence from the bugreport

The Android BaseBundleMonitorImpl (Xiaomi HyperOS) logged the following immediately before the failure:

19:56:56.867  BaseBundleMonitorImpl:
               Large Bundle: length=1531092, bundle=8814309
19:56:56.867  BaseBundleMonitorImpl:
               Large Bundle: length=1532640, bundle=36c790e

Binder then recorded the outgoing transaction and its failure:

Binder transaction failure
id: 12562575
error: -28 (No space left on device)

Large outgoing transaction of 1533260 bytes
interface descriptor: android.app.IActivityTaskManager
code 1

JavaBinder: FAILED BINDER TRANSACTION
parcel size = 1533260

The Java framework then threw the corresponding exception:

android.os.TransactionTooLargeException:
data parcel size 1533260 bytes

  at android.os.BinderProxy.transactNative(Native Method)
  at android.os.BinderProxy.transact(BinderProxy.java:642)
  at android.app.IActivityTaskManager$Stub$Proxy.startActivity(...)
  at android.app.Instrumentation.execStartActivity(...)
  at android.app.Activity.startActivityForResult(...)
  at org.chromium.ui.base.WindowAndroid.R(...)
  ...

Finally, the system terminated the browser process:

wm_finish_activity:
com.microsoft.emmx/org.chromium.chrome.browser.ChromeTabbedActivity, force-crash

am_proc_died:
com.microsoft.emmx

3.3 Chrome confirmation

The same sequence reproduces in Chrome 152 with nearly identical numbers:

TransactionTooLargeException:
data parcel size 1533240 bytes

wm_finish_activity:
com.android.chrome/org.chromium.chrome.browser.ChromeTabbedActivity, force-crash

am_proc_died:
com.android.chrome

Critical observation: Edge failed at 1,533,260 bytes. Chrome failed at 1,533,240 bytes. The difference is 20 bytes. Both browsers reach the same Chromium Activity-start path and both fail at the same Android Binder boundary.


4. STA-017 — Long-Press ANR

4.1 Trigger

The user long-presses a link. The context menu rendering path attempts to measure the anchor text and URL through TextView.onMeasure() → StaticLayout → libhwui → libminikin.so.

4.2 Stack trace (Chrome 152)

"main" prio=5 tid=1 Native   ← UI THREAD BLOCKED
  | state=R

native: minikin::getPrevWordBreakForCache          libminikin.so
native: minikin::StyleRun::getLineMetrics          libminikin.so
native: minikin::MeasuredText::getLineMetrics      libminikin.so
native: minikin::LineBreakOptimizer::computeBreaks libminikin.so
                                                   ← expensive text-processing path
native: minikin::breakLineOptimal                  libminikin.so
native: android::nComputeLineBreaks                libhwui.so

  at android.text.StaticLayout.generate(StaticLayout.java:969)
  at android.widget.TextView.onMeasure(TextView.java:11486)
  at org.chromium.chrome.browser.contextmenu.ContextMenuListView.onMeasure
  at android.view.ViewRootImpl.performTraversals

4.3 System response

ANR in Window ... ChromeTabbedActivity is not responding.
Waited 5000ms for MotionEvent(action=DOWN)

→ Force finishing activity ChromeTabbedActivity
→ Killing process

4.4 Edge confirmation

Edge reproduces the identical path. The ANR subject is:

Input dispatching timed out
(com.microsoft.emmx/...ChromeTabbedActivity is not responding.
 Waited 5000ms for MotionEvent(action=DOWN))

5. STA-020 — Address-Bar Focus ANR

5.1 Trigger

A crafted URL is stored in browser history (e.g. after a previous navigation). The user focuses the address bar. The omnibox suggestion list is rendered through OmniboxSuggestionsContainer.onMeasure() → RecyclerView → TextView.onMeasure() → StaticLayout → libminikin.so.

5.2 Stack trace (Edge 2026-09-06)

"main" prio=5 tid=1 Native
  | state=R

  at android.text.StaticLayout.generate
  at android.text.StaticLayout.
  at android.widget.TextView.onMeasure
  at androidx.appcompat.widget.AppCompatTextView.onMeasure
  at android.widget.LinearLayout.measureVertical
  at org.chromium.chrome.browser.omnibox.suggestions.base.BaseSuggestionView.onMeasure
  at androidx.recyclerview.widget.RecyclerView.onMeasure
  at android.view.ViewRootImpl.performTraversals
  at android.view.Choreographer.doFrame

5.3 System response

ANR in Window ... ChromeTabbedActivity
→ Force finishing activity
→ Killing process

Note: The Edge ANR was captured at 19:40:33 on 2026-09-06 during normal device use — not a synthetic test. It is a spontaneous production capture, which strengthens the reproducibility of the vector.


6. Why Chromium Patches Do Not Fix This

During 2026, Chromium introduced several mitigations for large IPC payloads and oversized text. None of them address the vectors documented above.

Patch Surface STA-003 STA-017 STA-020
SelectionUtils / 100 KB PDF text selection No No No
LargePayloadSupport (FD) Credential Manager No No No
SharedMemory (Union) Native Messaging No No No
Oversized Clipboard (ContentProvider) Clipboard No No No
PdfView anchors PdfView SavedState No No No
TLE telemetry Native Messaging No No No

The vulnerable paths are in Android platform components. They are libminikin.so (text processing) and the IActivityTaskManager Binder boundary (oversized transactions). Chromium cannot patch these paths.


7. September 2026 Android Security Bulletin — No Patches for STA

The September 2026 Android Security Bulletin was published on 8 September 2026. A complete search of the bulletin reveals zero references to the surfaces documented in this paper:

KeywordResults in Bulletin
libminikin0
Binder0
SavedState0
TransactionTooLarge0
StaticLayout, TextView, LineBreakOptimizer0

The bulletin contains dozens of CVEs across Framework, System, and Kernel — including critical RCEs — but none of them address the STA root causes.


8. The Failure Chain (Recap)

STA payload (crafted URL / oversized structured text)
        ↓
User action (Share / long-press / focus address bar)
        ↓
Chromium builds a share Intent or triggers a TextView measurement call
        ↓
Android platform components:
  · StaticLayout → libhwui → libminikin.so   (STA-017 / STA-020)
  · IActivityTaskManager.startActivity() → Binder   (STA-003)
        ↓
Main thread blocked >5 s OR Binder transaction failure
        ↓
ANR  (STA-017 / STA-020)
or
TransactionTooLargeException → Force finishing activity → Killing  (STA-003)

9. Why This Matters

Three points are worth emphasizing:

  1. Two independent browsers. Chrome 152 and Edge 2026 both reproduce all three vectors. This is not a Chrome-specific defect.
  2. Two independent mechanisms. STA-003 fails at the Binder boundary; STA-017 and STA-020 fail inside libminikin. Both mechanisms share the same architectural root: no early length gate before an expensive or bounded operation.
  3. No upstream mitigation. Neither the Chromium 2026 patches nor the September 2026 Android Security Bulletin address the affected paths.

10. Recommendations

10.1 Framework (AOSP / Android)

  • Introduce a global length gate in libminikin::LineBreakOptimizer::computeBreaks() and in the measurement/shaping paths (Layout::measureText, LayoutPiece) before entering expensive operations.
  • Validate the size of an Intent / Bundle before calling IActivityTaskManager.startActivity(), and reject or truncate oversized payloads instead of letting the Binder transaction fail with TransactionTooLargeException.
  • Instrument the affected paths with telemetry so that oversized payloads are detected before they cause user-visible failures.

10.2 Application-level (defensive)

  • Truncate URL / share text to a safe maximum (e.g. 50,000 characters) before passing it to the system share sheet.
  • Truncate suggestion / history text before measuring it in an omnibox or context menu.

These application-level measures reduce the attack surface but do not fix the root cause.


11. Conclusion

Chrome 152.0.7977.82 and Edge 152.0.4191.53 are vulnerable to three STA vectors on Android 16:

  • STA-003 — Share Intent crash (process termination).
  • STA-017 — Long-press ANR (main-thread block in libminikin).
  • STA-020 — Address-bar focus ANR (main-thread block in libminikin).

Forensic evidence from a production bugreport (2026-09-06) confirms the full failure chain from oversized Bundle to Binder transaction failure to process termination. The September 2026 Android Security Bulletin contains no patches for the affected paths.

The evidence indicates that the issue is not confined to a specific browser implementation. Chromium-only mitigations cannot fully address the demonstrated Android text-processing and Binder execution paths. A platform-level fix in AOSP appears necessary.


libminikin The Sixth Entry Point

Wednesday, September 09, 2026

The Sixth Entry Point: New Forensic Evidence Confirms STA Remains Unpatched in Android 16

New forensic evidence from a full Android 16 bugreport confirms that Structured Text Amplification

(STA) vectors remain reproducible in Chrome 152 and Edge 2026. A sixth entry point into libminikin has been identified, and the September 2026 Android Security Bulletin contains no patches for the affected paths.


1. Executive Summary

A full Android 16 bugreport (Redmi Note 14 5G, September 6, 2026) provides direct forensic evidence of two distinct failure mechanisms affecting Chromium-based browsers:

  • Text‑layout ANRs involving libminikin::LineBreakOptimizer::computeBreaks() during long-press and address-bar focus.
  • Oversized Binder transactions resulting in TransactionTooLargeException and browser process termination via Share / VIEW workflows.

Both Chrome 152.0.7977.82 and Edge 152.0.4191.53 reproduce the same failures on Android 16 (build BP2A.250605.031.A3 / HyperOS 3.0.301.0).

Key finding: A sixth entry point into libminikin has been identified Paint.measureText() → HarfBuzz shaping, reproduced in Google Docs (com.google.android.apps.docs.editors.docs). This is the first documented entry point that enters libminikin through the glyph shaping path rather than line-breaking.


2. The Sixth Entry Point STA-031

The previously documented entry points into libminikin all pass through line‑breaking algorithms (LineBreakOptimizer::computeBreaks, breakLineOptimal, breakLineGreedy). The new evidence reveals a sixth entry point:

android.graphics.Paint.measureText()
        ↓
libhwui (PaintGlue / MinikinUtils)
        ↓
libminikin (Layout::measureText)
        ↓
Layout::doLayoutRunCached
        ↓
Layout::doLayoutWord
        ↓
LayoutCache::getOrCreate<LayoutAppendFunctor>
        ↓
LayoutPiece::LayoutPiece
        ↓
libharfbuzz_ng (hb_shape_full, _hb_ot_shape)
        ↓
hb_font_t::get_glyph_h_origin_with_fallback
        ↓
Main thread blocked → InputDispatcher timeout → ANR
    

This stack was captured from a production ANR in Google Docs (com.google.android.apps.docs.editors.docs), which was not previously in the catalogue of applications with forensically confirmed libminikin ANRs.

The trigger path passes through AlertDialogLayout.onMeasure, consistent with an oversized structured payload being measured inside a dialog component, the same class of UI surface implicated in other STA vectors.


3. Forensic Evidence STA-003 (Share / Intent Binder Crash)

The bugreport records an ActivityTaskManager transition involving Google Files as the calling package:

19:40:03.713
START u0 {
    act=android.intent.action.VIEW
    dat=content://com.google.android.apps.nbu.files.provider/...
    typ=text/html
    ...
    cmp=com.microsoft.emmx/com.google.android.apps.chrome.IntentDispatcher
}
    

The Intent is explicitly reported as (has extras). Although the actual extra contents are redacted by the bugreport, in controlled reproduction the variable content supplied through this workflow is the crafted STA pattern.

3.1. Large Bundles

For Edge, the bugreport records:

Large Bundle: length=1531092
Large Bundle: length=1532640
    

3.2. Binder Transaction Failure

Immediately before the crash:

Binder transaction failure
ID: 12562575
error: -28 (No space left on device)

Large outgoing transaction of 1533260 bytes
interface descriptor: android.app.IActivityTaskManager
code 1
    

3.3. TransactionTooLargeException

android.os.TransactionTooLargeException:
data parcel size 1533260 bytes

android.app.Instrumentation.execStartActivity
android.app.Activity.startActivityForResult
org.chromium.ui.base.WindowAndroid
android.app.IActivityTaskManager$Stub$Proxy.startActivity
android.os.BinderProxy.transact
    

3.4. Process Termination

wm_finish_activity:
com.microsoft.emmx/...ChromeTabbedActivity, force-crash

am_proc_died:
com.microsoft.emmx
    

3.5. Chrome Confirmation

The same phenomenon is reproduced in Chrome:

TransactionTooLargeException:
data parcel size 1533240 bytes

wm_finish_activity:
com.android.chrome/...ChromeTabbedActivity, force-crash

am_proc_died:
com.android.chrome
    

The two Chromium implementations fail at almost exactly the same serialized transaction size:

  • Chrome: 1,533,240 bytes
  • Edge: 1,533,260 bytes
  • Difference: only 20 bytes

This is particularly significant because both browsers reach the same Chromium Activity-start path and both fail at the Android Binder boundary.


4. STA-017 / STA-020 Text-Layout ANRs

The same bugreport contains multiple ANR reports in which Chrome and Edge enter the Android text-layout stack:

TextView
StaticLayout
LineBreaker
libhwui
libminikin
minikin::LineBreakOptimizer::computeBreaks
breakLineOptimal
android::nComputeLineBreaks
    

In Chrome, the stack includes:

minikin::getPrevWordBreakForCache
StyleRun::getLineMetrics
MeasuredText::getLineMetrics
LineBreakOptimizer::computeBreaks
breakLineOptimal
android::nComputeLineBreaks
TextView.onMeasure
    

The ANR reason is an input dispatch timeout:

ChromeTabbedActivity is not responding.
Waited 5000ms for MotionEvent(action=DOWN)
    

The Activity is subsequently force-finished by the system. This demonstrates that the problem is not specific to a single Chromium implementation. The same Android text-layout subsystem is reached by both browsers.

4.1. STA-020 — Address Bar / Omnibox ANR

A separate reproduction occurs when the crafted URL is present in browser history and the address bar is subsequently focused. The omnibox suggestion rendering path again reaches Android's text measurement and libminikin line-breaking implementation:

OmniboxSuggestionsContainer.onMeasure
RecyclerView.onMeasure
TextView.onMeasure
StaticLayout.generate
libhwui
libminikin
LineBreakOptimizer::computeBreaks
    

This provides a second independent entry point into the same native text-layout subsystem.


5. Chromium Patches — Not Enough

The Chromium-specific mitigations introduced in 2026 do not address the underlying Android text-processing paths involved in these reproductions.

Patch Mechanism Covers STA-003? Covers STA-017/020?
SelectionUtils / 100 KB Truncates PDF selection text ❌ No ❌ No
LargePayloadSupport (FD) File descriptors for large IPC ❌ No ❌ No
SharedMemory (Union) Redesigns Native Messaging transport ❌ No ❌ No
Oversized Clipboard (ContentProvider) Redirects large clipboard payloads ❌ No ❌ No
PdfView anchors Replaces SelectionModel with placeholders ❌ No ❌ No

The root cause is not in Chromium. It is in Android's libminikin.so text layout engine, which lacks a global length gate before entering expensive paths like LineBreakOptimizer::computeBreaks() and Layout::measureText().


6. September 2026 Android Security Bulletin

The September 2026 Android Security Bulletin (published September 8) contains no patches for libminikin, Binder, SavedState, TransactionTooLargeException, or any of the STA vectors documented in this research.

A search of the bulletin reveals zero mentions of:

  • libminikin
  • Binder
  • SavedState
  • TransactionTooLarge
  • StaticLayout, TextView, LineBreakOptimizer

This confirms that the architectural gap in libminikin remains publicly unpatched.


7. The Bigger Picture

The evidence now supports the following conclusions:

Finding Status
Sixth entry point to libminikin (HarfBuzz shaping) ✅ Confirmed (Google Docs)
STA-003 (Share crash) — Edge and Chrome ✅ Reproducible in 2026
STA-017 (Long-press ANR) — Edge and Chrome ✅ Reproducible in 2026
STA-020 (Focus ANR) — Edge and Chrome ✅ Reproducible in 2026
Chromium patches ❌ Do not cover STA-003/017/020
September 2026 bulletin ❌ No patches for libminikin
Xiaomi STA-015b ✅ Patched (no CVE public)

8. Conclusion

New forensic evidence from a full Android 16 bugreport confirms that Structured Text Amplification (STA) vectors remain reproducible in the latest versions of Chromium-based browsers.

A sixth entry point into libminikin has been identified Paint.measureText() → HarfBuzz shaping, reproduced in Google Docs. This demonstrates that the problem is not confined to line-breaking; it also affects glyph shaping and text measurement paths.

Despite multiple Chromium patches in 2026 (LargePayloadSupport, SharedMemory, 100 KB selection limits, etc.), none of them address the underlying Android text-processing paths involved in STA-003, STA-017, and STA-020.

The September 2026 Android Security Bulletin contains no patches for libminikin, Binder, SavedState, or TransactionTooLargeException.

The evidence indicates a platform-level resource-exhaustion gap: Android text-processing entry points do not enforce a sufficiently early global length limit before entering expensive operations such as line breaking, shaping and measurement.

This indicates that the issue is not browser-specific and cannot be fully addressed through Chromium-only patches. A platform-level fix in AOSP appears necessary


 

Browse

About:Me

My blog:http://lostmon.blogspot.com
Mail:Lostmon@gmail.com
Lostmon Google group
Lostmon@googlegroups.com

La curiosidad es lo que hace
mover la mente...

Friends