64 bit driver with 32 bit app

hello,
i am trying to get sid from a 64 driver from a 32 bit application. here is my code to do that.

typedef struct sid_event_t
{


ULONG_PTR fileobj;
ULONG sa_size;
SID_AND_ATTRIBUTES sa;
UCHAR sid[1];
} sid_event_t;

i am using the Zw API to get the sid. it works i could see the sid in the debugger.
however when i send this to 32 bit app upon IOCTL then in the user mode app IsVAlidSid reports that it is invalid sid. i doubt that this is a 64 bit thunking issue.

here is my IOCTL code
BYTE m_ioctlBuf[IOCTL_BUF_SIZE];

BOOL rc = DeviceIoControl(m_hDriver, IOCTL_READ_EVENT, NULL, 0,
m_ioctlBuf, sizeof(m_ioctlBuf), &m_ioctlBytesReturned, &m_olIoctl);

in side the driver i typecast it and then return it

NTSTATUS copyToUser(PIRP irp, PIO_STACK_LOCATION irps, sid_event_t *evt, PULONG info)
{
NTSTATUS status;
sid_event_t*data;

ULONG cbout = irps->Parameters.DeviceIoControl.OutputBufferLength;

if (cbout < calcRequiredBufSize(evt))
{
status = STATUS_INVALID_BUFFER_SIZE;
goto error;
}

data = (sid_event_t *)MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
if (!data)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto error;
}

data->fileobj = evt->fileobj;
data->sa_size = evt->sa_size;
if (evt->sa)
RtlCopyMemory(&data->sa, evt->sa, evt->sa_size);
data->sa.Sid = NULL;

status = STATUS_SUCCESS;

error:
return status;
}

now in the application i use

CSid sid;

_ATLTRY
{
sid.LoadAccount((const SID *)evt->sa.Sid);
sid.AccountName();
}
_ATLCATCHALL()
{

//fails here
}

could someone show a light on this?

regards
d

You have a ULONG_PTR that will be 32 bits in the app, but defined as
64-bits in the driver so you are not accessing the right data. Of
course the bigger question is why you are handing back a file object (I
assume that is what fileobj is) in the first place. The user
application cannot use it directly, and having the user app pass it back
to the driver for use is a dangerous security hole.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“xxxxx@yahoo.co.in” wrote in message
news:xxxxx@ntdev:

> hello,
> i am trying to get sid from a 64 driver from a 32 bit application. here is my code to do that.
>
> typedef struct sid_event_t
> {
> …
> …
> ULONG_PTR fileobj;
> ULONG sa_size;
> SID_AND_ATTRIBUTES sa;
> UCHAR sid[1];
> } sid_event_t;
>
> i am using the Zw API to get the sid. it works i could see the sid in the debugger.
> however when i send this to 32 bit app upon IOCTL then in the user mode app IsVAlidSid reports that it is invalid sid. i doubt that this is a 64 bit thunking issue.
>
> here is my IOCTL code
> BYTE m_ioctlBuf[IOCTL_BUF_SIZE];
>
> BOOL rc = DeviceIoControl(m_hDriver, IOCTL_READ_EVENT, NULL, 0,
> m_ioctlBuf, sizeof(m_ioctlBuf), &m_ioctlBytesReturned, &m_olIoctl);
>
> in side the driver i typecast it and then return it
>
> NTSTATUS copyToUser(PIRP irp, PIO_STACK_LOCATION irps, sid_event_t evt, PULONG info)
> {
> NTSTATUS status;
> sid_event_t
data;
>
> ULONG cbout = irps->Parameters.DeviceIoControl.OutputBufferLength;
>
> if (cbout < calcRequiredBufSize(evt))
> {
> status = STATUS_INVALID_BUFFER_SIZE;
> goto error;
> }
>
> data = (sid_event_t *)MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
> if (!data)
> {
> status = STATUS_INSUFFICIENT_RESOURCES;
> goto error;
> }
>
> data->fileobj = evt->fileobj;
> data->sa_size = evt->sa_size;
> if (evt->sa)
> RtlCopyMemory(&data->sa, evt->sa, evt->sa_size);
> data->sa.Sid = NULL;
>
> status = STATUS_SUCCESS;
>
> error:
> return status;
> }
>
> now in the application i use
>
> CSid sid;
>
> _ATLTRY
> {
> sid.LoadAccount((const SID *)evt->sa.Sid);
> sid.AccountName();
> }
> _ATLCATCHALL()
> {
>
> //fails here
> }
>
>
> could someone show a light on this?
>
> regards
> d

> data = (sid_event_t *)MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);

And here you always interpret “data” as 64bit structure.

The simplest way is to throw away the “fileobj” field from the structure, anyway the file object pointer is not valid for user mode.

Another way is - see MSDN docs and recent archives of this forum, about declaring 2 structures, one used for 32/32 and 64/64 cases, and another for 32app/64driver case.

Search for “IoIs32BitProcess”.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com