Patch RPC library to avoid possible denial of service attacks as described

recently in BUGTRAQ. The set_input_fragment() routine in the XDR record
marking code blindly trusts that the first two bytes it sees will in fact
be an actual record header and that the specified size will be sane. In
fact, if you just telnet to a listening port of an RPC service and send a
few carriage returns, set_input_fragment() will obtain a ridiculously large
record size and sit there for a long time trying to read from the network.

A sanity test is required: if the record size is larger than the receive
buffer, punt.
This commit is contained in:
Bill Paul 1998-05-15 22:57:31 +00:00
parent 9c69f26836
commit a9352e90f0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36087

View File

@ -29,7 +29,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: xdr_rec.c,v 1.5 1996/12/30 14:07:10 peter Exp $";
static char *rcsid = "$Id: xdr_rec.c,v 1.8 1997/05/28 04:57:38 wpaul Exp $";
#endif
/*
@ -550,6 +550,12 @@ set_input_fragment(rstrm)
return (FALSE);
header = (long)ntohl(header);
rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
/*
* Sanity check. Try not to accept wildly incorrect
* record sizes.
*/
if ((header & (~LAST_FRAG)) > rstrm->recvsize)
return(FALSE);
rstrm->fbtbc = header & (~LAST_FRAG);
return (TRUE);
}