堆腐败 – Android原生代码中的SEGV_MAPERR

我正在尝试为流AES加密创建一个小型库,我开始基于Facebook Conceal项目( https://github.com/facebook/conceal )开展我的工作,只是更改了一些内容并改进了本机的包装以支持密码用填充物。

它工作正常,它可以解密文件没有问题,但是当我处理大流时,我得到随机的堆内存损坏,经过大量的时间调试,我一直无法找到错误。

这是我的代码:
https://gist.github.com/frisco82/9782725

我试图找到内存分配或免费问题,但几乎没有malloc或free,而jni调用应该是安全的,openssl也是如此(我编译了自己但隐藏提供的也失败了)

CheckJni没有任何警告,虽然上下文处理有点开箱即用,但它看起来并没有破坏(事实上Android的密码似乎使用了类似的东西)。

此外,如果有人可以指向我的Android本机AES多步骤(多个更新调用)库,我将切换到那个并忘记这一点。

错误时常变化,但通常与他的相似:

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 

完整堆栈跟踪:
http://pastebin.com/f6mDuQEj

它工作正常,它可以解密文件而没有问题,但是当我处理大流时,我会得到随机的堆内存损坏。

从上面看,我看到你的程序明显覆盖了代码隐式或显式分配的内存。 我试图理解你的代码,但我不清楚。 但我试图从内存损坏情况看,发现你的程序确实有malloc / free调用,这可能会导致内存溢出。

 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); 

我试图检查EVP_CIPHER_CTX结构的布局,但它在您的代码中不可用。 但我看到这些指针在程序中的各种上下文中被使用。 现在您应该检查在哪种情况下您的缓冲区可以被覆盖,因为您使用了不同的keyLength,并且根据这一点,您的程序正在执行不同的function。 我想你可能想查看这些代码,看看溢出是否可能!!! ….

由于您的应用程序将在基于Android的系统上运行,我们无法运行任何动态工具(Valgrind / WinDBG / Pageheap ..)所以我猜您需要通过在重要位置放置一些日志来查看您的代码,并查看您覆盖的位置。

希望以上信息对您了解您的问题很有用。

毕竟我能够解决这个问题, EVP_CipherUpdate (或jni ReleaseByteArrayElements )有时会溢出输出缓冲区导致堆损坏,我的代码中没有任何错误,并且调用者没有问题,因为用memcpy调用替换EVP_CipherUpdate使用相同的参数按预期工作,并且没有堆损坏。

因此解决方案是向发送到nativeUpdate的输出缓冲区添加一些额外的长度,错误消失了。

我已经为其他人创建了该库的完整工作版本: https : //github.com/frisco82/conceal