On 04/01/2011 10:29 AM, marius zbihlei wrote:
On 03/31/2011 07:52 PM, Timo Teräs wrote:
Hi all,
I'm running 3.1-branch git head currently under valgrind. And I've seen
several invalid reads and writes (apparently most are off by one).
Hello,
I haven't used Valgrind memcheck tool for Kamailio , but from what I
know it might not be that useful. What Valgrind does it hooks into the
memory allocation functions like malloc/calloc/realloc/alloca and keeps
track of said allocation. Because, by default, Kamailio uses it's own
memory manager (both for private memory or shared), this messes up on
how Valgrind can keep track of its allocation/deallocation.
It does not make valgrind useless. Basically, it just makes valgrind not
detect all errors. Any errors it does detect, should be valid.
I don't know if there is a way to make Valgrind to
work reliable with K
memory managers, but I will take a look on the cases you provide just to
be sure.
There are valgrind hooks for memory managers. Should probably add them,
so it becomes aware of the things. However, those should be only needed
for memory pools. Ultimately kamailio uses malloc or mmap to allocate
the memory and valgrind knows both.
As a side note, I had uses static analysis tools quite
succesfully on
3.1 . I had use clang analyzer from the llvm suite. There are still some
outstanding bugs which I didn't had time to look at.
Looks like all my bugs are related to pvars and kamailio modules.
The first really evil programming mistake I found is at:
modules_k/textops/txtvar.c:tr_txt_eval_re()
In line 86, it will fills the transformed variable with tr_txt_buf and
returns that. However, that is a stack variable, which will get
corrupted pretty soon after function return. I'm not sure how to fix
this properly.
Marius
> ==22274== Invalid read of size 1
> ==22274== at 0x6DA2C0A: pv_set_ruri_user (pv_core.c:1755)
> ==22274== by 0x13BA15: lval_pvar_assign (lvalue.c:357)
> ==22274== by 0x13BF0F: lval_assign (lvalue.c:405)
> ==22274== by 0x139E4D: do_action (action.c:1472)
> ==22274== by 0x13A6F1: run_actions (action.c:1555)
> ==22274== by 0x12FDEB: do_action (action.c:711)
> ==22274== by 0x13A6F1: run_actions (action.c:1555)
> ==22274== by 0x13A86F: run_actions_safe (action.c:1607)
> ==22274== by 0x1E2666: rval_get_int (rvalue.c:904)
> ==22274== by 0x1E5252: rval_expr_eval_int (rvalue.c:1866)
> ==22274== by 0x131B8A: do_action (action.c:1071)
> ==22274== by 0x13A6F1: run_actions (action.c:1555)
>
> Is fairly obvious. modules_k/pv/pv_core.c has several places which take
> backup of "val->rs.s[val->rs.len]" and replaces it with zero for
string
> termination. It's than later on set back to the original value. However,
> it would appear that the value passed does not always point to a memory
> area which is large enough. This results in multiple invalid reads and
> writes of one.
I fixed this by making a temporary copy of the string data to local
stack variable and null terminating it there. That made valgrind happy.
So obviously pv_set_ruri_user and others, are called with strings that
are allocated for the exact length, and the hacky zero-termination
cannot be used in this module.
> The remaining reads are not so clear to me.
I'm analysing the rest problems. Seems that they are almost always
related to using re.subst, which has the problem mentioned in the
beginning of the mail.
- Timo