xdr_string: don't leak strings with xdr_free

Historically (and in a small amount of older software such as OpenAFS),
developers would attempt to free XDR strings with

	xdr_free((xdrproc_t)xdr_string, &string)

This resulted in xdr_free calling xdr_string with only two intentional
arguments and whatever was left in the third argument register.  If the
register held a sufficently small number, xdr_string would return FALSE
and not free the string (no one checks the return values).

Software should instead free strings with:

	xdr_free((xdrproc_t)xdr_wrapstring, &string)

Because buggy software exists in the wild, act as though xdr_wrapstring
was used in the XDR_FREE case and plug these leaks.

Reviewed by:	kib
MFC after:	3 days
Effort:		CHERI upstreaming
Sponsored by:	Innovate UK
Differential Revision:	https://reviews.freebsd.org/D54825
This commit is contained in:
Brooks Davis
2026-01-23 10:35:55 +00:00
parent ac5a19ec69
commit e17d7ab869
2 changed files with 14 additions and 0 deletions
+7
View File
@@ -696,6 +696,13 @@ xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
if (sp == NULL) {
return(TRUE); /* already free */
}
/*
* XXX: buggy software may call this without a third
* argument via xdr_free(). Ignore maxsize since it may
* be invalid. Otherwise, if it's very small, we might
* fail to free the string.
*/
maxsize = RPC_MAXDATASIZE;
/* FALLTHROUGH */
case XDR_ENCODE:
size = strlen(sp);
+7
View File
@@ -620,6 +620,13 @@ xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
if (sp == NULL) {
return(TRUE); /* already free */
}
/*
* XXX: buggy software may call this without a third
* argument via xdr_free(). Ignore maxsize since it may
* be invalid. Otherwise, if it's very small, we might
* fail to free the string.
*/
maxsize = RPC_MAXDATASIZE;
/* FALLTHROUGH */
case XDR_ENCODE:
size = strlen(sp);