From 050b495a526c1adafc7ce6ca4e9fc5ff8a1bbd7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 21 Mar 2014 17:22:29 +0100 Subject: [PATCH] Fix an invalid memory access in k_order_perturbation DLL. In the case where a 2nd/3rd derivative is symbolically not zero but numerically zero at the evaluation point, the last lines of the g2/g3 matrices (in KordpDynare::calcDerivativesAtSteady()) where uninitialized (these matrices store the sparse hessian/3rd-deriv in coordinate list form, i.e. with 3 columns and as many rows as non-zero elements). When reconstructing the dense hessian/3rd-deriv matrix out of g2/g3, this would result in invalid memory accesses. --- .../k_order_perturbation/dynamic_abstract_class.cc | 13 ++++++++++++- mex/sources/k_order_perturbation/k_ord_dynare.cc | 6 +++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mex/sources/k_order_perturbation/dynamic_abstract_class.cc b/mex/sources/k_order_perturbation/dynamic_abstract_class.cc index c660e00f9..37607f422 100644 --- a/mex/sources/k_order_perturbation/dynamic_abstract_class.cc +++ b/mex/sources/k_order_perturbation/dynamic_abstract_class.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Dynare Team + * Copyright (C) 2010-2014 Dynare Team * * This file is part of Dynare. * @@ -52,5 +52,16 @@ DynamicModelAC::unpackSparseMatrix(mxArray *sparseMat) newMat[retvalind2++] = ptr[rind]; } + /* If there are less elements than Nzmax (that might happen if some + derivative is symbolically not zero but numerically zero at the evaluation + point), then fill in the matrix with empty entries, that will be + recognized as such by KordpDynare::populateDerivativesContainer() */ + while (retvalind0 < (int) sizeRowIdxVector) + { + newMat[retvalind0++] = 0; + newMat[retvalind1++] = 0; + newMat[retvalind2++] = 0; + } + return newMat; } diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.cc b/mex/sources/k_order_perturbation/k_ord_dynare.cc index 91c96e0bc..17dcf3254 100644 --- a/mex/sources/k_order_perturbation/k_ord_dynare.cc +++ b/mex/sources/k_order_perturbation/k_ord_dynare.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2013 Dynare Team + * Copyright (C) 2008-2014 Dynare Team * * This file is part of Dynare. * @@ -194,6 +194,8 @@ KordpDynare::populateDerivativesContainer(const TwoDMatrix &g, int ord, const ve { int j = (int) g.get(i, 0)-1; // hessian indices start with 1 int i1 = (int) g.get(i, 1) -1; + if (j < 0 || i1 < 0) + continue; // Discard empty entries (see comment in DynamicModelAC::unpackSparseMatrix()) int s0 = i1 / nJcols; int s1 = i1 % nJcols; if (s0 < nJcols1) @@ -222,6 +224,8 @@ KordpDynare::populateDerivativesContainer(const TwoDMatrix &g, int ord, const ve { int j = (int) g.get(i, 0)-1; int i1 = (int) g.get(i, 1) -1; + if (j < 0 || i1 < 0) + continue; // Discard empty entries (see comment in DynamicModelAC::unpackSparseMatrix()) int s0 = i1 / nJcols2; int i2 = i1 % nJcols2; int s1 = i2 / nJcols;