svn commit: r339143 - stable/11/sys/cddl/contrib/opensolaris/common/nvpair
Alexander Motin
mav at FreeBSD.org
Wed Oct 3 14:57:20 UTC 2018
Author: mav
Date: Wed Oct 3 14:57:19 2018
New Revision: 339143
URL: https://svnweb.freebsd.org/changeset/base/339143
Log:
MFC r337217: MFV r337216: 7263 deeply nested nvlist can overflow stack
illumos/illumos-gate at 9ca527c3d3dfa7c8f304b34a9e03b5eddace838f
Reviewed by: Adam Leventhal <ahl at delphix.com>
Reviewed by: George Wilson <george.wilson at delphix.com>
Reviewed by: Robert Mustacchi <rm at joyent.com>
Approved by: Dan McDonald <danmcd at omniti.com>
Author: Matthew Ahrens <mahrens at delphix.com>
Modified:
stable/11/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c
==============================================================================
--- stable/11/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c Wed Oct 3 14:56:38 2018 (r339142)
+++ stable/11/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c Wed Oct 3 14:57:19 2018 (r339143)
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 by Delphix. All rights reserved.
*/
#include <sys/debug.h>
@@ -142,6 +143,11 @@ static int nvlist_add_common(nvlist_t *nvl, const char
#define NVPAIR2I_NVP(nvp) \
((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_nvp)))
+#ifdef _KERNEL
+int nvpair_max_recursion = 20;
+#else
+int nvpair_max_recursion = 100;
+#endif
int
nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
@@ -2018,6 +2024,7 @@ typedef struct {
const nvs_ops_t *nvs_ops;
void *nvs_private;
nvpriv_t *nvs_priv;
+ int nvs_recursion;
} nvstream_t;
/*
@@ -2169,9 +2176,16 @@ static int
nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
{
switch (nvs->nvs_op) {
- case NVS_OP_ENCODE:
- return (nvs_operation(nvs, embedded, NULL));
+ case NVS_OP_ENCODE: {
+ int err;
+ if (nvs->nvs_recursion >= nvpair_max_recursion)
+ return (EINVAL);
+ nvs->nvs_recursion++;
+ err = nvs_operation(nvs, embedded, NULL);
+ nvs->nvs_recursion--;
+ return (err);
+ }
case NVS_OP_DECODE: {
nvpriv_t *priv;
int err;
@@ -2184,8 +2198,12 @@ nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
nvlist_init(embedded, embedded->nvl_nvflag, priv);
+ if (nvs->nvs_recursion >= nvpair_max_recursion)
+ return (EINVAL);
+ nvs->nvs_recursion++;
if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
nvlist_free(embedded);
+ nvs->nvs_recursion--;
return (err);
}
default:
@@ -2273,6 +2291,7 @@ nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen
return (EINVAL);
nvs.nvs_op = nvs_op;
+ nvs.nvs_recursion = 0;
/*
* For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
More information about the svn-src-stable
mailing list