summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'datapath-windows/ovsext/Datapath.c')
-rw-r--r--datapath-windows/ovsext/Datapath.c45
1 files changed, 40 insertions, 5 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;