[ovs-dev] [PATCH] datapath-windows: Validate netlink packets integrity
Alin Serdean
aserdean at cloudbasesolutions.com
Tue Apr 26 15:53:51 UTC 2016
Beside the alignment problems, looks good to me.
Acked-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
Thanks,
Alin.
> -----Mesaj original-----
> De la: dev [mailto:dev-bounces at openvswitch.org] În numele Paul Boca
> Trimis: Monday, April 25, 2016 2:16 PM
> Către: dev at openvswitch.org
> Subiect: [ovs-dev] [PATCH] 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>
> ---
> 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 at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
More information about the dev
mailing list