Bug 161217
Summary: | ypxfr crash in libc, xdr_string_internal | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Ben Shi <benjamin.shi> |
Component: | ypserv | Assignee: | Chris Feist <cfeist> |
Status: | CLOSED ERRATA | QA Contact: | |
Severity: | high | Docs Contact: | |
Priority: | medium | ||
Version: | 4 | CC: | edgar.hoch, jakub, steved, sundaram, tjb |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | x86_64 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2005-09-05 05:24:44 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Ben Shi
2005-06-21 14:39:38 UTC
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. |