Page MenuHomeFreeBSD

Off‑by‑one heap buffer overflow in rpc_gss_get_principal_name
ClosedPublic

Authored by thebugfixers_pm.me on Mon, Jun 22, 9:58 AM.
Tags
None
Referenced Files
F162638535: D57738.diff
Wed, Jul 15, 7:27 AM
F162638534: D57738.diff
Wed, Jul 15, 7:27 AM
F162614515: D57738.diff
Wed, Jul 15, 2:14 AM
Unknown Object (File)
Thu, Jul 9, 10:48 PM
Unknown Object (File)
Sat, Jul 4, 11:28 AM
Unknown Object (File)
Sat, Jul 4, 11:25 AM
Unknown Object (File)
Fri, Jul 3, 7:46 PM
Unknown Object (File)
Fri, Jul 3, 7:42 PM
Subscribers

Details

Summary

The buffer size is calculated without room for the terminating null byte:

namelen = strlen(name);          /* missing +1 */
if (node)    namelen += strlen(node) + 1;   /* +1 for '/'  */
if (domain)  namelen += strlen(domain) + 1; /* +1 for '@'  */
buf.value = mem_alloc(namelen);  /* exact size, no NUL */
strcpy((char *)buf.value, name); /* writes strlen+1 bytes */

Even when node and domain are provided, the calculation only accounts for separators (/ and @), not for the final \0. Every call therefore writes one byte past the allocation.

Impact: Heap metadata corruption leading to crashes or exploitable memory corruption.


Fix: Change the first line to namelen = strlen(name) + 1; (as the kernel version correctly does).

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

markj added a subscriber: markj.

This looks right. It would be simpler to use asprintf().

Note that the kernel has a copy of this function, with the same bug, but nothing calls it from what I can see.

This function doesn't appear to be called by anything in the base system, but it's exported by the library.

Impact: Heap metadata corruption leading to crashes or exploitable memory corruption.


Are you stating this as a hypothetical worst case, or do you actually have a way to exploit this? If it's the latter, please email secteam@freebsd.org with some details.

This revision is now accepted and ready to land.Mon, Jun 22, 12:50 PM

Thanks for the review.

Regarding your comment about the kernel having the same bug, to check we're on the same page sys/rpc/rpcsec_gss/svc_rpcsec_gss.c ? That seems to have namelen = strlen(name) + 1; already ? https://cgit.freebsd.org/src/tree/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c#n392

Hypothetical, my bad, I will omit similar wording in the future.

Thanks for the review.

Regarding your comment about the kernel having the same bug, to check we're on the same page sys/rpc/rpcsec_gss/svc_rpcsec_gss.c ? That seems to have namelen = strlen(name) + 1; already ? https://cgit.freebsd.org/src/tree/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c#n392

Right, sorry, I missed that somehow.