jinganix / enif_protobuf

A Google Protobuf implementation with enif (Erlang nif)
38 stars 21 forks source link

load_cache/1 segfaults on non-trivial maps #29

Closed JayKickliter closed 9 months ago

JayKickliter commented 2 years ago

Minimal failing proto:

syntax = "proto3";

message a_message {
    map<string, non_trivial_item> non_trivial_map = 1;
}

message non_trivial_item {
    int64 item = 1;
}

Running enif_proto compiled with ASan (see bottom for Makefile modifications:

enif_protobuf (master *=) $ protoc-erl fail.proto
enif_protobuf (master *=) $ erlc -I/home/jay/repos/gpb/include fail.erl
~/repos/enif_protobuf (master *=) $ ASAN_OPTIONS=detect_leaks=0 LD_PRELOAD=$(gcc -print-file-name=libasan.so) rebar3 shell
===> Verifying dependencies...
make: Entering directory 'enif_protobuf/c_src'
make: 'enif_protobuf/c_src/../priv/enif_protobuf.so' is up to date.
make: Leaving directory 'enif_protobuf/c_src'
===> Analyzing applications...
===> Compiling enif_protobuf
Erlang/OTP 23 [erts-11.2.2.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V11.2.2.7  (abort with ^G)
1> fail:get_msg_defs().
[{{msg,a_message},
  [{field,non_trivial_map,1,2,
          {map,string,{msg,non_trivial_item}},
          repeated,[]}]},
 {{msg,non_trivial_item},
  [{field,item,1,2,int64,optional,[]}]}]
2> enif_protobuf:load_cache(fail:get_msg_defs()).

enif_protobuf/c_src/ep_node.c:714:44: runtime error: member access within null pointer of type 'struct ep_node_t'
ASAN:DEADLYSIGNAL
=================================================================
==21520==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x7ff516041014 bp 0x7ff51827e9f0 sp 0x7ff51827e910 T4)
==21520==The signal is caused by a READ memory access.
==21520==Hint: address points to the zero page.
#0 0x7ff516041013 in stack_ensure_all /home/jay/repos/enif_protobuf/c_src/ep_node.c:714
#1 0x7ff5160370c3 in load_cache_1 /home/jay/repos/enif_protobuf/c_src/enif_protobuf.c:261
#2 0x564925a8e3c4 in process_main x86_64-unknown-linux-gnu/opt/smp/beam_cold.h:184
#3 0x564925aa8e39 in sched_thread_func beam/erl_process.c:8560
#4 0x564925ca726b in thr_wrapper pthread/ethread.c:122
#5 0x7ff55e0196da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
#6 0x7ff55db3aa3e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x121a3e)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/jay/repos/enif_protobuf/c_src/ep_node.c:714 in stack_ensure_all
Thread T4 (1_scheduler) created by T0 here:
#0 0x7ff55ec51d2f in __interceptor_pthread_create (/usr/lib/gcc/x86_64-linux-gnu/7/libasan.so+0x37d2f)
#1 0x564925ca760f in ethr_thr_create pthread/ethread.c:419
==21520==ABORTING

Compiling enif_protobuf with ASan

diff --git a/c_src/Makefile b/c_src/Makefile
index 8c8fc3d..063d782 100644
--- a/c_src/Makefile
+++ b/c_src/Makefile
@@ -32,10 +32,13 @@ else ifeq ($(UNAME_SYS), Linux)
 endif

 CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
+CFLAGS +=  -ggdb3 -fno-omit-frame-pointer -Og -fsanitize=address,undefined
 CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
+CXXFLAGS +=  -ggdb3 -fno-omit-frame-pointer -Og -fsanitize=address,undefined

 LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lei -lpthread
 LDFLAGS += -shared
+LDFLAGS += -fsanitize=address,undefined

 # Verbosity.
jinganix commented 2 years ago

fixed, please refer to ep_issue_29_tests