Corruption de tas – SEGV_MAPERR en code natif Android

J’essaie de créer une petite bibliothèque pour le cryptage AES en stream. J’ai commencé mon travail sur le projet Facebook Dissimulation ( https://github.com/facebook/conceal ), en modifiant simplement certaines choses et en améliorant l’encapsuleur natif afin de prendre en charge les chiffrements avec rembourrage.

Il fonctionne et peut déchiffrer les fichiers sans problème, mais je subis des corruption aléatoires de la mémoire de tas lorsque je travaille avec de gros stream de données. Après un débogage très long, je n’ai pas trouvé l’erreur.

Voici mon code:
https://gist.github.com/frisco82/9782725

J’ai essayé de trouver des problèmes d’allocation de mémoire ou de problèmes, mais il n’y a presque pas de malloc ou de libre, et jni call devrait être sûr, la même chose pour les opensl (j’ai compilé le mien, mais dissimule ceux qui échouent également)

CheckJni ne met en garde sur rien et bien que la gestion du contexte soit un peu originale, elle ne semble pas cassée (en effet, Android conscrypt semble utiliser quelque chose de similaire).

De plus, si quelqu’un peut m’indiquer une bibliothèque AES multiniveau (appels de mise à jour multiple) native sous Android, je vais passer à cela et l’oublier.

L’erreur varie de temps en temps mais elle ressemble généralement à la sienne:

03-26 10:33:02.065: A/dalvikvm(2475): @@@ ABORTING: DALVIK: HEAP MEMORY CORRUPTION IN mspace_malloc addr=0x0 03-26 10:33:02.065: A/libc(2475): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 2494 (AsyncTask #1) 03-26 10:33:02.205: I/DEBUG(933): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 03-26 10:33:02.205: I/DEBUG(933): Build fingerprint: 'generic_x86/google_sdk_x86/generic_x86:4.4.2/KK/999428:eng/test-keys' 03-26 10:33:02.205: I/DEBUG(933): Revision: '0' 03-26 10:33:02.205: I/DEBUG(933): pid: 2475, tid: 2494, name: AsyncTask #1 >>> com.proton <<< 03-26 10:33:02.205: I/DEBUG(933): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad 

Traces de stack complètes:
http://pastebin.com/f6mDuQEj

Il fonctionne et peut déchiffrer les fichiers sans problème, mais je subis des altérations aléatoires de la mémoire lors de l’utilisation de gros stream de données.

À partir de la ligne ci-dessus, il me semble que votre programme écrase clairement la mémoire allouée implicitement ou explicitement par votre code. J’essayais de comprendre votre code, mais ce n’était pas clair pour moi. Mais j’ai essayé de regarder à partir d’un scénario de corruption de mémoire et j’ai constaté que votre programme avait un appel malloc / free pouvant entraîner un dépassement de la mémoire.

 EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*) malloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(ctx); EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*) malloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(ctx); 

J’ai essayé de vérifier la mise en page de la structure EVP_CIPHER_CTX mais celle-ci n’était pas disponible dans votre code. Mais j’ai vu que ces pointeurs sont utilisés dans différents contextes au sein de votre programme. Maintenant, vous devriez vérifier que dans quel scénario votre tampon peut être écrasé car, à certains endroits, vous avez utilisé une longueur de clé différente et, en fonction de cela, votre programme exécute une fonction différente. Je pense que vous voudrez peut-être revoir ces codes et voir si un débordement est possible !!! ….

Comme votre application fonctionnerait sur un système basé sur Android où nous ne pouvons exécuter aucun outil dynamic (Valgrind / WinDBG / Pageheap ..), je suppose que vous devez revoir votre code en mettant un journal à un endroit important et voir où vous écrasez.

J’espère que les informations ci-dessus vous seront utiles pour comprendre votre problème.

Après tout ce que j’ai pu contourner ce problème, EVP_CipherUpdate (ou jni ReleaseByteArrayElements ) déborde parfois du tampon de sortie, causant la corruption du tas, rien dans mon code n’était erroné et le fait que l’appelant ait remplacé EVP_CipherUpdate par un appel memcpy n’était pas un problème. avec les mêmes parameters a fonctionné comme prévu et il n’y avait pas de corruption de tas.

La solution ajoutait donc une longueur supplémentaire au tampon de sortie envoyé à nativeUpdate et l’erreur disparaissait.

J’ai créé la version de travail complète de la bibliothèque pour que d’autres puissent l’utiliser à l’ adresse : https://github.com/frisco82/conceal