Solved access violation when trying to acces netling message - obtained with 
forged IOCTLs

Signed-off-by: Paul-Daniel Boca <pb...@cloudbasesolutions.com>
---
 datapath-windows/ovsext/Datapath.c        | 45 +++++++++++++++++---
 datapath-windows/ovsext/Flow.c            | 42 ++++++++++---------
 datapath-windows/ovsext/Netlink/Netlink.c | 68 ++++++++++++++++++++++++++-----
 datapath-windows/ovsext/Netlink/Netlink.h | 15 +++++--
 datapath-windows/ovsext/User.c            |  5 ++-
 datapath-windows/ovsext/Vport.c           | 34 ++++++++--------
 lib/netlink-socket.c                      |  2 +
 7 files changed, 154 insertions(+), 57 deletions(-)

diff --git a/datapath-windows/ovsext/Datapath.c 
b/datapath-windows/ovsext/Datapath.c
index 0a25af0..6f97693 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,
@@ -693,6 +694,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
     UINT32 devOp;
     OVS_MESSAGE ovsMsgReadOp;
     POVS_MESSAGE ovsMsg;
+    UINT32 ovsMsgLength = 0;
     NETLINK_FAMILY *nlFamilyOps;
     OVS_USER_PARAMS_CONTEXT usrParamsCtx;
 
@@ -772,6 +774,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
         }
 
         ovsMsg = inputBuffer;
+        ovsMsgLength = inputBufferLen;
         devOp = OVS_TRANSACTION_DEV_OP;
         break;
 
@@ -806,6 +809,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;
@@ -851,6 +855,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject,
 
         /* Create an NL message for consumption. */
         ovsMsg = &ovsMsgReadOp;
+        ovsMsgLength = sizeof (ovsMsgReadOp);
         devOp = OVS_READ_DEV_OP;
 
         break;
@@ -862,7 +867,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;
 
@@ -901,7 +920,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;
         }
@@ -936,11 +956,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. */
@@ -975,6 +1002,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;
 }
@@ -1026,6 +1061,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) 
{
@@ -1041,8 +1077,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) {
@@ -1414,9 +1449,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 a7e9bd2..2a3bf73 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 e2312da..b5a97b9 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);
@@ -1100,7 +1146,7 @@ NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
     for (iter = 0; iter < numPolicyAttr; iter++) {
         const PNL_POLICY e = (const PNL_POLICY)(&policy[iter]);
         if (!e->optional && e->type != NL_A_NO_ATTR && !attrs[iter]) {
-            OVS_LOG_ERROR("Required attr:%d missing", iter);
+            OVS_LOG_WARN("Required attr:%d missing", iter);
             goto done;
         }
     }
diff --git a/datapath-windows/ovsext/Netlink/Netlink.h 
b/datapath-windows/ovsext/Netlink/Netlink.h
index 8f6a5be..a37ea57 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.h
+++ b/datapath-windows/ovsext/Netlink/Netlink.h
@@ -72,7 +72,8 @@ 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);                        \
-         NlAttrIsValid(ITER, LEFT);                                     \
+         ((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)) &&              \
+                NlAttrIsValid(ITER, LEFT); \
          (LEFT) -= NlAttrLenPad(ITER, LEFT), (ITER) = NlAttrNext(ITER))
 
 /* This macro does not check for attributes with bad lengths.  It should only
@@ -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 6b2d94a..909e945 100644
--- a/datapath-windows/ovsext/User.c
+++ b/datapath-windows/ovsext/User.c
@@ -355,8 +355,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 882b41f..2825a22 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@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to