|
COMMAND Sun RPC type services remote overflow SYSTEMS AFFECTED All ? PROBLEM Editor's note : Would you think the SUN RPC code is found solely on unix, eh ? ============= ISS X-Force has releases a Security Advisory, where they state to exist a buffer overflow in the 'xdr_array' primitive of the Sun RPC code : http://bvlive01.iss.net/issEn/delivery/xforce/alertdetail.jsp?oid=20823 Update (02 August 2002) ====== Charles Hannum further analyses : The scope of this bug is somewhat limited. It depends on a particular multiplication overflowing: nodesize = c * elsize; In order for this to happen, you must have maxsize>max(nodesize)*elsize; otherwise the c>maxsize check will catch it. Hence the patch: - if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { + if ((c > maxsize || UINT_MAX/elsize < c) && + (xdrs->x_op != XDR_FREE)) { In practice, there are only two ways that this constraint is violated: 1) An application explicitly passes in a large maxsize. I generally consider this an application bug, in the same vain as sending bogus arguments to calloc(), fread()/fwrite() or qsort(). However, amd and various amd utilities -- amd, amq, pawd, and probably others -- pass in a maxsize ~0 (i.e. all-1s) and are therefore susceptible. 2) A program uses rpcgen with unbounded arrays; e.g. in rex.x: rexstring rst_cmd<>; /* list of command and args */ rexstring rst_env<>; /* list of environment */ (Note that nothing in our source tree actually *uses* rex.x, but the same problems occurs in rusers.x.) There are only a few things in our source tree that actually use xdr_array(): /usr/src/dist/am-utils/amd/amq_subr.c /usr/src/dist/am-utils/amq/amq_xdr.c /usr/src/dist/am-utils/libamu/xdr_func.c /usr/src/gnu/dist/toolchain/gdb/vx-share/xdr_ld.c /usr/src/gnu/dist/toolchain/gdb/vx-share/xdr_rdb.c /usr/src/lib/libc/rpc/authunix_prot.c /usr/src/lib/librpcsvc/rnusers.x /usr/obj.i386/lib/librpcsvc/rex.c /usr/obj.i386/lib/librpcsvc/rnusers.c /usr/obj.i386/lib/librpcsvc/rusers.c /usr/obj.i386/usr.sbin/rpc.pcnfsd/pcnfsd_xdr.c The GDB stuff and rex.c are not actually linked into anything. The uses in authunix_prot.c, rnusers.c and pcnfsd_xdr.c are all sufficiently bounded. Ergo, the only vulnerable programs are amd/amq/etc. and rusers (the client, not the server). Update (05 August 2002) ====== david evlis reign found that the kerberos code is vulnerable too : /usr/home/dreign/useless/krb5-1.1-current/src/lib/rpc/xdr_array.c : /* * XDR an array of arbitrary elements * *addrp is a pointer to the array, *sizep is the number of elements. * If addrp is NULL (*sizep * elsize) bytes are allocated. * elsize is the size (in bytes) of each element, and elproc is the * xdr procedure to call to handle each element of the array. */ Further on, in MIT krb5 security advisory : There is an integer overflow bug in the SUNRPC-derived RPC library used by the Kerberos 5 administration system that could be exploited to gain unauthorized root access to a KDC host. It is believed that the attacker needs to be able to authenticate to the kadmin daemon for this attack to be successful. -Also- Ricardo Quesada suspects (all?) releases of libc to be affectecd : glibc-2.2.5/sunrpc/xdr_array.c Update (07 August 2002) ====== FreeBSD advisory [FreeBSD-SA-02:36.nfs] informs that the NFS service is based on SUN RPC, and is also affected by the bug. A part of the NFS server code charged with handling incoming RPC messages had an error which, when the server received a message with a zero-length payload, would cause it to reference the payload from the previous message, creating a loop in the message chain. This would later cause an infinite loop in a different part of the NFS server code which tried to traverse the chain. Update (13 August 2002) ====== From Entercept Ricochet [http://www.entercept.com/news/uspr/08-12-02.asp] we learn that the Tooltalk RPC service found on most mainframe Unix is vulnerable via the _TT_CREATE_FILE procedure. Update (14 August 2002) ====== Martin Schulze in Debian Security advisory [DSA 149-1] [http://www.debian.org/security/] informs us that libc also holds the bad code : An integer overflow bug has been discovered in the RPC library used by GNU libc, which is derived from the SunRPC library. This bug could be exploited to gain unauthorized root access to software linking to this code. The packages below also fix integer overflows in the malloc code. They also contain a fix from Andreas Schwab to reduce linebuflen in parallel to bumping up the buffer pointer in the NSS DNS code. SOLUTION FreeBSD : # fetch ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/patches/SA-02:34/rpc.patch # fetch ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/patches/SA-02:34/rpc.patch.asc NetBSD patch is out check : http://www.NetBSD.ORG/Security/ Kerberos : Apply the following patch to src/lib/rpc/xdr_array.c: Index: xdr_array.c =================================================================== RCS file: /cvs/krbdev/krb5/src/lib/rpc/xdr_array.c,v retrieving revision 1.5 diff -c -r1.5 xdr_array.c *** xdr_array.c 1998/02/14 02:27:23 1.5 - --- xdr_array.c 2002/08/02 17:25:05 *************** *** 75,81 **** return (FALSE); } c = *sizep; ! if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { return (FALSE); } nodesize = c * elsize; - --- 75,82 ---- return (FALSE); } c = *sizep; ! if ((c > maxsize || c > LASTUNSIGNED / elsize) ! && (xdrs->x_op != XDR_FREE)) { return (FALSE); } nodesize = c * elsize; and rebuild your tree. The patch was generated against krb5-1.2.5; patches to other releases may apply with some offset. This patch may also be found at: http://web.mit.edu/kerberos/www/advisories/2002-001-xdr_array_patch.txt Update (06 August 2002) ====== OpenAFS is vulerable, here's the patch : The OpenAFS project recommends that all users upgrade to OpenAFS 1.2.6 or newer. The latest stable OpenAFS release is always available from http://www.openafs.org/release/latest.html. No update is presently available for the OpenAFS-unstable series. For those who are unable to upgrade, apply the following patch to correct the XDR vulnerability, and rebuild your tree. =================================================================== RCS file: /cvs/openafs/src/rx/Makefile.in,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -r1.4.2.1 -r1.4.2.2 - --- openafs/src/rx/Makefile.in 2002/01/20 08:38:38 1.4.2.1 +++ openafs/src/rx/Makefile.in 2002/08/02 02:45:14 1.4.2.2 @@ -38,7 +38,7 @@ # Generic xdr objects (or, at least, xdr stuff that's not newly defined for rx). # Really the xdr stuff should be in its own directory. # - -XDROBJS = xdr_arrayn.o xdr_rx.o xdr_afsuuid.o +XDROBJS = xdr.o xdr_array.o xdr_arrayn.o xdr_rx.o xdr_afsuuid.o RXOBJS = rx_clock.o rx_event.o rx_user.o rx_lwp.o rx.o rx_null.o rx_globals.o rx_getaddr.o rx_misc.o rx_packet.o rx_rdwr.o rx_trace.o rx_conncache.o =================================================================== RCS file: /cvs/openafs/src/rx/xdr.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 - --- openafs/src/rx/xdr.c 2002/06/08 04:43:38 1.4 +++ openafs/src/rx/xdr.c 2002/07/31 23:13:09 1.5 @@ -558,6 +558,8 @@ u_int size; u_int nodesize; + if (maxsize > ((~0) >> 1) - 1) maxsize = ((~0) >> 1) - 1; + /* * first deal with the length since xdr strings are counted-strings */ =================================================================== RCS file: /cvs/openafs/src/rx/xdr_array.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 - --- openafs/src/rx/xdr_array.c 2001/08/08 00:03:57 1.4 +++ openafs/src/rx/xdr_array.c 2002/07/31 23:13:09 1.5 @@ -84,7 +84,10 @@ register caddr_t target = *addrp; register u_int c; /* the actual element count */ register bool_t stat = TRUE; - - register int nodesize; + register u_int nodesize; + + i = ((~0) >> 1) / elsize; + if (maxsize > i) maxsize = i; /* like strings, arrays are really counted arrays */ if (! xdr_u_int(xdrs, sizep)) { =================================================================== RCS file: /cvs/openafs/src/rx/xdr_arrayn.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 - --- openafs/src/rx/xdr_arrayn.c 2001/08/08 00:03:57 1.4 +++ openafs/src/rx/xdr_arrayn.c 2002/07/31 23:13:09 1.5 @@ -89,7 +89,10 @@ register caddr_t target = *addrp; register u_int c; /* the actual element count */ register bool_t stat = TRUE; - - register int nodesize; + register u_int nodesize; + + i = ((~0) >> 1) / elsize; + if (maxsize > i) maxsize = i; /* like strings, arrays are really counted arrays */ if (! xdr_u_int(xdrs, sizep)) { =================================================================== This patch may also be found at: http://www.openafs.org/security/xdr-updates-20020731.delta Update (13 August 2002) ====== As for the Tooltalk RPC see http://www.cert.org/advisories/CA-2002-26.html Update (14 Auguts 2002) ====== Get glibc version 2.1.3-23 see the diff below : http://security.debian.org/pool/updates/main/g/glibc/glibc_2.1.3-23.diff.gz