Buffer overwrited when querying name

in IRP_MJ_CREATE, I query the name and dos name of the volume by following:
if (p_stack_location != NULL && p_stack_location->FileObject != NULL
&& p_stack_location->FileObject->FileName.Length > 0)
{
// get the volume’s driver letter
POBJECT_NAME_INFORMATION p_volume_name = NULL;
// OBJECT_NAME_INFORMATION volume_name;
status = IoQueryFileDosDeviceName(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION *)&p_volume_name);
if ( _wcsnicmp(p_volume_name->Name.Buffer,
L"B:“,
wcslen(L"B:”)) == 0)
{
DbgPrint(“OK\n”);
}

// display the name of volume
UNICODE_STRING u_str_vol_name_info;
WCHAR sz_vol_name[254];
ULONG ul_ret_len;
RtlInitEmptyUnicodeString(&u_str_vol_name_info,
sz_vol_name,
sizeof(sz_vol_name));
status = ObQueryNameString(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION)&u_str_vol_name_info,
sizeof(sz_vol_name),
&ul_ret_len);

}
After ObQueryNameString, the memory of p_volume_name were overwrited. I could not find where the problem is.

Another question, should we free the p_volume_name? By ExFreePool or other relative function?

This is very tricky, you cannot just pass a UNICODE_STRING allocated on the
stack instead of a OBJECT_NAME_INFORMATION this way. This is because " If
the given object is named and the type-specific query-name method succeeds,
the returned string is the full path to the given object. In this case,
ObQueryNameString sets Name.Buffer to the address immediately after
ObjectNameInfo ". This means you cannot rely on the buffer that you point
the unicode string to because ObQueryNameString actually sets it. You you
could rewrite this stuff to get the whole thing allocated from the pool and
then pass it to ObQueryNameString without relying on any buffers you may
have set before the call.

/Daniel

wrote in message news:xxxxx@ntfsd…
> in IRP_MJ_CREATE, I query the name and dos name of the volume by
> following:
> if (p_stack_location != NULL && p_stack_location->FileObject !=
> NULL
> && p_stack_location->FileObject->FileName.Length > 0)
> {
> // get the volume’s driver letter
> POBJECT_NAME_INFORMATION p_volume_name = NULL;
> // OBJECT_NAME_INFORMATION volume_name;
> status =
> IoQueryFileDosDeviceName(p_stack_location->FileObject,
> (POBJECT_NAME_INFORMATION
> *)&p_volume_name);
> if ( _wcsnicmp(p_volume_name->Name.Buffer,
> L"B:“,
> wcslen(L"B:”)) == 0)
> {
> DbgPrint(“OK\n”);
> }
>
> // display the name of volume
> UNICODE_STRING u_str_vol_name_info;
> WCHAR sz_vol_name[254];
> ULONG ul_ret_len;
> RtlInitEmptyUnicodeString(&u_str_vol_name_info,
> sz_vol_name,
> sizeof(sz_vol_name));
> status = ObQueryNameString(p_stack_location->FileObject,
>
> (POBJECT_NAME_INFORMATION)&u_str_vol_name_info,
> sizeof(sz_vol_name),
> &ul_ret_len);
> …
> }
> After ObQueryNameString, the memory of p_volume_name were overwrited. I
> could not find where the problem is.
>
> Another question, should we free the p_volume_name? By ExFreePool or other
> relative function?
>
>
>

BTW you ARE aware there is also a FltGetFileNameInformation ?

/Daniel

wrote in message news:xxxxx@ntfsd…
> in IRP_MJ_CREATE, I query the name and dos name of the volume by
> following:
> if (p_stack_location != NULL && p_stack_location->FileObject !=
> NULL
> && p_stack_location->FileObject->FileName.Length > 0)
> {
> // get the volume’s driver letter
> POBJECT_NAME_INFORMATION p_volume_name = NULL;
> // OBJECT_NAME_INFORMATION volume_name;
> status =
> IoQueryFileDosDeviceName(p_stack_location->FileObject,
> (POBJECT_NAME_INFORMATION
> *)&p_volume_name);
> if ( _wcsnicmp(p_volume_name->Name.Buffer,
> L"B:“,
> wcslen(L"B:”)) == 0)
> {
> DbgPrint(“OK\n”);
> }
>
> // display the name of volume
> UNICODE_STRING u_str_vol_name_info;
> WCHAR sz_vol_name[254];
> ULONG ul_ret_len;
> RtlInitEmptyUnicodeString(&u_str_vol_name_info,
> sz_vol_name,
> sizeof(sz_vol_name));
> status = ObQueryNameString(p_stack_location->FileObject,
>
> (POBJECT_NAME_INFORMATION)&u_str_vol_name_info,
> sizeof(sz_vol_name),
> &ul_ret_len);
> …
> }
> After ObQueryNameString, the memory of p_volume_name were overwrited. I
> could not find where the problem is.
>
> Another question, should we free the p_volume_name? By ExFreePool or other
> relative function?
>
>
>

Sorry, ignore, this apparently is not a minifilter.

/Daniel

“Daniel Terhell” wrote in message
news:xxxxx@ntfsd…
> BTW you ARE aware there is also a FltGetFileNameInformation ?
>
> /Daniel
>

On Fri, 13 Jul 2007 16:11:26 +0800, Daniel Terhell
wrote:

> This is very tricky, you cannot just pass a UNICODE_STRING allocated on
> the stack instead of a OBJECT_NAME_INFORMATION this way. This is
> because " If the given object is named and the type-specific query-name
> method succeeds, the returned string is the full path to the given
> object. In this case, ObQueryNameString sets Name.Buffer to the address
> immediately after ObjectNameInfo “. This means you cannot rely on the
> buffer that you point the unicode string to because ObQueryNameString

Do you mean that the buffer from stack is not reliable in this scenario?

I have tried following codes, but got the same result:
—8<----------------------------------------------------------------------------------->8—
// get the volume’s driver letter
POBJECT_NAME_INFORMATION p_volume_name = NULL;
status =
IoQueryFileDosDeviceName(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION
)&p_volume_name);

//
// display the name of volume
//
// UNICODE_STRING u_str_vol_name_info;
WCHAR sz_vol_name =
(WCHAR
)ExAllocatePoolWithTag(NonPagedPool,
254
sizeof(WCHAR),
‘ReDt’);

OBJECT_NAME_INFORMATION vol_name_info;
ULONG ul_ret_len;
RtlInitEmptyUnicodeString(&vol_name_info.Name, //
&u_str_vol_name_info,
sz_vol_name,
254 * sizeof(WCHAR));

status = ObQueryNameString(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION)&vol_name_info,
254 * sizeof(WCHAR),
&ul_ret_len);

—8<----------------------------------------------------------------------------------->8—

BTW, until now, If used ObQueryNameString only, it worked.

> actually sets it. You you could rewrite this stuff to get the whole
> thing allocated from the pool and then pass it to ObQueryNameString
> without relying on any buffers you may have set before the call.
>
> /Daniel
>
>
>
>
>
> wrote in message news:xxxxx@ntfsd…
>> in IRP_MJ_CREATE, I query the name and dos name of the volume by
>> following:
>> if (p_stack_location != NULL && p_stack_location->FileObject !=
>> NULL
>> && p_stack_location->FileObject->FileName.Length > 0)
>> {
>> // get the volume’s driver letter
>> POBJECT_NAME_INFORMATION p_volume_name = NULL;
>> // OBJECT_NAME_INFORMATION volume_name;
>> status =
>> IoQueryFileDosDeviceName(p_stack_location->FileObject,
>> (POBJECT_NAME_INFORMATION
>> *)&p_volume_name);
>> if ( _wcsnicmp(p_volume_name->Name.Buffer,
>> L"B:”,
>> wcslen(L"B:")) == 0)
>> {
>> DbgPrint(“OK\n”);
>> }
>>
>> // display the name of volume
>> UNICODE_STRING u_str_vol_name_info;
>> WCHAR sz_vol_name[254];
>> ULONG ul_ret_len;
>> RtlInitEmptyUnicodeString(&u_str_vol_name_info,
>> sz_vol_name,
>> sizeof(sz_vol_name));
>> status = ObQueryNameString(p_stack_location->FileObject,
>> (POBJECT_NAME_INFORMATION)&u_str_vol_name_info,
>> sizeof(sz_vol_name),
>> &ul_ret_len);
>> …
>> }
>> After ObQueryNameString, the memory of p_volume_name were overwrited. I
>> could not find where the problem is.
>>
>> Another question, should we free the p_volume_name? By ExFreePool or
>> other relative function?
>>
>>
>>
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com


Sincerely yours,
William

No, but it needs to be followed immediately with the buffer.
ObQueryNameString sets the buffer so you cannot rely on your buffer. Rewrite
your code to something like this and you should be fine:

//

POBJECT_NAME_INFORMATION pNameInfo;

// Doc says: A reasonable size for the buffer to accommodate most object
names is 1024 bytes.
ULONG size= 1024; // (sizeof(OBJECT_NAME_INFORMATION)+ nameLen *
sizeof(WCHAR)

pNameInfo=(PBOJECT_NAME_INFORMATION) ExAllocatePoolWithTag(size,‘!xeS’);

if (pNameInfo)
{
status = ObQueryNameString(p_stack_location->FileObject,
pNameInfo,size, &ul_ret_len);
//
// …
//
ExFreePoolWithTag(pNameInfo,‘!xeS’);

}

//Daniel

“William Xue” wrote in message news:xxxxx@ntfsd…
On Fri, 13 Jul 2007 16:11:26 +0800, Daniel Terhell
wrote:

> This is very tricky, you cannot just pass a UNICODE_STRING allocated on
> the stack instead of a OBJECT_NAME_INFORMATION this way. This is because
> " If the given object is named and the type-specific query-name method
> succeeds, the returned string is the full path to the given object. In
> this case, ObQueryNameString sets Name.Buffer to the address immediately
> after ObjectNameInfo “. This means you cannot rely on the buffer that you
> point the unicode string to because ObQueryNameString

Do you mean that the buffer from stack is not reliable in this scenario?

I have tried following codes, but got the same result:
—8<----------------------------------------------------------------------------------->8—
// get the volume’s driver letter
POBJECT_NAME_INFORMATION p_volume_name = NULL;
status =
IoQueryFileDosDeviceName(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION
)&p_volume_name);

//
// display the name of volume
//
// UNICODE_STRING u_str_vol_name_info;
WCHAR sz_vol_name =
(WCHAR
)ExAllocatePoolWithTag(NonPagedPool,

254
sizeof(WCHAR),

‘ReDt’);

OBJECT_NAME_INFORMATION vol_name_info;
ULONG ul_ret_len;
RtlInitEmptyUnicodeString(&vol_name_info.Name, //
&u_str_vol_name_info,
sz_vol_name,
254 * sizeof(WCHAR));

status = ObQueryNameString(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION)&vol_name_info,
254 * sizeof(WCHAR),
&ul_ret_len);

—8<----------------------------------------------------------------------------------->8—

BTW, until now, If used ObQueryNameString only, it worked.

> actually sets it. You you could rewrite this stuff to get the whole thing
> allocated from the pool and then pass it to ObQueryNameString without
> relying on any buffers you may have set before the call.
>
> /Daniel
>
>
>
>
>
> wrote in message news:xxxxx@ntfsd…
>> in IRP_MJ_CREATE, I query the name and dos name of the volume by
>> following:
>> if (p_stack_location != NULL && p_stack_location->FileObject !=
>> NULL
>> && p_stack_location->FileObject->FileName.Length > 0)
>> {
>> // get the volume’s driver letter
>> POBJECT_NAME_INFORMATION p_volume_name = NULL;
>> // OBJECT_NAME_INFORMATION volume_name;
>> status =
>> IoQueryFileDosDeviceName(p_stack_location->FileObject,
>>
>> (POBJECT_NAME_INFORMATION *)&p_volume_name);
>> if ( _wcsnicmp(p_volume_name->Name.Buffer,
>> L"B:”,
>> wcslen(L"B:")) == 0)
>> {
>> DbgPrint(“OK\n”);
>> }
>>
>> // display the name of volume
>> UNICODE_STRING u_str_vol_name_info;
>> WCHAR sz_vol_name[254];
>> ULONG ul_ret_len;
>> RtlInitEmptyUnicodeString(&u_str_vol_name_info,
>> sz_vol_name,
>> sizeof(sz_vol_name));
>> status = ObQueryNameString(p_stack_location->FileObject,
>> (POBJECT_NAME_INFORMATION)&u_str_vol_name_info,
>> sizeof(sz_vol_name),
>> &ul_ret_len);
>> …
>> }
>> After ObQueryNameString, the memory of p_volume_name were overwrited. I
>> could not find where the problem is.
>>
>> Another question, should we free the p_volume_name? By ExFreePool or
>> other relative function?
>>
>>
>>
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com


Sincerely yours,
William

In an attempt to explain better, the problem is not that it’s allocated on
the stack, the problem is that your unicode string and the buffer do not
form one contigious block. ObQueryNameString does not respect the buffer
member to which your string may point like most functions do which take a
unicode string. Instead it sets the buffer itself to just after the
OBJECT_NAME_INFORMATION as the documentation says. So after the call the
buffer does not anymore point to where you have set it. So the issue is you
need to allocate the unicode string and the buffer in one go so they form
one block. ObQueryNameString originally was not a documented function that
they did document later so this is maybe why it doesn’t handle unicode
strings the way the APIs regularly do. A hint is that the function takes an
POBJECT_NAME_INFORMATION (and not a PUNICODE_STRING).

/Daniel

“William Xue” wrote in message news:xxxxx@ntfsd…

Do you mean that the buffer from stack is not reliable in this scenario?

I have tried following codes, but got the same result:
—8<----------------------------------------------------------------------------------->8—
// get the volume’s driver letter
POBJECT_NAME_INFORMATION p_volume_name = NULL;
status =
IoQueryFileDosDeviceName(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION
)&p_volume_name);

//
// display the name of volume
//
// UNICODE_STRING u_str_vol_name_info;
WCHAR sz_vol_name =
(WCHAR
)ExAllocatePoolWithTag(NonPagedPool,

254
sizeof(WCHAR),

‘ReDt’);

OBJECT_NAME_INFORMATION vol_name_info;
ULONG ul_ret_len;
RtlInitEmptyUnicodeString(&vol_name_info.Name, //
&u_str_vol_name_info,
sz_vol_name,
254 * sizeof(WCHAR));

status = ObQueryNameString(p_stack_location->FileObject,
(POBJECT_NAME_INFORMATION)&vol_name_info,
254 * sizeof(WCHAR),
&ul_ret_len);

—8<----------------------------------------------------------------------------------->8—

BTW, until now, If used ObQueryNameString only, it worked.

> actually sets it. You you could rewrite this stuff to get the whole thing
> allocated from the pool and then pass it to ObQueryNameString without
> relying on any buffers you may have set before the call.
>
> /Daniel
>
>
>
>
>
> wrote in message news:xxxxx@ntfsd…
>> in IRP_MJ_CREATE, I query the name and dos name of the volume by
>> following:
>> if (p_stack_location != NULL && p_stack_location->FileObject !=
>> NULL
>> && p_stack_location->FileObject->FileName.Length > 0)
>> {
>> // get the volume’s driver letter
>> POBJECT_NAME_INFORMATION p_volume_name = NULL;
>> // OBJECT_NAME_INFORMATION volume_name;
>> status =
>> IoQueryFileDosDeviceName(p_stack_location->FileObject,
>>
>> (POBJECT_NAME_INFORMATION *)&p_volume_name);
>> if ( _wcsnicmp(p_volume_name->Name.Buffer,
>> L"B:“,
>> wcslen(L"B:”)) == 0)
>> {
>> DbgPrint(“OK\n”);
>> }
>>
>> // display the name of volume
>> UNICODE_STRING u_str_vol_name_info;
>> WCHAR sz_vol_name[254];
>> ULONG ul_ret_len;
>> RtlInitEmptyUnicodeString(&u_str_vol_name_info,
>> sz_vol_name,
>> sizeof(sz_vol_name));
>> status = ObQueryNameString(p_stack_location->FileObject,
>> (POBJECT_NAME_INFORMATION)&u_str_vol_name_info,
>> sizeof(sz_vol_name),
>> &ul_ret_len);
>> …
>> }
>> After ObQueryNameString, the memory of p_volume_name were overwrited. I
>> could not find where the problem is.
>>
>> Another question, should we free the p_volume_name? By ExFreePool or
>> other relative function?
>>
>>
>>
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com


Sincerely yours,
William

If you are using the attaching device technique for your file system filter driver, ObQueryNameString is useles, because it will produce an infinite loop. You should make an IRP and send it to the device you’re attached to, with IRP_MJ_QUERY_INFORMATION, and FileNameInformation class
This way you will get the name for sure from the Lowest device object.
use IoAllocateIrp to allocate an IRP
and IoGetNextirpStackLocation to get the stack for the next device object and set the parameters

On Fri, 13 Jul 2007 18:01:06 +0800, Daniel Terhell
wrote:

> In an attempt to explain better, the problem is not that it’s allocated
> on the stack, the problem is that your unicode string and the buffer do
> not form one contigious block. ObQueryNameString does not respect the
> buffer member to which your string may point like most functions do
> which take a unicode string. Instead it sets the buffer itself to just
> after the OBJECT_NAME_INFORMATION as the documentation says. So after

Thank you very much!
I got it.

Though the doc also mentioned it, it’s hard to understand that time.

> the call the buffer does not anymore point to where you have set it. So
> the issue is you need to allocate the unicode string and the buffer in
> one go so they form one block. ObQueryNameString originally was not a
> documented function that they did document later so this is maybe why it
> doesn’t handle unicode strings the way the APIs regularly do. A hint is
> that the function takes an POBJECT_NAME_INFORMATION (and not a
> PUNICODE_STRING).
>
> /Daniel
>
>
>
> “William Xue” wrote in message
> news:xxxxx@ntfsd…
>
> Do you mean that the buffer from stack is not reliable in this scenario?
>
> I have tried following codes, but got the same result:
> —8<----------------------------------------------------------------------------------->8—
> // get the volume’s driver letter
> POBJECT_NAME_INFORMATION p_volume_name = NULL;
> status =
> IoQueryFileDosDeviceName(p_stack_location->FileObject,
> (POBJECT_NAME_INFORMATION
> *)&p_volume_name);
>
> //
> // display the name of volume
> //
> // UNICODE_STRING u_str_vol_name_info;
> WCHAR sz_vol_name =
> (WCHAR
)ExAllocatePoolWithTag(NonPagedPool,
>
> 254
> * sizeof(WCHAR),
>
> ‘ReDt’);
>
> OBJECT_NAME_INFORMATION vol_name_info;
> ULONG ul_ret_len;
> RtlInitEmptyUnicodeString(&vol_name_info.Name, //
> &u_str_vol_name_info,
> sz_vol_name,
> 254 * sizeof(WCHAR));
>
>
> status = ObQueryNameString(p_stack_location->FileObject,
> (POBJECT_NAME_INFORMATION)&vol_name_info,
> 254 * sizeof(WCHAR),
> &ul_ret_len);
>
> —8<----------------------------------------------------------------------------------->8—
>
> BTW, until now, If used ObQueryNameString only, it worked.
>
>> actually sets it. You you could rewrite this stuff to get the whole
>> thing allocated from the pool and then pass it to ObQueryNameString
>> without relying on any buffers you may have set before the call.
>>
>> /Daniel
>>
>>
>>
>>
>>
>> wrote in message news:xxxxx@ntfsd…

>>
>>
>> —
>> Questions? First check the IFS FAQ at
>> https://www.osronline.com/article.cfm?id=17
>>
>> You are currently subscribed to ntfsd as: xxxxx@gmail.com
>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>


Sincerely yours,
William