[ovs-dev] [PATCH V2] datapath-windows: Validate netlink packets integrity

Nithin Raju nithin at vmware.com
Tue May 17 17:42:29 UTC 2016


Hi Paul,
Can you point out the particular code that fixed the access violation?

I looked at the code, and code such as the following is redundant:
+    // We need to ensure we have enough data to process
+    if (NlMsgSize(&ovsMsg->nlMsg) > ovsMsgLength) {
+        status = STATUS_INVALID_PARAMETER;
+        goto done;
+    }

We already validate the minimum required length when we call into
MapIrpOutputBuffer().

Also, it would be helpful for review if we limited each patch to address
one problem. I see fixes in Flow.c and Datpath.c. Are they all related to
the same problem you are trying to address?

-- Nithin


-----Original Message-----
From: dev <dev-bounces at openvswitch.org> on behalf of Paul Boca
<pboca at cloudbasesolutions.com>
Date: Wednesday, April 27, 2016 at 1:05 AM
To: "dev at openvswitch.org" <dev at openvswitch.org>
Subject: [ovs-dev] [PATCH V2] datapath-windows: Validate netlink
packets	integrity

>Solved access violation when trying to acces netling message - obtained
>with forged IOCTLs
>
>Signed-off-by: Paul-Daniel Boca <pboca at cloudbasesolutions.com>
>Acked-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
>---
>V2: Fixed alignement problems
>---
> datapath-windows/ovsext/Datapath.c        | 45 ++++++++++++++++++---
> datapath-windows/ovsext/Flow.c            | 42 +++++++++++---------
> datapath-windows/ovsext/Netlink/Netlink.c | 66
>++++++++++++++++++++++++++-----
> datapath-windows/ovsext/Netlink/Netlink.h | 13 ++++--
> datapath-windows/ovsext/User.c            |  5 ++-
> datapath-windows/ovsext/Vport.c           | 34 ++++++++--------
> lib/netlink-socket.c                      |  2 +
> 7 files changed, 152 insertions(+), 55 deletions(-)
>
>diff --git a/datapath-windows/ovsext/Datapath.c
>b/datapath-windows/ovsext/Datapath.c
>index 06f99b3..1f89964 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 a49a60c..792b614 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 27dcd4f..dc1e78c 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 8f6a5be..63164c7 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 33cbd89..bc010c7 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 d04b12b..4299169 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);
>     }
> }
>diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c
>index cad9490..32b0cc3 100644
>--- a/lib/netlink-socket.c
>+++ b/lib/netlink-socket.c
>@@ -127,6 +127,7 @@ nl_sock_create(int protocol, struct nl_sock **sockp)
>     sock = xmalloc(sizeof *sock);
> 
> #ifdef _WIN32
>+    sock->overlapped.hEvent = NULL;
>     sock->handle = CreateFile(OVS_DEVICE_NAME_USER,
>                               GENERIC_READ | GENERIC_WRITE,
>                               FILE_SHARE_READ | FILE_SHARE_WRITE,
>@@ -1191,6 +1192,7 @@ pend_io_request(struct nl_sock *sock)
> 
>     ovs_header = ofpbuf_put_uninit(&request, sizeof *ovs_header);
>     ovs_header->dp_ifindex = 0;
>+    nlmsg->nlmsg_len = request.size;
> 
>     if (!DeviceIoControl(sock->handle, OVS_IOCTL_WRITE,
>                          request.data, request.size,
>-- 
>2.7.2.windows.1
>_______________________________________________
>dev mailing list
>dev at openvswitch.org
>https://urldefense.proofpoint.com/v2/url?u=http-3A__openvswitch.org_mailma
>n_listinfo_dev&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=pN
>HQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=GabGAlmcY24uVSoAQCaiRYFIYSfiDS
>JZomM6llWwZmA&s=N-QN8hqnSsvjfhoygdktRzwFa6jdc2QCMZelWxlsT3g&e= 




More information about the dev mailing list