rnpgp / rnp

RNP: high performance C++ OpenPGP library used by Mozilla Thunderbird
https://www.rnpgp.org
Other
196 stars 55 forks source link

netpgp_init crash when using libnetpgp #34

Closed bitblight closed 7 years ago

bitblight commented 7 years ago

I wrote a small test unit and found that libnetpgp causes an access violation when it attempts to read the "homedir" variable in netpgp_init:

#include <stddef.h>
#include <stdio.h>
#include <netpgp.h>

int main(int argc, char *argv[])
{
        netpgp_t netpgp;

        puts("hello, world");
        if (netpgp_init(&netpgp)) {
                netpgp_list_keys(&netpgp, 1);
                netpgp_end(&netpgp);
        }
        return 0;
}

Resulting in:

(lldb) run
Process 27903 launched: './test' (x86_64)
hello, world
Process 27903 stopped
* thread #1: tid = 0x677ad, 0x00007fff9192f313 libsystem_platform.dylib`_platform_strcmp + 19, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4800000019)
    frame #0: 0x00007fff9192f313 libsystem_platform.dylib`_platform_strcmp + 19
libsystem_platform.dylib`_platform_strcmp:
->  0x7fff9192f313 <+19>: movzbq (%rdi), %rax
    0x7fff9192f317 <+23>: movzbq (%rsi), %r8
    0x7fff9192f31b <+27>: incq   %rdi
    0x7fff9192f31e <+30>: incq   %rsi
(lldb) bt
* thread #1: tid = 0x677ad, 0x00007fff9192f313 libsystem_platform.dylib`_platform_strcmp + 19, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4800000019)
  * frame #0: 0x00007fff9192f313 libsystem_platform.dylib`_platform_strcmp + 19
    frame #1: 0x000000010009b11f libnetpgp.0.dylib`findvar + 42
    frame #2: 0x00000001000980d9 libnetpgp.0.dylib`netpgp_init + 57
    frame #3: 0x0000000100000f21 test`main + 49
    frame #4: 0x00007fff91722255 libdyld.dylib`start + 1
    frame #5: 0x00007fff91722255 libdyld.dylib`start + 1
(lldb) register read
General Purpose Registers:
       rax = 0x0000000000000000
       rbx = 0x0000000000000000
       rcx = 0x0000000000000000
       rdx = 0x0000000000012068
       rdi = 0x0000004800000019
       rsi = 0x00000001000b41c7  "coredumps"

I suspect this is as a result of a null pointer finding its way to strcmp when an expected variable is not set. If it happens with "coredumps" it will likely happen with "homedir" as well.

dewyatt commented 7 years ago

Yes, currently you must set homedir before calling netpgp_init. It's one of the various undocumented oddities of libnetpgp.

The way I was using it before switching to lower-level functions, was something like:

netpgp_set_homedir(&netpgp, "/home/username/", ".gnupg", 0);
netpgp_init(&netpgp);
dewyatt commented 7 years ago

Ah actually it crashes because netpgp_t currently needs to be zeroed prior to use, otherwise netpgp->c is not 0 and findvar will try to read garbage. At least that's my conclusion from a quick look.

Honestly I think the netpgp_* layers are a bit weird all around. The global variable store makes things difficult to debug sometimes (things like not setting "need seckey" at times can cause crashes too if I recall correctly).

bitblight commented 7 years ago

@dewyatt Aha! Good catch! I'll add a memset() to netpgp_init.

edit: and if you happen to know of any other oddities like this please send me a list, it would be great to fix them early on.