Crashlytics plugin writes build ID lists in directory listing order, so APKs can differ between machines
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 72/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Área
- build-system, mobile
Línea de trabajo
Empieza en BuildIdInfoCollector.collect() en firebase-crashlytics-buildtools, donde el bucle sobre FileUtils.listFiles() añade filas de BuildIdInfo, y revisa cómo se derivan las listas de nombre de biblioteca, arquitectura e ID de compilación a partir de esa única lista. Añade una ordenación determinista al final de collect() usando los campos que propone el issue, y verifica la salida con una prueba unitaria que alimente los archivos en orden aleatorio. Está terminado cuando las mismas entradas siempre producen el mismo orden de filas y las tres listas siguen emparejadas.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
[REQUIRED] Step 2: Describe your environment
- Android Studio version: not used; command-line build with Gradle 9.3.1, AGP 9.1.1 and JDK 21
- Firebase Component: Crashlytics Gradle plugin
- Component version: 3.0.8
[REQUIRED] Step 3: Describe the problem
When nativeSymbolUploadEnabled is on, the plugin writes three lists into the app's resources:
com.google.firebase.crashlytics.build_ids_lib, _arch and _build_id.
The rows follow directory listing order and are not sorted. So the same source can produce a different
resources.arsc, which breaks reproducible builds. We verify open source Bitcoin wallets at WalletScrutiny,
and this is how we found it.
BuildIdInfoCollector.collect() loops over FileUtils.listFiles()
and adds rows in that order. That helper
does not sort either.
Steps to reproduce:
- Use an app with native libraries, and set
nativeSymbolUploadEnabled true. - Build it normally, and keep
com_google_firebase_crashlytics_build_ids.xml. - Mount the source with
disorderfs --shuffle-dirents=yes --reverse-dirents=no --sort-dirents=no <source> <mount>. - Build the same commit inside the mount.
- Compare the two files. The rows match, but their order differs.
We ran these builds with P.CASH 0.60.1, commit ab67f8e649, on one host:
| Build | List order |
|---|---|
| Normal, first | same as second |
| Normal, second | same as first |
Under disorderfs shuffle |
different |
The shuffled build still had the same 80 rows. After sorting them, the only decoded difference left was the
random mapping_file_id (#2570). Two of the three APK splits stayed byte-identical.
We also compared the developer's official builds with ours:
| Release | Official file | Commit | Rows | Changed list lines |
|---|---|---|---|---|
| 0.60.1 | Google Play base.apk |
ab67f8e649 |
80 | 262 |
| 1.0.260 | GitHub -google APK |
596bf08522 |
74 | 246 |
Each pair has the same rows once sorted.
Limits of our testing:
- We ran one shuffled build.
- We did not build on two machines of our own.
- We have no minimal sample project.
Expected: the same source gives the same list order, whatever the directory listing order is.
Relevant Code:
Part of the 0.60.1 diff (official <, ours >):
< <item>libjnidispatch.so</item>
< <item>libgojni.so</item>
< <item>libcrashlytics-common.so</item>
> <item>libc++_shared.so</item>
> <item>libimage_processing_util_jni.so</item>
> <item>libsecp256k1-jni.so</item>
A possible fix, at the end of collect(), which we have not compiled or tested:
buildIdInfoList.sort(
Comparator.comparing(BuildIdInfo::getLibraryName)
.thenComparing(BuildIdInfo::getArch)
.thenComparing(BuildIdInfo::getBuildId));
All three lists come from this one list, so the rows should stay paired.
Related: #2570 covers the random mapping_file_id. This issue is only about list order.
- Lenguaje dominante
- Java
- Estrellas
- 2.6k
- Forks
- 733
- Merge medio
- 2 d 15 h
- PR fusionados (30 d)
- 72
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de firebase/firebase-android-sdk
-
api: remoteconfig
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
firebase/firebase-android-sdk#8827 ·
Los mantenedores suelen responder en 1 día
-
api: auth
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
firebase/firebase-android-sdk#8505 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 15/100
firebase/firebase-android-sdk#8835 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
firebase/firebase-android-sdk#8832 ·
Los mantenedores suelen responder en 1 día
-
Firestore: NoSuchElementException in SQLiteIndexManager.encodeValues for a != query with a trailing orderBy when cache index auto-creation is enabledPosiblemente ocupada @dconeybe la tomó hace 1 día. Abiertoapi: firestore
firebase/firebase-android-sdk#8831 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de firebase/firebase-android-sdk
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
NationalSecurityAgency/ghidra#10220 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
Los mantenedores suelen responder en 1 día
-
RIS export splits an organization name containing “and” into multiple authorsPosiblemente ocupada @Gautam-aman la tomó hoy. Abiertostatus: needs-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
JabRef/jabref#17821 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
FailureContext.java rounds down thresholds in lastedAtLeast()Posiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día