diff options
Diffstat (limited to 'datapath-windows/ovsext/Datapath.c')
-rw-r--r-- | datapath-windows/ovsext/Datapath.c | 45 |
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; |