Hi, On Tue, Oct 22, 2013 at 02:13:36PM +0200, Gert Doering wrote: > On Tue, Oct 22, 2013 at 01:40:18PM +0200, Gert Doering wrote:
(I seem to be talking to myself a lot, lately...)
> > I could use some ideas on how to debug this further - if valgrind isn't
> > complaining, normally our memory management should be OK, but why is
> > VSZ/RSZ still growing, then...?
>
> Arne brought up a good point. If we "lose" the memory inside the gc_*
> functions (as in: use the same gc block for a very long time, like
> "while OpenVPN runs", but *do* free it at the end), valgrind might not
> be able to see it - after all, we nicely cleaned up later - but we'll
> still grow out of bounds at runtime.
... and *that* seems to be the issue here. I've instrumented the gc_arena
to have a creation time (time_t) and a use_count, and the only one that
shows up at renegotiation time is the gc inside the "environment set",
with this call chain... (included for those that are curious :-) ).
#3 0x080714e8 in add_env_item (str=0x811287c "untrusted_ip6=::ffff:127.0.0.1",
do_alloc=true, list=0x80fc500,
gc=0x810a65c) at ../../../openvpn-testing/src/openvpn/misc.c:553
#4 0x0807156a in env_set_add_nolock (es=0x80fc4fc, str=0x811287c
"untrusted_ip6=::ffff:127.0.0.1")
at ../../../openvpn-testing/src/openvpn/misc.c:568
#5 0x080716b2 in env_set_add (es=0x80fc4fc, str=0x811287c
"untrusted_ip6=::ffff:127.0.0.1")
at ../../../openvpn-testing/src/openvpn/misc.c:613
#6 0x08071b96 in setenv_str_ex (es=0x80fc4fc, name=0xbfffd430 "untrusted_ip6",
value=0xbfffd3b0 "::ffff:127.0.0.1", name_include=32772, name_exclude=0,
name_replace=0 '\000',
value_include=128, value_exclude=0, value_replace=0 '\000') at
../../../openvpn-testing/src/openvpn/misc.c:784
#7 0x080719d6 in setenv_str (es=0x80fc4fc, name=0xbfffd430 "untrusted_ip6",
value=0xbfffd3b0 "::ffff:127.0.0.1")
at ../../../openvpn-testing/src/openvpn/misc.c:735
#8 0x080b1a7a in setenv_sockaddr (es=0x80fc4fc, name_prefix=0x80e2139
"untrusted", addr=0x810b20c, flags=1)
at ../../../openvpn-testing/src/openvpn/socket.c:2396
#9 0x080b1b7e in setenv_link_socket_actual (es=0x80fc4fc,
name_prefix=0x80e2139 "untrusted", act=0x810b20c,
flags=1) at ../../../openvpn-testing/src/openvpn/socket.c:2426
#10 0x080bde24 in setenv_untrusted (session=0x810b19c) at
../../../openvpn-testing/src/openvpn/ssl_verify.c:74
#11 0x080bf07a in verify_cert (session=0x810b19c, cert=0x812fa50, cert_depth=0)
at ../../../openvpn-testing/src/openvpn/ssl_verify.c:667
#12 0x080c050e in verify_callback (preverify_ok=1, ctx=0xbfffd748)
at ../../../openvpn-testing/src/openvpn/ssl_verify_openssl.c:84
Preliminary analysis: the problematic code seems to be
env_set_add_nolock (struct env_set *es, const char *str)
{
remove_env_item (str, es->gc == NULL, &es->list);
add_env_item ((char *)str, true, &es->list, es->gc);
}
... because add_env_item() will (have to) do...
add_env_item (char *str, const bool do_alloc, struct env_item **list, struct
gc_arena *gc)
{
...
ALLOC_OBJ_GC (item, struct env_item, gc);
item->string = do_alloc ? string_alloc (str, gc): str;
item->next = *list;
*list = item;
...
}
so while the environment list itself is not growing out of bounds, the
gc_arena used for storing the local copy of the string is (because these
are only ever cleaned up if gc_free() is destroying the whole arena,
which for *this* one is only happening at program end).
OTOH, the whole thing looks like it would work perfectly if es->gc
were just NULL (string_alloc() would then call malloc() instead, and
remove_env_item() would call free()). So maybe this can be solved fairly
easily without rewriting all of this...
(Doing this in a train which will arrive soon -> digging deeper on my
way back)
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]
fax: +49-89-35655025 [email protected]
pgpIN7AfTOVa8.pgp
Description: PGP signature
