Description of problem: running ypxfr cause core dump Version-Release number of selected component (if applicable): How reproducible: run ypxfr Steps to Reproduce: 1. 2. 3. Actual results: core dumps Expected results: transfer ypmaps Additional info: Here is running gdb outputs: (gdb) bt #0 0x00000036f07f021f in xdr_string_internal () from /lib64/libc.so.6 #1 0x00000036f07eafbc in clntudp_call () from /lib64/libc.so.6 #2 0x0000000000403551 in ypproc_master_2 (argp=Variable "argp" is not available. ) at ypxfr_clnt.c:45 #3 0x0000000000402359 in ypxfr (map=0x7fffffc7eb77 "protocols.byname", source_host=0x7fffffc7eb49 "fspd1.aoa.twosigma.com", source_domain=0x7fffffc7eb66 "nyc.twosigma.com", target_domain=0x7fffffc7eb66 "nyc.twosigma.com", noclear=1, force=1) at ypxfr.c:423 #4 0x0000000000403180 in main (argc=Variable "argc" is not available. ) at ypxfr.c:839 #5 0x00000036f071c4cc in __libc_start_main () from /lib64/libc.so.6 #6 0x0000000000401ce9 in _start () #7 0x00007fffffc7cac8 in ?? () #8 0x0000000000000000 in ?? () diassemble ... 0x00000036f07f0218 <xdr_string_internal+168>: test %rbx,%rbx 0x00000036f07f021b <xdr_string_internal+171>: je 0x36f07f0265 <xdr_string_internal+245> 0x00000036f07f021d <xdr_string_internal+173>: mov %edx,%eax 0x00000036f07f021f <xdr_string_internal+175>: movb $0x0,(%rax,%rbx,1) 0x00000036f07f0223 <xdr_string_internal+179>: mov 0x14(%rsp),%edx 0x00000036f07f0227 <xdr_string_internal+183>: mov %rbx,%rsi 0x00000036f07f022a <xdr_string_internal+186>: mov %rbp,%rdi ...
I have not debugged it, but from skimming the source that sounds like ypxfr bug. Both xdr_ypresp_order and xdr_ypresp_master fill in strings read from network, with xdr_string and ~0 as the maxsize. xdr_string allocates a new string with malloc if the pointer passed to it is NULL, but otherwise will assume the pointer passed to it points to a valid buffer, at least maxsize bytes long. So, before xdr_ypresp_order or xdr_ypresp_master is called, the structure passed to it must be cleared and it is caller's responsibility to do so. E.g. libc/nis/ypclnt.c when it uses these functions internally, it clears the memory; ypclnt.c (ypmaster) has: ypresp_master resp; ... memset (&resp, '\0', sizeof (ypresp_master)); ... result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey, (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp); Now, ypxfr in ypxfr.c passes uninitialized memory to those: struct ypresp_order resp_order; struct ypresp_master resp_master; ... if (ypproc_master_2 (&req_nokey, &resp_master, clnt_udp) != RPC_SUCCESS) ... if (ypproc_order_2 (&req_nokey, &resp_order, clnt_udp) != RPC_SUCCESS) So, if you are lucky and the stack contains zeros in the right places, it will not crash, otherwise it will.
so this fixed it: --- ypxfr.c_ 2005-06-21 19:44:12.000000000 -0400 +++ ypxfr.c 2005-06-21 19:42:19.000000000 -0400 @@ -420,6 +420,7 @@ server name for the map on the master host. */ req_nokey.domain = source_domain; req_nokey.map = map; + memset (&resp_master, '\0', sizeof (ypresp_master)); if (ypproc_master_2 (&req_nokey, &resp_master, clnt_udp) != RPC_SUCCESS) { log_msg (clnt_sperror (clnt_udp, "ypproc_master_2"));
There is memset (&resp_order, '\0', sizeof (resp_order)); needed somewhere before ypproc_order_2 call as well.
is this a spec change on libc? which calls for a behavior change on the caller? the same ypxfr code works fine for previous version of libc.
No, it is not. glibc (and other sunrpc implementations) have always behaved that way. You might be lucky and see NULL in the right place on the stack when you don't trigger it.
fair enough, so let's fix ypxfr, thanks for your help
I've put a fix for this into fc4 testing updates. Can you please test this package and verify that it fixes the problem? It's ypserv-2.13-7. http://download.fedora.redhat.com/pub/fedora/linux/core/updates/testing/4/
This bug also affects i386 and the ypserv in testing fixes it. It would probably be good to get this pushed to updates.
This package has been pushed to final and will be available shortly.