nis: Fix stack overflow (stack exhaustion) in yp_all (bug 34528)
Checks
| Context |
Check |
Description |
| redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
| redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
| linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
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(-)
base-commit: 6144ef08960e1db191db2054abef02d361042018
@@ -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;