My application is receiving the segmentation fault. The back trace log -
Program received signal SIGSEV, Segmentation fault.
0x00000000004a5c03 in engine_unlocked_finish ()
(gdb) bt
#0 0x00000000004a5c03 in engine_unlocked_finish ()
#1 0x00000000004a5d71 in ENGINE_finish ()
#2 0x000000000046a537 in EVP_PKEY_free_it ()
#3 0x000000000046a91b in EVP_PKEY_free ()
#4 0x00000000004b231a in pubkey_cb ()
#5 0x0000000000470c97 in asn1_item_combine_free ()
#6 0x0000000000750f70 in X509_CINF_seq_tt ()
#7 0x00000000010f7d90 in ?? ()
#8 0x00000000010f7cf0 in ?? ()
#9 0x0000000000000000 in ?? ()
The stackframe at #9 is interesting. It's address is 0x0000000000000000. Does this mean stack got corrupted even before getting to engine_unlocked_finish () ?
The stackframe at #9 is interesting.
Not really. What's most likely happening is that X509_CINF_seq_tt is hand-coded assembly, and lacks correct unwind descriptors, so everything after it in the stack trace is just bogus.
In fact, looking at this source, X509_CINF_seq_tt is not even a function, so it's probably asn1_item_combine_free that starts the "bad unwind".
Related
So this is a follow up to my previous Question
I am trying to build a legacy codebase with Address Sanitizer. As soon as I run the binary, I get a Segmentation Fault.
==2940167==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000002aa79a0 at pc 0x000000d6aaf4 bp 0x7fffe7244140 sp 0x7fffe7244130
READ of size 4 at 0x000002aa79a0 thread T3
Thread 1 "block_hk.xcg." received signal SIGSEGV, Segmentation fault.
Here is the trace with gdb:
#0 0x00007ffff6f0dc26 in __sanitizer::internal_strlen(char const*) () from /lib64/libasan.so.5
#1 0x00007ffff6e57208 in printf_common(void*, char const*, __va_list_tag*) () from /lib64/libasan.so.5
#2 0x00007ffff6e59566 in vsnprintf () from /lib64/libasan.so.5
#3 0x00007ffff540ed5c in ?? () from /lib64/libdus.so
#4 0x00007ffff540f017 in ?? () from /lib64/libdus.so
#5 0x00007ffff540f860 in ?? () from /lib64/libdus.so
#6 0x00007ffff541a443 in logPrint () from /lib64/libdus.so
#7 0x00007ffff4761734 in mcsCreateSem () from /lib64/libcwl.so
#8 0x00007ffff4764b14 in mcsInitialize () from /lib64/libcwl.so
#9 0x00007ffff47678fc in cwlAppRunCPP () from /lib64/libcwl.so
#10 0x000000000112d719 in main (argc=1, argv=0x7ffffffe7478) at ./src/main.c:755
get the encode_audio.c example from ffmpeg, which converts in-memory raw PCM data to MP2
compile
gcc -o encode_audio encode_audio.c -I/usr/include/x86_64-linux-gnu/libavcodec -lavformat -lavcodec -lavutil -lm
check that is works with the MP2 encoder -> OK
change the encoder to codec = avcodec_find_encoder(AV_CODEC_ID_ADPCM_G722);
adapt the output parameters to g722
c->sample_rate = 16000;//select_sample_rate(codec);
c->channel_layout = AV_CH_LAYOUT_MONO;//select_channel_layout(codec);
c->channels = 1; //av_get_channel_layout_nb_channels(c->channel_layout);
recompile, test... crash!
#0 0x00007ffff5cd5e97 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff5cd7801 in __GI_abort () at abort.c:79
#2 0x00007ffff5d20897 in __libc_message (action=action#entry=do_abort, fmt=fmt#entry=0x7ffff5e4db9a "%s\n")
at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007ffff5d2790a in malloc_printerr (str=str#entry=0x7ffff5e4f800 "free(): invalid next size (fast)")
at malloc.c:5350
#4 0x00007ffff5d2a078 in _int_free (have_lock=<optimized out>, p=<optimized out>, av=<optimized out>)
at malloc.c:4213
#5 0x00007ffff5d2a078 in __GI___libc_free (mem=<optimized out>) at malloc.c:3124
#6 0x00007ffff5d2a078 in tcache_thread_shutdown () at malloc.c:2969
#7 0x00007ffff5d2a078 in arena_thread_freeres () at arena.c:950
#8 0x00007ffff5d2c55a in _int_memalign (av=0x7ffff6082c40 <main_arena>, alignment=32, bytes=<optimized out>)
at malloc.c:4750
#9 0x00007ffff5d31e43 in _mid_memalign (address=<optimized out>, bytes=40, alignment=<optimized out>)
at malloc.c:3305
#10 0x00007ffff5d31e43 in __posix_memalign (memptr=0x7fffffffd720, alignment=<optimized out>, size=40)
at malloc.c:5369
#11 0x00007ffff6457663 in av_malloc () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#12 0x00007ffff645798d in av_mallocz () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#13 0x00007ffff643b89d in av_buffer_create () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#14 0x00007ffff643be40 in av_buffer_realloc () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#15 0x00007ffff6848efa in av_packet_ref () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#16 0x00007ffff68f8474 in avcodec_encode_audio2 () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#17 0x00007ffff68f8af9 in () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#18 0x00007ffff68f8c5a in avcodec_send_frame () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#19 0x0000555555555085 in encode ()
#20 0x00005555555555a2 in main ()
Hmm... what am I missing?
Solution:
The code encoding a single ton sound is explicitly written for stereo channel layout. Reducing to one channel avoid the buffer overflow.
samples = (uint16_t*)frame->data[0];
for (j = 0; j < c->frame_size; j++)
{
samples[j] = (int)(sin(t) * 10000);
for (k = 1; k < c->channels; k++)
samples[j + k] = samples[j];
t += tincr;
}
Currently learning heap exploitation but there is something weird I don't understand:
This is the next chunk to be allocated by a call to malloc(0x80):
0x602090: 0x0000000000000000 0x0000000000000091
0x6020a0: 0x00007ffff7dd1b78 0x0000000000601120
...
Calling another malloc(0x80) after this, my goal is to get back 0x601130. This works, but only if 0x601128 == 0x90:
0x601120: 0x0000000000602010 0x0000000000000090
0x601130: 0x0000000000602130 0x00000000006021c0
If I change 90 to any other value, I get memory corruption:
*** Error in `censored': malloc(): memory corruption: 0x00000000006021d0 **
...
#0 0x00007ffff7a42428 in __GI_raise (sig=sig#entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff7a4402a in __GI_abort () at abort.c:89
#2 0x00007ffff7a847ea in __libc_message (do_abort=0x2, fmt=fmt#entry=0x7ffff7b9de98 "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff7a8f13e in malloc_printerr (ar_ptr=0x7ffff7dd1b20 <main_arena>, ptr=0x6021d0,
str=0x7ffff7b9acff "malloc(): memory corruption", action=<optimized out>) at malloc.c:5006
#4 _int_malloc (av=av#entry=0x7ffff7dd1b20 <main_arena>, bytes=bytes#entry=0x80) at malloc.c:3474
Here is the code in GLIBC_2.2.5, at malloc:3474:
bck = victim->bk;
if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (chunksize_nomask (victim)
> av->system_mem, 0))
malloc_printerr (check_action, "malloc(): memory corruption",
chunk2mem (victim), av);
size = chunksize (victim);
Now, from what I've read and my understanding of this code, the victim chunksize should be bigger than 2 * SIZE_SZ (so bigger than 16 bytes in 64bits) and smaller than av->system_mem. Here av->system_mem is equal to:
gdb-peda$ p av->system_mem
$1 = 0x21000
So I would expect any value between 0x10 and 0x21000 to pass that checks. Why does it not?
I'm trying to use Gstreamer in a C program.
I use udpsrc so I have to put caps :
GstCaps *caps = gst_caps_new_empty_simple("application/x-rtp");
With this, I get an Segmentation fault.
So, I've tried with G_DEBUG="fatal_warnings" gdb --args ./test_gst.
Here's the output :
Program received signal SIGSEGV, Segmentation fault.
0x76f010e4 in gst_mini_object_init (mini_object=0x28600, flags=0, type=0, copy_func=0x76ed6174 <_gst_caps_copy>, dispose_func=0x0, free_func=0x76ed5128 <_gst_caps_free>)
at gstminiobject.c:133
133 gstminiobject.c: No such file or directory.
(gdb) bt
#0 0x76f010e4 in gst_mini_object_init (mini_object=0x28600, flags=0, type=0, copy_func=0x76ed6174 <_gst_caps_copy>, dispose_func=0x0, free_func=0x76ed5128 <_gst_caps_free>)
at gstminiobject.c:133
#1 0x76ed57b4 in gst_caps_init (caps=0x28600) at gstcaps.c:209
#2 gst_caps_new_empty () at gstcaps.c:239
#3 0x76ed58f8 in gst_caps_new_empty_simple (media_type=0x110b4 "application/x-rtp") at gstcaps.c:282
#4 0x00010bbc in main ()
I don't know if this can help, but I'm working on a Raspberry PI 3 (raspbian).
I found a similar bug report with Segmentation fault in gst_mini_object_init(). According to this comment you should call gst_init() before using Gstreamer.
Did you call gst_init() before using Gstreamer API ?
I am using RSA_sign() to create dkim signatures. Sometimes , extremely unpredictably the code just crashes
I get a gdb dump like this
Thread 39 (Thread 0x41401940 (LWP 31921)):
#0 0x0000003b9dacc3bb in BN_div () from /lib64/libcrypto.so.6
#1 0x0000003b9daceb40 in BN_mod_inverse () from /lib64/libcrypto.so.6
#2 0x0000003b9dacb609 in BN_BLINDING_create_param () from /lib64/libcrypto.so.6
#3 0x0000003b9dadc9f7 in RSA_setup_blinding () from /lib64/libcrypto.so.6
#4 0x0000003b9daee954 in ?? () from /lib64/libcrypto.so.6
#5 0x0000003b9daef56b in ?? () from /lib64/libcrypto.so.6
#6 0x0000003b9da6e965 in RSA_sign () from /lib64/libcrypto.so.6
#7 0x0000000000403e7f in dkim_create (headers=0x2aaaac001840, headerc=7,
......., v=0) at firm-dkim.c:145
The firm-dkim.c is available here
http://code.google.com/p/firm-dkim/source/browse/trunk/firm-dkim.c
How can I debug this further ?
Thanks
Ram
Ok I think I got the error
The code over here
firm-dkim.c.
Does not allocate any memory for RSA *rsa_private , line 48
And this unallocated memory area is used in RSA_sign() and RSA_free()
I think that must be causing the segfault. I have alloc'ed memory now and I am running the daemon in production. Hopefully no more segfaults now.