summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext
diff options
context:
space:
mode:
authorPaul Boca <pboca@cloudbasesolutions.com>2016-04-27 08:05:47 +0000
committerBen Pfaff <blp@ovn.org>2016-05-16 22:04:58 -0700
commite6b298ef73816355e94e22a7df0cd28414957087 (patch)
tree502a15bcf85497676f561f13e5fcb8b98dd19e67 /datapath-windows/ovsext
parent59936df6f45cf554ca201a08d8335af04d82a82c (diff)
downloadopenvswitch-e6b298ef73816355e94e22a7df0cd28414957087.tar.gz
datapath-windows: Validate Netlink packets' integrity.
Solved access violation when trying to access Netlink message - obtained with forged IOCTLs. Signed-off-by: Paul-Daniel Boca <pboca@cloudbasesolutions.com> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext')
-rw-r--r--datapath-windows/ovsext/Datapath.c45
-rw-r--r--datapath-windows/ovsext/Flow.c42
-rw-r--r--datapath-windows/ovsext/Netlink/Netlink.c66
-rw-r--r--datapath-windows/ovsext/Netlink/Netlink.h13
-rw-r--r--datapath-windows/ovsext/User.c5
-rw-r--r--datapath-windows/ovsext/Vport.c34
6 files changed, 150 insertions, 55 deletions
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 06f99b3d7..1f89964de 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -307,6 +307,7 @@ static NTSTATUS MapIrpOutputBuffer(PIRP irp,
static NTSTATUS ValidateNetlinkCmd(UINT32 devOp,
POVS_OPEN_INSTANCE instance,
POVS_MESSAGE ovsMsg,
+ UINT32 ovsMgsLength,
NETLINK_FAMILY *nlFamilyOps);
static NTSTATUS InvokeNetlinkCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
NETLINK_FAMILY *nlFamilyOps,
@@ -694,6 +695,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
UINT32 devOp;
OVS_MESSAGE ovsMsgReadOp;
POVS_MESSAGE ovsMsg;
+ UINT32 ovsMsgLength = 0;
NETLINK_FAMILY *nlFamilyOps;
OVS_USER_PARAMS_CONTEXT usrParamsCtx;
@@ -774,6 +776,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
}
ovsMsg = inputBuffer;
+ ovsMsgLength = inputBufferLen;
devOp = OVS_TRANSACTION_DEV_OP;
break;
@@ -808,6 +811,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
OVS_CTRL_CMD_EVENT_NOTIFY :
OVS_CTRL_CMD_READ_NOTIFY;
ovsMsg->genlMsg.version = nlControlFamilyOps.version;
+ ovsMsgLength = outputBufferLen;
devOp = OVS_READ_DEV_OP;
break;
@@ -853,6 +857,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
/* Create an NL message for consumption. */
ovsMsg = &ovsMsgReadOp;
+ ovsMsgLength = sizeof (ovsMsgReadOp);
devOp = OVS_READ_DEV_OP;
break;
@@ -864,7 +869,21 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
goto done;
}
+ /*
+ * Output buffer not mandatory but map it in case we have something
+ * to return to requester.
+ */
+ if (outputBufferLen != 0) {
+ status = MapIrpOutputBuffer(irp, outputBufferLen,
+ sizeof *ovsMsg, &outputBuffer);
+ if (status != STATUS_SUCCESS) {
+ goto done;
+ }
+ ASSERT(outputBuffer);
+ }
+
ovsMsg = inputBuffer;
+ ovsMsgLength = inputBufferLen;
devOp = OVS_WRITE_DEV_OP;
break;
@@ -903,7 +922,8 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
* "artificial" or was copied from a previously validated 'ovsMsg'.
*/
if (devOp != OVS_READ_DEV_OP) {
- status = ValidateNetlinkCmd(devOp, instance, ovsMsg, nlFamilyOps);
+ status = ValidateNetlinkCmd(devOp, instance, ovsMsg,
+ ovsMsgLength, nlFamilyOps);
if (status != STATUS_SUCCESS) {
goto done;
}
@@ -938,11 +958,18 @@ static NTSTATUS
ValidateNetlinkCmd(UINT32 devOp,
POVS_OPEN_INSTANCE instance,
POVS_MESSAGE ovsMsg,
+ UINT32 ovsMsgLength,
NETLINK_FAMILY *nlFamilyOps)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
UINT16 i;
+ // We need to ensure we have enough data to process
+ if (NlMsgSize(&ovsMsg->nlMsg) > ovsMsgLength) {
+ status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
for (i = 0; i < nlFamilyOps->opsCount; i++) {
if (nlFamilyOps->cmds[i].cmd == ovsMsg->genlMsg.cmd) {
/* Validate if the command is valid for the device operation. */
@@ -977,6 +1004,14 @@ ValidateNetlinkCmd(UINT32 devOp,
}
}
+ // validate all NlAttrs
+ if (!NlValidateAllAttrs(&ovsMsg->nlMsg, sizeof(*ovsMsg),
+ NlMsgAttrsLen((PNL_MSG_HDR)ovsMsg),
+ NULL, 0)) {
+ status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
done:
return status;
}
@@ -1028,6 +1063,7 @@ InvokeNetlinkCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
POVS_MESSAGE msgIn = NULL;
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
if (usrParamsCtx->ovsMsg->genlMsg.cmd == OVS_CTRL_CMD_EVENT_NOTIFY ||
usrParamsCtx->ovsMsg->genlMsg.cmd == OVS_CTRL_CMD_READ_NOTIFY) {
@@ -1043,8 +1079,7 @@ InvokeNetlinkCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
ASSERT(msgIn);
ASSERT(msgError);
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
if (*replyLen != 0) {
@@ -1416,9 +1451,9 @@ cleanup:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
return STATUS_SUCCESS;
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index 1f236257e..d957d3962 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -285,20 +285,10 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
goto done;
}
- /* Get all the top level Flow attributes */
- if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr),
- nlFlowPolicy, ARRAY_SIZE(nlFlowPolicy),
- flowAttrs, ARRAY_SIZE(flowAttrs)))
- != TRUE) {
- OVS_LOG_ERROR("Attr Parsing failed for msg: %p",
- nlMsgHdr);
- rc = STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- /* FLOW_DEL command w/o any key input is a flush case. */
+ /* FLOW_DEL command w/o any key input is a flush case.
+ If we don't have any attr, we treat this as a flush command*/
if ((genlMsgHdr->cmd == OVS_FLOW_CMD_DEL) &&
- (!(flowAttrs[OVS_FLOW_ATTR_KEY]))) {
+ (!NlMsgAttrsLen(nlMsgHdr))) {
rc = OvsFlushFlowIoctl(ovsHdr->dp_ifindex);
@@ -323,6 +313,17 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
goto done;
}
+ /* Get all the top level Flow attributes */
+ if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr),
+ nlFlowPolicy, ARRAY_SIZE(nlFlowPolicy),
+ flowAttrs, ARRAY_SIZE(flowAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ rc = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
if (flowAttrs[OVS_FLOW_ATTR_PROBE]) {
rc = OvsProbeSupportedFeature(msgIn, flowAttrs[OVS_FLOW_ATTR_KEY]);
if (rc != STATUS_SUCCESS) {
@@ -399,8 +400,9 @@ done:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
+
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
rc = STATUS_SUCCESS;
}
@@ -568,8 +570,9 @@ done:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
+
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
rc = STATUS_SUCCESS;
}
@@ -706,8 +709,9 @@ done:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
+
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
rc = STATUS_SUCCESS;
}
diff --git a/datapath-windows/ovsext/Netlink/Netlink.c b/datapath-windows/ovsext/Netlink/Netlink.c
index 27dcd4f14..dc1e78c60 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.c
+++ b/datapath-windows/ovsext/Netlink/Netlink.c
@@ -108,12 +108,18 @@ NlFillNlHdr(PNL_BUFFER nlBuf, UINT16 nlmsgType,
* ---------------------------------------------------------------------------
*/
VOID
-NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgError, UINT errorCode)
+NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgError,
+ UINT32 msgErrorLen,
+ UINT errorCode, UINT32 *msgLen)
{
NL_BUFFER nlBuffer;
ASSERT(errorCode != NL_ERROR_PENDING);
+ if ((msgError == NULL) || (msgErrorLen < sizeof *msgError)) {
+ return;
+ }
+
NlBufInit(&nlBuffer, (PCHAR)msgError, sizeof *msgError);
NlFillNlHdr(&nlBuffer, NLMSG_ERROR, 0,
msgIn->nlMsg.nlmsgSeq, msgIn->nlMsg.nlmsgPid);
@@ -121,6 +127,10 @@ NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgError, UINT errorCode)
msgError->errorMsg.error = errorCode;
msgError->errorMsg.nlMsg = msgIn->nlMsg;
msgError->nlMsg.nlmsgLen = sizeof(OVS_MESSAGE_ERROR);
+
+ if (NULL != msgLen) {
+ *msgLen = msgError->nlMsg.nlmsgLen;
+ }
}
/*
@@ -1006,7 +1016,7 @@ NlAttrFind__(const PNL_ATTR attrs, UINT32 size, UINT16 type)
{
PNL_ATTR iter = NULL;
PNL_ATTR ret = NULL;
- UINT32 left;
+ INT left;
NL_ATTR_FOR_EACH (iter, left, attrs, size) {
if (NlAttrType(iter) == type) {
@@ -1036,6 +1046,49 @@ NlAttrFindNested(const PNL_ATTR nla, UINT16 type)
/*
*----------------------------------------------------------------------------
+ * Traverses all attributes in received buffer in order to insure all are valid
+ *----------------------------------------------------------------------------
+ */
+BOOLEAN NlValidateAllAttrs(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
+ UINT32 totalAttrLen,
+ const NL_POLICY policy[], const UINT32 numPolicy)
+{
+ PNL_ATTR nla;
+ INT left;
+ BOOLEAN ret = TRUE;
+
+ if ((NlMsgSize(nlMsg) < attrOffset)) {
+ OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d",
+ nlMsg, attrOffset);
+ ret = FALSE;
+ goto done;
+ }
+
+ NL_ATTR_FOR_EACH_UNSAFE(nla, left, NlMsgAt(nlMsg, attrOffset),
+ totalAttrLen)
+ {
+ if (!NlAttrIsValid(nla, left)) {
+ ret = FALSE;
+ goto done;
+ }
+
+ UINT16 type = NlAttrType(nla);
+ if (type < numPolicy && policy[type].type != NL_A_NO_ATTR) {
+ /* Typecasting to keep the compiler happy */
+ const PNL_POLICY e = (const PNL_POLICY)(&policy[type]);
+ if (!NlAttrValidate(nla, e)) {
+ ret = FALSE;
+ goto done;
+ }
+ }
+ }
+
+done:
+ return ret;
+}
+
+/*
+ *----------------------------------------------------------------------------
* Parses the netlink message at a given offset (attrOffset)
* as a series of attributes. A pointer to the attribute with type
* 'type' is stored in attrs at index 'type'. policy is used to define the
@@ -1052,20 +1105,13 @@ NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
PNL_ATTR attrs[], UINT32 numAttrs)
{
PNL_ATTR nla;
- UINT32 left;
+ INT left;
UINT32 iter;
BOOLEAN ret = FALSE;
UINT32 numPolicyAttr = MIN(numPolicy, numAttrs);
RtlZeroMemory(attrs, numAttrs * sizeof *attrs);
-
- /* There is nothing to parse */
- if (!(NlMsgAttrsLen(nlMsg))) {
- ret = TRUE;
- goto done;
- }
-
if ((NlMsgSize(nlMsg) < attrOffset)) {
OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d",
nlMsg, attrOffset);
diff --git a/datapath-windows/ovsext/Netlink/Netlink.h b/datapath-windows/ovsext/Netlink/Netlink.h
index 8f6a5bea5..63164c716 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.h
+++ b/datapath-windows/ovsext/Netlink/Netlink.h
@@ -72,6 +72,7 @@ typedef struct _NL_POLICY
/* This macro is careful to check for attributes with bad lengths. */
#define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \
for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \
+ ((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)) && \
NlAttrIsValid(ITER, LEFT); \
(LEFT) -= NlAttrLenPad(ITER, LEFT), (ITER) = NlAttrNext(ITER))
@@ -80,7 +81,7 @@ typedef struct _NL_POLICY
* already been validated (e.g. with NL_ATTR_FOR_EACH). */
#define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \
for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \
- (LEFT) > 0; \
+ ((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)); \
(LEFT) -= NLA_ALIGN((ITER)->nlaLen), (ITER) = NlAttrNext(ITER))
#define NL_ATTR_GET_AS(NLA, TYPE) \
@@ -94,8 +95,9 @@ BOOLEAN NlFillNlHdr(PNL_BUFFER nlBuf,
UINT16 nlmsgType, UINT16 nlmsgFlags,
UINT32 nlmsgSeq, UINT32 nlmsgPid);
-VOID NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgOut,
- UINT errorCode);
+VOID NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgError,
+ UINT32 msgErrorLen,
+ UINT errorCode, UINT32 *msgLen);
/* Netlink message accessing the payload */
PVOID NlMsgAt(const PNL_MSG_HDR nlh, UINT32 offset);
@@ -187,6 +189,11 @@ static __inline NlAttrIsLast(const PNL_ATTR nla, int rem)
/* Netlink attribute validation */
BOOLEAN NlAttrValidate(const PNL_ATTR, const PNL_POLICY);
+/* Netlink attribute stream validation */
+BOOLEAN NlValidateAllAttrs(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
+ UINT32 totalAttrLen,
+ const NL_POLICY policy[], const UINT32 numPolicy);
+
/* Put APis */
BOOLEAN NlMsgPutNlHdr(PNL_BUFFER buf, PNL_MSG_HDR nlMsg);
BOOLEAN NlMsgPutGenlHdr(PNL_BUFFER buf, PGENL_MSG_HDR genlMsg);
diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c
index 34f38f45f..f2e3c1791 100644
--- a/datapath-windows/ovsext/User.c
+++ b/datapath-windows/ovsext/User.c
@@ -345,8 +345,9 @@ OvsNlExecuteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
+
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
status = STATUS_SUCCESS;
goto done;
}
diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c
index d04b12be0..429916961 100644
--- a/datapath-windows/ovsext/Vport.c
+++ b/datapath-windows/ovsext/Vport.c
@@ -1729,9 +1729,9 @@ cleanup:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
return STATUS_SUCCESS;
@@ -2088,9 +2088,9 @@ Cleanup:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
return STATUS_SUCCESS;
@@ -2324,6 +2324,7 @@ Cleanup:
if ((nlError != NL_ERROR_SUCCESS) && (nlError != NL_ERROR_PENDING)) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
if (vport && vportAllocated == TRUE) {
if (vportInitialized == TRUE) {
@@ -2343,8 +2344,7 @@ Cleanup:
OvsFreeMemoryWithTag(vport, OVS_VPORT_POOL_TAG);
}
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
return (status == STATUS_PENDING) ? STATUS_PENDING : STATUS_SUCCESS;
@@ -2452,9 +2452,9 @@ Cleanup:
if (nlError != NL_ERROR_SUCCESS) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
return STATUS_SUCCESS;
@@ -2544,9 +2544,9 @@ Cleanup:
if ((nlError != NL_ERROR_SUCCESS) && (nlError != NL_ERROR_PENDING)) {
POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
usrParamsCtx->outputBuffer;
+ UINT32 msgErrorLen = usrParamsCtx->outputLength;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
return (status == STATUS_PENDING) ? STATUS_PENDING : STATUS_SUCCESS;
@@ -2579,10 +2579,11 @@ OvsTunnelVportPendingRemove(PVOID context,
*replyLen = msgOut->nlMsg.nlmsgLen;
} else {
- POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)msgOut;
+ POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
+ tunnelContext->outputBuffer;
+ UINT32 msgErrorLen = tunnelContext->outputLength;
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
}
@@ -2721,12 +2722,13 @@ OvsTunnelVportPendingInit(PVOID context,
} while (error);
if (error) {
- POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) msgOut;
+ POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
+ tunnelContext->outputBuffer;
+ UINT32 msgErrorLen = tunnelContext->outputLength;
OvsCleanupVxlanTunnel(NULL, vport, NULL, NULL);
OvsFreeMemory(vport);
- NlBuildErrorMsg(msgIn, msgError, nlError);
- *replyLen = msgError->nlMsg.nlmsgLen;
+ NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
}
}