FltSendMessage return STATUS_BUFFER_OVERFLOW due to an alignment issue.

Hi,

I think there is an unexpected behavior of FilterReplyMessage() &
FltSendMessage(). It would be convenient to be documented.

FilterReplyMessage() doc says:

lpReplyBuffer
Pointer to a caller-allocated buffer containing the reply to be sent
to the minifilter. The reply must contain a FILTER_REPLY_HEADER structure,
but otherwise, its format is caller-defined. This parameter is required and
cannot be NULL.

dwReplyBufferSize
Size, in bytes, of the buffer that the lpReplyBuffer parameter points
to.

And for FltSendMessage():
ReplyBuffer
Pointer to a caller-allocated buffer that receives the reply (if any)
from the application. This parameter is optional and can be NULL.

ReplyLength
Size, in bytes, of the buffer that ReplyBuffer points to

The sizeof value for any structure is the offset of the final member, plus
that member’s size, rounded up to the nearest multiple of the largest member
alignment value or the whole structure alignment value, whichever is
greater.

Therefore when FILTER_REPLY_HEADER is added to the header of a user reply,
the resulting struct size may not correspond to the size calculated by
adding up the storage requirements of the individual members.

typedef struct _FILTER_REPLY_HEADER {

NTSTATUS Status;
ULONGLONG MessageId;
} FILTER_REPLY_HEADER, *PFILTER_REPLY_HEADER;

typedef struct _REPLY_FROM_USER {

BOOLEAN ProcessExcluded;
BOOLEAN ProcessAllowed;
} REPLY_FROM_USER, *PREPLY_FROM_USER;

typedef struct _REPLY {

FILTER_REPLY_HEADER ReplyHeader;
REPLY_FROM_USER ReplyFromUser;
} REPLY, *PREPLY;

sizeof(FILTER_REPLY_HEADER) = 16 bytes
sizeof(REPLY_FROM_USER) = 2 bytes
sizeof(REPLY) = 24 bytes (16 + 8 (->2 rounded to the alignment of
FILTER_REPLY_HEADER))

Then sizeof(REPLY) != sizeof(REPLY_FROM_USER) + sizeof(FILTER_REPLY_HEADER).

I suppose FltMgr is validating buffer size computing REPLY_FROM_USER as
sizeof(REPLY) - sizeof(FILTER_REPLY_HEADER) = 8 bytes. Unfortunately the
minifilter will set 2 for ReplyLength in FltSendMessage() and FltMgr expect
8 bytes, so FltSendMessage() returns 0x80000005 (STATUS_BUFFER_OVERFLOW).

Then REPLY_FROM_USER must be aligned properly:

#define REPLY_ALIGN __declspec(align(8))

typedef REPLY_ALIGN struct _REPLY_FROM_USER {

BOOLEAN ProcessExcluded;
BOOLEAN ProcessAllowed;
} REPLY_FROM_USER, *PREPLY_FROM_USER;

Now sizeof(REPLY_FROM_USER) will be 8, as expected by FltMgr.

Note that additional structure types declared with this type as a member
preserve this type’s alignment attribute, that is, any structure with
REPLY_FROM_USER as an element will have an alignment attribute of at least
8.

Thanks,
mK


Express yourself instantly with MSN Messenger! Download today it’s FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

Misha,

I agree with your analysis but this is a fairly common issue that can
show up in lots of different areas.

The simple answer is do not make the assumption that you made. When you
call FilterReplyMessage you should pass in sizeof(REPLY) rather than
assuming that you can simply add the subcomponents together. If you
look at the scanner sample (scanUser.c) you will see that it does this
exact thing.

Neal Christiansen
Microsoft File System Filter Group Lead
This posting is provided “AS IS” with no warranties, and confers no
rights

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Misha Karpin
Sent: Tuesday, March 08, 2005 3:51 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] FltSendMessage return STATUS_BUFFER_OVERFLOW due to an
alignment issue.

Hi,

I think there is an unexpected behavior of FilterReplyMessage() &
FltSendMessage(). It would be convenient to be documented.

FilterReplyMessage() doc says:

lpReplyBuffer
Pointer to a caller-allocated buffer containing the reply to be
sent
to the minifilter. The reply must contain a FILTER_REPLY_HEADER
structure,
but otherwise, its format is caller-defined. This parameter is required
and
cannot be NULL.

dwReplyBufferSize
Size, in bytes, of the buffer that the lpReplyBuffer parameter
points
to.

And for FltSendMessage():
ReplyBuffer
Pointer to a caller-allocated buffer that receives the reply (if
any)
from the application. This parameter is optional and can be NULL.

ReplyLength
Size, in bytes, of the buffer that ReplyBuffer points to

The sizeof value for any structure is the offset of the final member,
plus
that member’s size, rounded up to the nearest multiple of the largest
member
alignment value or the whole structure alignment value, whichever is
greater.

Therefore when FILTER_REPLY_HEADER is added to the header of a user
reply,
the resulting struct size may not correspond to the size calculated by
adding up the storage requirements of the individual members.

typedef struct _FILTER_REPLY_HEADER {

NTSTATUS Status;
ULONGLONG MessageId;
} FILTER_REPLY_HEADER, *PFILTER_REPLY_HEADER;

typedef struct _REPLY_FROM_USER {

BOOLEAN ProcessExcluded;
BOOLEAN ProcessAllowed;
} REPLY_FROM_USER, *PREPLY_FROM_USER;

typedef struct _REPLY {

FILTER_REPLY_HEADER ReplyHeader;
REPLY_FROM_USER ReplyFromUser;
} REPLY, *PREPLY;

sizeof(FILTER_REPLY_HEADER) = 16 bytes
sizeof(REPLY_FROM_USER) = 2 bytes
sizeof(REPLY) = 24 bytes (16 + 8 (->2 rounded to the alignment of
FILTER_REPLY_HEADER))

Then sizeof(REPLY) != sizeof(REPLY_FROM_USER) +
sizeof(FILTER_REPLY_HEADER).

I suppose FltMgr is validating buffer size computing REPLY_FROM_USER as
sizeof(REPLY) - sizeof(FILTER_REPLY_HEADER) = 8 bytes. Unfortunately the

minifilter will set 2 for ReplyLength in FltSendMessage() and FltMgr
expect
8 bytes, so FltSendMessage() returns 0x80000005
(STATUS_BUFFER_OVERFLOW).

Then REPLY_FROM_USER must be aligned properly:

#define REPLY_ALIGN __declspec(align(8))

typedef REPLY_ALIGN struct _REPLY_FROM_USER {

BOOLEAN ProcessExcluded;
BOOLEAN ProcessAllowed;
} REPLY_FROM_USER, *PREPLY_FROM_USER;

Now sizeof(REPLY_FROM_USER) will be 8, as expected by FltMgr.

Note that additional structure types declared with this type as a member

preserve this type’s alignment attribute, that is, any structure with
REPLY_FROM_USER as an element will have an alignment attribute of at
least
8.

Thanks,
mK


Express yourself instantly with MSN Messenger! Download today it’s FREE!

http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com