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;
