diff options
Diffstat (limited to 'src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp')
-rw-r--r-- | src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp b/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp index 249c2b9f4..e35f7aae8 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp @@ -26,6 +26,72 @@ #include <iprt/string.h> #include <iprt/assert.h> +DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq) +{ + if (!pReq || cbReq < sizeof (VMMDevRequestHeader)) + { + dprintf(("VbglGRVerify: Invalid parameter: pReq = %p, cbReq = %d\n", pReq, cbReq)); + return VERR_INVALID_PARAMETER; + } + + if (pReq->size > cbReq) + { + dprintf(("VbglGRVerify: request size %d > buffer size %d\n", pReq->size, cbReq)); + return VERR_INVALID_PARAMETER; + } + + /* The request size must correspond to the request type. */ + size_t cbReqExpected = vmmdevGetRequestSize(pReq->requestType); + + if (cbReq < cbReqExpected) + { + dprintf(("VbglGRVerify: buffer size %d < expected size %d\n", cbReq, cbReqExpected)); + return VERR_INVALID_PARAMETER; + } + + if (cbReqExpected == cbReq) + { + /* This is most likely a fixed size request, and in this case the request size + * must be also equal to the expected size. + */ + if (pReq->size != cbReqExpected) + { + dprintf(("VbglGRVerify: request size %d != expected size %d\n", pReq->size, cbReqExpected)); + return VERR_INVALID_PARAMETER; + } + + return VINF_SUCCESS; + } + + /* This can be a variable size request. Check the request type and limit the size + * to VMMDEV_MAX_VMMDEVREQ_SIZE, which is max size supported by the host. + */ + if ( pReq->requestType == VMMDevReq_LogString + || pReq->requestType == VMMDevReq_VideoSetVisibleRegion + || pReq->requestType == VMMDevReq_SetPointerShape +#ifdef VBOX_WITH_64_BITS_GUESTS + || pReq->requestType == VMMDevReq_HGCMCall32 + || pReq->requestType == VMMDevReq_HGCMCall64 +#else + || pReq->requestType == VMMDevReq_HGCMCall +#endif /* VBOX_WITH_64_BITS_GUESTS */ + || pReq->requestType == VMMDevReq_ChangeMemBalloon) + { + if (cbReq > VMMDEV_MAX_VMMDEVREQ_SIZE) + { + dprintf(("VbglGRVerify: VMMDevReq_LogString: buffer size %d too big\n", cbReq)); + return VERR_BUFFER_OVERFLOW; /* @todo is this error code ok? */ + } + } + else + { + dprintf(("VbglGRVerify: request size %d > buffer size %d\n", pReq->size, cbReq)); + return VERR_IO_BAD_LENGTH; /* @todo is this error code ok? */ + } + + return VINF_SUCCESS; +} + DECLVBGL(int) VbglGRAlloc (VMMDevRequestHeader **ppReq, uint32_t cbSize, VMMDevRequestType reqType) { VMMDevRequestHeader *pReq; |