[PATCH] nis: Fix stack overflow (stack exhaustion) in yp_all (bug 34528)
Florian Weimer <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
The fix relies on the XDRMAXRECORD limit imposed in yp_xdr.c.
The bug was present from the beginning.
---
nis/ypclnt.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index 455d80df1f..83bafb5151 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -685,23 +685,36 @@ __xdr_ypresp_all (XDR *xdrs, struct ypresp_all_data *objp)
{
case YP_TRUE:
{
- char key[resp.ypresp_all_u.val.key.keydat_len + 1];
- char val[resp.ypresp_all_u.val.val.valdat_len + 1];
- int keylen = resp.ypresp_all_u.val.key.keydat_len;
- int vallen = resp.ypresp_all_u.val.val.valdat_len;
/* We are not allowed to modify the key and val data.
But we are allowed to add data behind the buffer,
if we don't modify the length. So add an extra NUL
character to avoid trouble with broken code. */
+
+ size_t keylen = resp.ypresp_all_u.val.key.keydat_len;
+ size_t vallen = resp.ypresp_all_u.val.val.valdat_len;
+ /* Cannot overflow due to the XDRMAXRECORD limit in yp_xdr.c. */
+ size_t keyval_size = keylen + vallen + 2;
+ char *buffer = malloc (keyval_size);
+ if (buffer == NULL)
+ {
+ xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
+ objp->status = YP_YPERR;
+ return FALSE;
+ }
+
objp->status = YP_TRUE;
- *((char *) __mempcpy (key, resp.ypresp_all_u.val.key.keydat_val,
- keylen)) = '\0';
- *((char *) __mempcpy (val, resp.ypresp_all_u.val.val.valdat_val,
- vallen)) = '\0';
+ buffer[keylen] = '\0';
+ buffer[keyval_size - 1] = '\0';
+ char *val = buffer + keylen + 1;
+ memcpy (buffer, resp.ypresp_all_u.val.key.keydat_val, keylen);
+ memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen);
xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
- if ((*objp->foreach) (objp->status, key, keylen,
- val, vallen, objp->data))
+
+ bool ok = (*objp->foreach) (objp->status, buffer, keylen,
+ val, vallen, objp->data);
+ free (buffer);
+ if (ok)
return TRUE;
}
break;
base-commit: 6144ef08960e1db191db2054abef02d361042018