Crash when parsing protobuf message containing a s

2019-06-24 01:27发布

问题:

I have two programs, both running on an Android 2.3.4 platform - one is a C++ binary in a daemon form, compiled with cmake, the other is a apk with jni part compiled with ndk-build. I'm using android-ndk-r6. I'm using protobuf messages and local unix sockets to pass data between them. I'm using the SerializeAsString and ParseFromString methods. Here is a snippet

AbstractMessage protobuff_msg;
protobuff_msg.set_id ( 1 ); //TODO: for now hardcoded, later can be used for request-response pairs
protobuff_msg.set_type ( AbstractMessage_MessageType_REQUEST );
protobuff_msg.set_method ( AbstractMessage_MethodName_LOAD_DEFINITION );

AbstractMessage_Parameter* param = protobuff_msg.mutable_param()->Add();
param->set_name(AbstractMessage_ParameterName_FILEPATH);
param->set_value(filepath);

std::string msg = protobuff_msg.SerializeAsString();

client_->write_protobuf_message ( msg, MAGIC_NUMBER );

AbstractMessage is the protobuf message, AbstractMessage_MessageType_REQUEST,LOAD_DEFINITION,FILEPATH are enums, AbstractMessage_Parameter is a repeated nested message. The param value is a string, all other types are int-s. client is a custom library for the socket communication.

int Foo::write_protobuf_message(std::string protobuf_msg, int magic_number)
    {
        int send_int = 0;
        send_int = htonl(magic_number); 
        int n = write_to_socket((void *)&send_int, sizeof(int));
        if(n<0)
            return -1;
        send_int = htonl(protobuf_msg.size());
        n = write_to_socket((void *)&send_int, sizeof(int));
        if(n<0)
            return -1;
        n = write_to_socket((void *)protobuf_msg.c_str(),protobuf_msg.size());

        return n;
    }

The parsing:

    void foo ( void* buffer, int buff_size, int error)
{
    std::string buffstr;
    if (error == 0)
    {
        buffstr.assign ( ( char* ) buffer, buff_size );

        AbstractMessage proto_msg;

        bool res = proto_msg.ParsePartialFromString(buffstr);
        if (res)
        {
            //TODO handle ok parsing
            return;
        }
        else
        {
            //TODO handle failed parsing
            return;
        }
    }

}

This scenario is tested with two c++ daemon binaries as test tools and it works. However when I try the real deal with the apk I get the following crash:

09-30 11:43:28.335: INFO/DEBUG(1044): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
09-30 11:43:28.335: INFO/DEBUG(1044): Build fingerprint: 'foobar/voles/sholes/sholes:2.2.1/FRG83D/75603:user/release-keys'
09-30 11:43:28.335: INFO/DEBUG(1044): pid: 3991, tid: 4001  >>> com.foo.bar <<<
09-30 11:43:28.335: INFO/DEBUG(1044): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
09-30 11:43:28.335: INFO/DEBUG(1044):  r0 00000027  r1 deadbaad  r2 a0000000  r3 00000000
09-30 11:43:28.335: INFO/DEBUG(1044):  r4 00000001  r5 00000000  r6 80422d0c  r7 0000a000
09-30 11:43:28.342: INFO/DEBUG(1044):  r8 44156eb0  r9 44156eb4  10 000ab44c  fp 000001f0
09-30 11:43:28.342: INFO/DEBUG(1044):  ip afd46668  sp 44156c80  lr afd193b1  pc afd15e80  cpsr 60000030
09-30 11:43:28.342: INFO/DEBUG(1044):  d0  6472656767756265  d1  696e6a2f6c6c6173
09-30 11:43:28.342: INFO/DEBUG(1044):  d2  4194fc184194fb65  d3  4194fc804194fc74
09-30 11:43:28.342: INFO/DEBUG(1044):  d4  4194fce84194fcb4  d5  4194fd504194fd1c
09-30 11:43:28.342: INFO/DEBUG(1044):  d6  4194fdb84194fd84  d7  4194fe204194fdec
09-30 11:43:28.342: INFO/DEBUG(1044):  d8  0000000000000000  d9  0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  d10 0000000000000000  d11 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  d12 0000000000000000  d13 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  d14 0000000000000000  d15 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  d16 00000000405122d8  d17 3fe999999999999a
09-30 11:43:28.350: INFO/DEBUG(1044):  d18 42eccefa43de3400  d19 3fbc71c71c71c71c
09-30 11:43:28.350: INFO/DEBUG(1044):  d20 4008000000000000  d21 3fd99a27ad32ddf5
09-30 11:43:28.350: INFO/DEBUG(1044):  d22 3fd24998d6307188  d23 3fcc7288e957b53b
09-30 11:43:28.350: INFO/DEBUG(1044):  d24 3fc74721cad6b0ed  d25 3fc39a09d078c69f
09-30 11:43:28.350: INFO/DEBUG(1044):  d26 0000000000000000  d27 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  d28 0000000000000000  d29 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  d30 0000000000000000  d31 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044):  scr 60000010
09-30 11:43:28.514: INFO/DEBUG(1044):          #00  pc 00015e80  /system/lib/libc.so (__libc_android_abort)
09-30 11:43:28.514: INFO/DEBUG(1044):          #01  pc 00013834  /system/lib/libc.so (dlfree)
09-30 11:43:28.514: INFO/DEBUG(1044):          #02  pc 00014726  /system/lib/libc.so (free)
09-30 11:43:28.514: INFO/DEBUG(1044): code around pc:
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e60 2c006824 e028d1fb b13368db c064f8df 
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e70 44fc2401 4000f8cc 49124798 25002027 
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e80 f7f57008 2106ebce ed7af7f6 460aa901 
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e90 f04f2006 95015380 95029303 e8a0f7f6 
09-30 11:43:28.514: INFO/DEBUG(1044): afd15ea0 462aa905 f7f62002 f7f5e8ac 2106ebba 
09-30 11:43:28.514: INFO/DEBUG(1044): code around lr:
09-30 11:43:28.514: INFO/DEBUG(1044): afd19390 4a0e4b0d e92d447b 589c41f0 26004680 
09-30 11:43:28.514: INFO/DEBUG(1044): afd193a0 686768a5 f9b5e006 b113300c 47c04628 
09-30 11:43:28.514: INFO/DEBUG(1044): afd193b0 35544306 37fff117 6824d5f5 d1ef2c00 
09-30 11:43:28.514: INFO/DEBUG(1044): afd193c0 e8bd4630 bf0081f0 0002816c ffffff88 
09-30 11:43:28.522: INFO/DEBUG(1044): afd193d0 b086b570 f602fb01 9004460c a804a901 
09-30 11:43:28.522: INFO/DEBUG(1044): stack:
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c40  afd42664  
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c44  000a9908  
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c48  00000015  
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c4c  afd18479  /system/lib/libc.so
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c50  afd4270c  
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c54  afd426b8  
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c58  00000000  
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c5c  afd193b1  /system/lib/libc.so
09-30 11:43:28.522: INFO/DEBUG(1044):     44156c60  00000001  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c64  44156c94  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c68  80422d0c  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c6c  0000a000  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c70  44156eb0  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c74  afd186d3  /system/lib/libc.so
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c78  df002777  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c7c  e3a070ad  
09-30 11:43:28.530: INFO/DEBUG(1044): #00 44156c80  00000023  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c84  001533b8  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c88  80422d0c  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c8c  44156cec  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c90  80422d0c  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c94  fffffbdf  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c98  44156eb0  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156c9c  afd46450  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156ca0  44156cec  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156ca4  afd13839  /system/lib/libc.so
09-30 11:43:28.530: INFO/DEBUG(1044): #01 44156ca8  80422d0c  
09-30 11:43:28.530: INFO/DEBUG(1044):     44156cac  44156cec  
09-30 11:43:28.538: INFO/DEBUG(1044):     44156cb0  0000000b  
09-30 11:43:28.538: INFO/DEBUG(1044):     44156cb4  00000000  
09-30 11:43:28.538: INFO/DEBUG(1044):     44156cb8  44156eb0  
09-30 11:43:28.538: INFO/DEBUG(1044):     44156cbc  afd14729  /system/lib/libc.so
09-30 11:43:30.382: INFO/BootReceiver(1185): Copying /data/tombstones/tombstone_00 to DropBox (SYSTEM_TOMBSTONE)

If I try to parse only ints (I change the protobuf message to be without a string/bytes) all works great. If i add the string/bytes all fails. I tried also with required and optional string, also with bytes. Nothing works. I found that such a crash my be caused by an assert. Any ideas?

回答1:

What I can say about your error :

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad

deadbaad usually means invalid address.. so you most probably have an invalid address in the parsing section..

I would suggest enabling dalvik.vm.checkjni=true and trying to see if you get any further info