How to use ndr_pull_struct_blob?

tridge at samba.org tridge at samba.org
Sat Jan 1 18:14:18 MST 2011


Hi Volker,

 > that I can't solve easily:
 > 
 > ==49827== Invalid read of size 1
 > ==49827==    at 0x85F6E39: make_dc_info_from_cldap_reply (dsgetdcname.c:740)
 > ==49827==    by 0x85F8519: dsgetdcname (dsgetdcname.c:357)
 > ==49827==    by 0x80FFF02: net_lookup_dsgetdcname (net_lookup.c:419)
 > ==49827==    by 0x8100A81: net_lookup (net_lookup.c:460)
 > ==49827==    by 0x8117EE0: net_run_function (net_util.c:585)
 > ==49827==    by 0x80E86AE: main (net.c:933)
 > ==49827==  Address 0x66b110 is 48 bytes inside a block of size 49 free'd
 > ==49827==    at 0x58CDC: free (in /usr/local/lib/valgrind/vgpreload_memcheck-x86-freebsd.so)
 > ==49827==    by 0x862E786: _talloc_free_internal (talloc.c:699)
 > ==49827==    by 0x862E713: _talloc_free_internal (talloc.c:652)
 > ==49827==    by 0x83BB0C3: ndr_pull_struct_blob (ndr.c:873)
 > ==49827==    by 0x85F8409: dsgetdcname (dsgetdcname.c:348)
 > ==49827==    by 0x80FFF02: net_lookup_dsgetdcname (net_lookup.c:419)
 > ==49827==    by 0x8100A81: net_lookup (net_lookup.c:460)
 > ==49827==    by 0x8117EE0: net_run_function (net_util.c:585)
 > ==49827==    by 0x80E86AE: main (net.c:933)

This means that a ndr function is allocating memory for a structure
element on ndr instead of on ndr->current_mem_ctx. From your
backtrace, the culprit seems to be ndr_pull_nbt_string(), which
allocates on ndr via both talloc_strdup() and ndr_pull_component().

It seems to be a pretty common mistake in our hand-written
ndr_pull_*() functions. 

If you fix the ones in nbtname.c to use ndr->current_mem_ctx then the
above error should go away, but that still leaves us with the problem
of finding all the other places where this mistake has been made.

One approach might be to talloc_free() all of the ndr_token_list
elements in the ndr_pull structure at the end of every
ndr_pull_struct_blob(), then check that talloc_total_blocks(ndr) is
1. If it isn't then that indicates that something has allocated a
child of ndr in the pull function. So we could have an assert on that
block count that will find the bug without needing valgrind. If we ran
our full test suite with that, we should find all (most?) of the
instances of this bug pretty quickly.

Cheers, Tridge


More information about the samba-technical mailing list