Skip to content

Commit

Permalink
Try to limit buffer size to USHORT in NtQueryObject.
Browse files Browse the repository at this point in the history
  • Loading branch information
Holt59 committed Jul 16, 2024
1 parent 0601cb8 commit 37b3fa6
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/usvfs_dll/hooks/ntdll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <addrtools.h>
#include <unicodestring.h>
#include <queue>
#include <limits>
#include <algorithm>

namespace ulog = usvfs::log;
namespace ush = usvfs::shared;
Expand Down Expand Up @@ -1096,23 +1098,33 @@ DLLEXPORT NTSTATUS WINAPI usvfs::hook_NtQueryObject(
buffer =
std::wstring(deviceName) + L'\\' + std::wstring(buffer.data() + 7, buffer.size() - 7);

// the name is put in the buffer AFTER the struct, so the required size if
// sizeof(OBJECT_NAME_INFORMATION) + the number of bytes for the name + 2 bytes for a wide null character
const auto requiredLength = sizeof(OBJECT_NAME_INFORMATION) + buffer.size() * 2 + 2;
if (ObjectInformationLength < requiredLength) {
// the name is put in the object AFTER the struct, so the remaining length is the size of
// the object minus the size of the struct
//
// the buffer length is a USHORT so if we have more than the maximum possible value
// for USHORT, we need to truncate
//
const USHORT unicodeBufferLength =
static_cast<USHORT>(std::min(
static_cast<unsigned long long>(ObjectInformationLength - sizeof(OBJECT_NAME_INFORMATION)),
static_cast<unsigned long long>(std::numeric_limits<USHORT>::max())
));


// the number of bytes for the name + 2 bytes for a wide null character
const auto requiredLength = buffer.size() * 2 + 2;
if (unicodeBufferLength < requiredLength) {
// if the status was info length mismatch, we keep it, we are just going to update
// *ReturnLength
if (res != STATUS_INFO_LENGTH_MISMATCH) {
res = STATUS_BUFFER_OVERFLOW;
}

if (ReturnLength) {
*ReturnLength = requiredLength;
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION) + requiredLength;
}
} else {
// put the unicode buffer at the end of the object
const auto unicodeBufferLength =
ObjectInformationLength - sizeof(OBJECT_NAME_INFORMATION);
LPWSTR unicodeBuffer = reinterpret_cast<LPWSTR>(
static_cast<LPSTR>(ObjectInformation) + sizeof(OBJECT_NAME_INFORMATION));

Expand All @@ -1125,7 +1137,7 @@ DLLEXPORT NTSTATUS WINAPI usvfs::hook_NtQueryObject(
// update the actual unicode string
info->Name.Buffer = unicodeBuffer;
info->Name.Length = static_cast<USHORT>(buffer.size() * 2);
info->Name.MaximumLength = static_cast<USHORT>(unicodeBufferLength);
info->Name.MaximumLength = unicodeBufferLength;

res = STATUS_SUCCESS;
}
Expand Down

0 comments on commit 37b3fa6

Please sign in to comment.