Segmentation fault - Invalid free unresolved - C - c

Error
Program received signal SIGSEGV, Segmentation fault.
0x007068ef in _int_malloc () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install IV_prepaid_oam-37beta-1433949053.x86_64
(gdb) where
#0 0x007068ef in _int_malloc () from /lib/libc.so.6
#1 0x00707d9e in malloc () from /lib/libc.so.6
#2 0x00642fe8 in XtMalloc () from /usr/lib/libXt.so.6
#3 0x0097783f in XmTextFieldGetString () from /usr/lib/libXm.so.4
#4 0x080ee9c1 in check_code (w=0x839d588, client_data=0x0,
call_data=0xffffaf1c) at debit_rt.c:2026
#5 0x006435c6 in XtCallCallbackList () from /usr/lib/libXt.so.6
#6 0x0097637a in ?? () from /usr/lib/libXm.so.4
#7 0x0097fdbe in ?? () from /usr/lib/libXm.so.4
#8 0x00669d96 in ?? () from /usr/lib/libXt.so.6
#9 0x0066a72a in XtSetValues () from /usr/lib/libXt.so.6
#10 0x0067d92a in XtVaSetValues () from /usr/lib/libXt.so.6
#11 0x080eea0d in check_code (w=0x839d588, client_data=0x0,
call_data=0xffffba8c) at debit_rt.c:2030
#12 0x006435c6 in XtCallCallbackList () from /usr/lib/libXt.so.6
#13 0x0097637a in ?? () from /usr/lib/libXm.so.4
#14 0x00981fea in XmTextFieldSetString () from /usr/lib/libXm.so.4
#15 0x00982454 in ?? () from /usr/lib/libXm.so.4
#16 0x0092ab39 in XmTextSetString () from /usr/lib/libXm.so.4
#17 0x080eb19d in set_widget_val (w=0x839d588, val=0x84b8ce0 "000024390")
at debit_rt.c:628
#18 0x080eb2fe in display_rate (btn_num=0) at debit_rt.c:654
#19 0x080ed448 in redraw_rate_table (table_num=100, table_type=66 'B',
reread=1) at debit_rt.c:1428
#20 0x080ee716 in rt_modify2 () at debit_rt.c:1928
#21 0x080c97a6 in apply_cb (w=0x84958d0, client_data=0x0,
call_data=0xffffc0a4) at debit_cbs.c:1823
...
Details
To make sure what the problem was I did a memory check:
==26407== Invalid free() / delete / delete[] / realloc()
==26407== at 0x4026CAF: free (vg_replace_malloc.c:446)
==26407== by 0x642E51: XtFree (in /usr/lib/libXt.so.6.0.0)
==26407== by 0x97658C: ??? (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x981FE9: XmTextFieldSetString (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x982453: ??? (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x92AB38: XmTextSetString (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x80EB196: set_widget_val (debit_rt.c:628)
==26407== by 0x80EB2F7: display_rate (debit_rt.c:654)
==26407== by 0x80ED441: redraw_rate_table (debit_rt.c:1428)
==26407== by 0x80EE70F: rt_modify2 (debit_rt.c:1928)
==26407== by 0x80C97A5: apply_cb (debit_cbs.c:1823)
==26407== by 0x643630: XtCallCallbackList (in /usr/lib/libXt.so.6.0.0)
==26407== Address 0x7f01380 is 0 bytes inside a block of size 6 free'd
==26407== at 0x4026CAF: free (vg_replace_malloc.c:446)
==26407== by 0x642E51: XtFree (in /usr/lib/libXt.so.6.0.0)
==26407== by 0x80EEA16: check_code (debit_rt.c:2031)
==26407== by 0x6435C5: XtCallCallbackList (in /usr/lib/libXt.so.6.0.0)
==26407== by 0x976379: ??? (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x981FE9: XmTextFieldSetString (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x982453: ??? (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x92AB38: XmTextSetString (in /usr/lib/libXm.so.4.0.3)
==26407== by 0x80EB196: set_widget_val (debit_rt.c:628)
==26407== by 0x80EB2F7: display_rate (debit_rt.c:654)
==26407== by 0x80ED441: redraw_rate_table (debit_rt.c:1428)
==26407== by 0x80EE70F: rt_modify2 (debit_rt.c:1928) I
Possible causes
And according to Valgrind official documentation:
4.2.4. Illegal frees
For example:
Invalid free()
at 0x4004FFDF: free (vg_clientmalloc.c:577)
by 0x80484C7: main (tests/doublefree.c:10)
Address 0x3807F7B4 is 0 bytes inside a block of size 177 free'd
at 0x4004FFDF: free (vg_clientmalloc.c:577)
by 0x80484C7: main (tests/doublefree.c:10)
Memcheck keeps track of the blocks allocated by your program with
malloc/new, so it can know exactly whether or not the argument to
free/delete is legitimate or not. Here, this test program has freed
the same block twice. As with the illegal read/write errors, Memcheck
attempts to make sense of the address freed. If, as here, the address
is one which has previously been freed, you will be told that -- making
duplicate frees of the same block easy to spot. You will also get this
message if you try to free a pointer that doesn't point to the start
Code
As you can see, I only free after checking if it is NOT NULL.
void check_code( w, client_data, call_data )
Widget w;
caddr_t client_data;
XmTextVerifyCallbackStruct *call_data;
{
char *str;
char *test_str;
test_str = (w==rt_source) ? ANY_SOURCE_STRING : ANY_DEST_STRING;
/* If the new value is the special string, then allow it */
/* Note it will always be replacing any old contents */
if( call_data->text->ptr != NULL )
if( strcmp( call_data->text->ptr, test_str ) == 0 )
return;
/* If the old value of the text widget was the special string, */
/* delete it and replace it with any new string */
str = XmTextFieldGetString( w ); /* This get string tries to allocate memory */
if( strcmp( str, test_str ) == 0 )
if( call_data->text->ptr != NULL ) /* Make sure it exist before freeing */
{
XtVaSetValues( w, XmNvalue, call_data->text->ptr, NULL ); /* Existis, so, pointing incorr. */
XtFree( call_data->text->ptr ); /* Same as above line */
call_data->text->length = 0;
}
else
XtVaSetValues( w, XmNvalue, "", NULL );
XtFree( str );
/* Perform the normal check for new contents (GPRS allows characters) */
if ( rt_type == VOICE_RT )
check_digits( w, client_data, call_data );
}
Evaluation (personal)
Since I'm checking for existence, the problem seems to be the pointer not pointing to the start of the heap block.
Running gdb more times, the problem is found in different parts, but it always comes to the Invalid Free problem.
Given the context, my questions are:
How can I make sure the pointer is pointing correctly in this case?
What do you think is the cause of this problem?

It's being not null doesn't guarantee that it's a valid allocated memory.
We need more context to understand the exact problem.
But, when you free the memory the pointer keeps storing the invalid address, as the pointer is passed by value to the free function, as you can see a better explanation here.
Based on that my guess is that you are trying to free the same pointer twice.
A temporary hack would be to manually set the pointer to null after free it, so you can better isolate the problem and try to find the real root of that:
if( strcmp( str, test_str ) == 0 )
if( call_data->text->ptr != NULL ) /* Make sure it exist before freeing */
{
XtVaSetValues( w, XmNvalue, call_data->text->ptr, NULL ); /* Existis, so, pointing incorr. */
XtFree( call_data->text->ptr ); /* Same as above line */
call_data->text->ptr = NULL;
call_data->text->length = 0;
}

Related

Valgrind: Conditional jump depends on uninitialised value(s) created by a stack allocation

When debugin my code, I'm getting a series of strange errors in Valgrind. The errors are all of the same type: "Conditional jump or move depends on uninitialised value(s) at ... Uninitialised value was created by a stack allocation at ...".
Example of valgrind output:
==153367== Thread 6:
==153367== Conditional jump or move depends on uninitialised value(s)
==153367== at 0x14B393: serializeNewAnnounce (topology_discovery.c:1146)
==153367== by 0x1494A2: upon_AnnounceTimer (topology_discovery.c:360)
==153367== by 0x148D87: topology_discovery_main_loop (topology_discovery.c:189)
==153367== by 0x49EB608: start_thread (pthread_create.c:477)
==153367== by 0x4B27102: clone (clone.S:95)
==153367== Uninitialised value was created by a stack allocation
==153367== at 0x14AB00: serializeNewAnnounce (topology_discovery.c:1076)
==153367==
==153367== Conditional jump or move depends on uninitialised value(s)
==153367== at 0x14B3CC: serializeNewAnnounce (topology_discovery.c:1204)
==153367== by 0x1494A2: upon_AnnounceTimer (topology_discovery.c:360)
==153367== by 0x148D87: topology_discovery_main_loop (topology_discovery.c:189)
==153367== by 0x49EB608: start_thread (pthread_create.c:477)
==153367== by 0x4B27102: clone (clone.S:95)
==153367== Uninitialised value was created by a stack allocation
==153367== at 0x14AB00: serializeNewAnnounce (topology_discovery.c:1076)
At a frist glance, this error seems to indicate that I forgot to initialize some memory.
However, up verifying several times, I can't find where exactly is the source of these errors.
The code is huge and with several functions, so I filtered only the important parts:
...
148 topology_discovery_state* state = malloc(sizeof(topology_discovery_state));
149 memset(state, 0, sizeof(topology_discovery_state));
...
260 state->neighbors = double_list_init(); // neighbors is a malloc and initializes head as NULL
...
... // The following code is within a single function, the previous is on another function
...
1047 unsigned int horizon = state->proto_args.horizon;
...
1050 unsigned char ptrs[horizon+1];
1051 memset(ptrs, 0, sizeof(ptrs));
...
1076 for(double_list_item* current_item = state->neighbors->head; current_item; current_item = current_item->next) {
1077 neighbor* current_neigh = (neighbor*) current_item->data;
...
1106 for(int h = 0; h <= horizon; h++) {
1107 ptrs[h] = levels[h]->size + ptrs[h-1];
1108 }
...
1145 int processed = 0;
1146 for(int h = 0; h <= horizon; h++) {
1147 int level_size = ptrs[h];
1148 int level_start = h == 0 ? 0 : ptrs[h-1];
1149 for(int node = level_start; node < level_size; node++) {
...
Only state is not a local variable and is passed as a parameter, the rest is all local to the same function.
At line 1107, in the first iteration, ptrs get index -1. Since in C array is actually a memory location and index interprete as pointer arithmetic, the result is access to the memory location that is one byte before ptrs, which is of course not initialized.

Heap exploit fails: Memory corruption

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?

Valgrind, "uninitialized value(s)" error

In my C program, I'm allocating memory using malloc() which does, in contrast to calloc(), not initialize the memory and it might still contain garbage. Mostly, in context of the allocation, I do not make any changes to the memory allocated by malloc(). (For example in a function to initialize a struct that contains a buffer, I do not make changes to the buffer's memory, but later on).
Valgrind gives me a lot of theese errors:
Conditional jump or move depends on uninitialised value(s)
Use of uninitialised value of size 4
I am sure to never read from memory that was not initialized in these cases.
Should I ignore them or is it better to initialize the memory on allocation? In case I should ignore them, how can I deactivate this error message in Valgrind?
Example 1:
==4253== Conditional jump or move depends on uninitialised value(s)
==4253== at 0x408EB8E: vfprintf (vfprintf.c:1624)
==4253== by 0x4093C2E: printf (printf.c:35)
==4253== by 0x40624D2: (below main) (libc-start.c:226)
==4253== Uninitialised value was created by a heap allocation
==4253== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048938: gk_StreamBufferNode_init (stream.c:101)
==4253== by 0x8048D0D: gk_Stream_bufferWriteProc (stream.c:252)
==4253== by 0x8048665: main (main.c:21)
Code:
int gk_StreamBufferNode_init(gk_StreamBufferNode* node, int buffer_size,
gk_AllocProc malloc) {
node->buffer = malloc(buffer_size); // line 101
if (node->buffer == NULL) {
return GKIT_FAILEDALLOC;
}
node->next = NULL;
return GKIT_NOERR;
}
Example 2:
==4253== Conditional jump or move depends on uninitialised value(s)
==4253== at 0x402DA39: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048C6E: gk_Stream_bufferWriteProc (stream.c:230)
==4253== by 0x8048665: main (main.c:21)
==4253== Uninitialised value was created by a heap allocation
==4253== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048CE0: gk_Stream_bufferWriteProc (stream.c:248)
==4253== by 0x8048665: main (main.c:21)
Code:
/* ... */
int available_bytes = binfo->buffer_size - bnode->filled;
int bytes_to_go = size * count;
int offset = 0;
int node_offset = 0;
gk_StreamBufferNode* new_node;
void* destination = NULL;
void* source = NULL;
while (bytes_to_go > 0) {
destination = bnode->buffer + bnode->filled + node_offset;
source = buffer + offset;
if (available_bytes > bytes_to_go) {
memcpy(destination, source, bytes_to_go); // line 230
bnode->filled += bytes_to_go;
offset += bytes_to_go;
node_offset = bytes_to_go;
bytes_to_go = 0;
}
else {
memcpy(destination, source, available_bytes);
offset += available_bytes;
node_offset = 0;
bytes_to_go -= available_bytes;
bnode->filled += available_bytes;
#ifdef DEBUG
assert(bnode->filled == bnode->buffer_size);
#endif // DEBUG
// Allocate a new buffer node.
new_node = (gk_StreamBufferNode*) malloc(sizeof(gk_StreamBufferNode)); // line 248
if (new_node == NULL) {
return GKIT_FAILEDALLOC;
}
int success = gk_StreamBufferNode_init(new_node, binfo->buffer_size,
malloc);
if (success <= GKIT_ERROR) {
free(new_node);
return GKIT_FAILEDALLOC;
}
bnode->next = new_node;
bnode = new_node;
available_bytes = binfo->buffer_size;
}
}
In both cases you just allocate memory without initializing it. The easiest way is to use calloc instead of malloc to zero it out. This may be a good strategy for simple cases, e.g if you later use a buffer as a string that is to be printed. For more complicated use cases assign values to the individual fields, or even better if you have C99 assign the whole structure from a compound literal:
toto * t = malloc(sizeof(*t));
*t = (toto){ 0 };
Your code should not be expecting uninitialized memory to contain any value, so having conditional jumps dependent on these shows serious problems.
You should either be initializing the memory (to some known value, eg. 0), or not refer to its contents unless they have been initialized.

What does this error mean in Valgrind

When I run my program, I get segmentation fault, so I decided to check it through Valgrind. When I did, I got the following message from Valgrind. And I get the error when I use the code described here. Any idea what is going on here?
==21471== Invalid write of size 8
==21471== at 0x4802511: _vgnU_freeres (vg_preloaded.c:64)
==21471== by 0x38A715397F: ???
==21471== by 0x38A6E4D549: printf (in /lib64/libc-2.5.so)
==21471== by 0x401D52: call_func(int) (replication.cpp:752)
==21471== by 0x6137C7: ???
==21471== by 0x40621C: AdvanceFramesMT(void*) (pthreads.cpp:1020)
==21471== by 0x38A7A0673C: start_thread (in /lib64/libpthread-2.5.so)
==21471== by 0x38A6ED44BC: clone (in /lib64/libc-2.5.so)
==21471== Address 0x612ba8 is 14216 bytes inside data symbol "func_stack"
Code
static char func_stack[16384];
static ucontext_t uctx_main[16], uctx_func[16];
void call_func( int n )
{
printf( "Message %d!", n );
}
if (getcontext(&uctx_func[tid]) == -1)
handle_error("getcontext");
uctx_func[tid].uc_stack.ss_sp = func_stack;
uctx_func[tid].uc_stack.ss_size = sizeof(func_stack);
uctx_func[tid].uc_link = &uctx_main[tid];
makecontext(&uctx_func[tid], (void(*)())call_func, 1, 2);
if (swapcontext(&uctx_main[tid], &uctx_func[tid]) == -1)
handle_error("swapcontext");
Try to improve Valgrind stack traces - this will hopefully help to understand the problem. Are you using -fomit-frame-pointer or -fstack-check gcc options? This can make Valgrind stack traces worse (with ??? symbols instead of names) Valgrind FAQ.
OK, I got it now. Actually I was using this for multiple threads. That is why uctx_main[16] and uctx_func[16] are arrays. However, I forgot to make func_stack also an array (a 2-dimensional array in fact). So I changed it to char func_stack[16][16384] and it solved the problem.

*** glibc detected *** free(): invalid next size (fast) -- should work? [duplicate]

This question already has answers here:
Facing an error "*** glibc detected *** free(): invalid next size (fast)"
(2 answers)
Closed 8 years ago.
I'm working on an existing c project (spglib on sourceforge), and I'm running into the following problem after cleaning up some array initializations:
* glibc detected * tests/spglibtest: free(): invalid next size (fast): 0x08ab46e0 ***
The backtrace is:
#0 0xb7fe1424 in __kernel_vsyscall ()
#1 0xb5cfdd61 in raise () from /lib/libc.so.6
#2 0xb5cff5ee in abort () from /lib/libc.so.6
#3 0xb5d397ed in ?? () from /lib/libc.so.6
#4 0xb5d3f7b1 in ?? () from /lib/libc.so.6
#5 0xb5d4052b in ?? () from /lib/libc.so.6
#6 0xb5d441cd in free () from /lib/libc.so.6
#7 0xb6681484 in sym_get_multiplicity (cell=0xbfffe1f0, symprec=0.050000000000000003) at /git/xtalopt-public/src/spglib/symmetry.c:168
#8 0xb6680550 in spg_find_primitive (lattice=0xbfffe2a8, position=0x813c6f0, types=0x813c700, num_atom=2, symprec=0.050000000000000003)
at /git/xtalopt-public/src/spglib/spglib.c:253
The error is in the "free(trans)" line below:
int sym_get_multiplicity(const Cell *cell, const double symprec)
{
int i, rc;
double **trans;
trans = (double**)malloc(cell->size * sizeof(double*));
for (i = 0; i < cell->size; i++) {
trans[i] = (double*)malloc(3 * sizeof(double));
}
rc = get_translation(&trans[0][0], identity, cell, symprec);
for (i = 0; i < cell->size; i++) {
free(trans[i]);
}
free(trans);
return rc;
}
get_translation assigns values to trans like so:
static int get_translation(double trans[][3], const int rot[3][3], const Cell *cell,
const double symprec)
{
...
for (j = 0; j < 3; j++) {
trans[num_trans][j] = someDouble;
}
...
}
Valgrind is showing the following when writing to the array in get_translation:
==17929== Invalid write of size 8
==17929== at 0x56BE8A7: get_translation (symmetry.c:285)
==17929== by 0x56BE44B: sym_get_multiplicity (symmetry.c:163)
...
==17929== Address 0x9cb5868 is 0 bytes after a block of size 8 alloc'd
==17929== at 0x4024918: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==17929== by 0x56BE3F7: sym_get_multiplicity (symmetry.c:158)
....
This suggests to me that it's trying to write past the end of the allocated memory for trans, but it's writing to trans[0][0], and trans is of dimension [2][3]. This should work, AFAIK, can anyone see something that I'm missing?
Your types are wrong, you can't pass a pointer to an array of pointers to a function expecting an array of arrays (i.e. a pointer to an array).
For the signature of get_translation that you have, you need:
double (*trans)[3] = malloc(cell->size * sizeof(double[3]));
SO here is perhaps one problem. Your function seems to assume (based on) trans[num_trans][j] = someDouble; that trans is in fact an array laid out sequentially which as I mentioned above is not true in this case. You are allocating an array of pointers rather than a 2 dimensional array. Something similar to
double* trans = malloc(cell->size * 3); might be better. In general you might want to use a 1d array instead of a 2d one and just use it as 2 dimensional array.

Resources