Re: FW: SYSTEM_SERVICE_EXCEPTION (3b)

Osman TOKER wrote:

Hi Tim,
Thanks for reply, it is the most complicated error i ever seen for this job(cause i didnt write the codes) Ý want to post u the log and codes. I guess that the error is about ExAllocBuffer but i’m not sure…

Did you take a look at the dump? The issue was this instruction:
movzx eax, word ptr [rax+r8*2]
which is fetching a word from a table, and the address in rax is
00000000_07afb000. Your thread’s stack is at fffff880_07a678b0. That’s
suspicious. If I were a gambling man, I’d say you passed a pointer in a
DWORD somewhere and lost the upper 32 bits.

And, since you sent me the source code, I can even see where that is
happening. You are passing “struct driver_in_buff_s” and “struct
driver_out_buff_s” through your ioctls (although you hide that fact in
the way you implement those functions). The first element in each case is:
unsigned long int translated_base_address;

An “unsigned long int” is 32 bits. That is not large enough to hold an
address in a 64-bit system.

This means you have some work to do. The simplest solution is to change
the “unsigned long int” to an “unsigned __int64”. That means you will
have to recompile your application as well.

However, stepping back a bit, it is extremely dangerous to have your
driver pass a kernel address up to user mode, and to have your driver
TRUST that the address it was handed is valid. You should seriously
consider a safer design. There is no reason to pass the
“translated_base_address” up to user mode to begin with. Just let the
kernel driver keep the base address. If you need the user-mode app to
pass an offset into that space, that’s fine. An offset can be
validated. A raw pointer cannot.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

In addition, you will want to use size_t or UINT_PTR for that offset instead
of unsigned __int64 or any other fixed size type. This will involve some
extra work in KM to detect when the interface is being used by a 32-bit app,
but a simple byte count check or field will make your life much better.
This way you can even support multiple versions of your application /
interface in the same binary if necessary and never have this kind of
problem again

“Tim Roberts” wrote in message news:xxxxx@ntdev…

Osman TOKER wrote:

Hi Tim,
Thanks for reply, it is the most complicated error i ever seen for this
job(cause i didnt write the codes) Ý want to post u the log and codes. I
guess that the error is about ExAllocBuffer but i’m not sure…

Did you take a look at the dump? The issue was this instruction:
movzx eax, word ptr [rax+r8*2]
which is fetching a word from a table, and the address in rax is
00000000_07afb000. Your thread’s stack is at fffff880_07a678b0. That’s
suspicious. If I were a gambling man, I’d say you passed a pointer in a
DWORD somewhere and lost the upper 32 bits.

And, since you sent me the source code, I can even see where that is
happening. You are passing “struct driver_in_buff_s” and “struct
driver_out_buff_s” through your ioctls (although you hide that fact in
the way you implement those functions). The first element in each case is:
unsigned long int translated_base_address;

An “unsigned long int” is 32 bits. That is not large enough to hold an
address in a 64-bit system.

This means you have some work to do. The simplest solution is to change
the “unsigned long int” to an “unsigned __int64”. That means you will
have to recompile your application as well.

However, stepping back a bit, it is extremely dangerous to have your
driver pass a kernel address up to user mode, and to have your driver
TRUST that the address it was handed is valid. You should seriously
consider a safer design. There is no reason to pass the
“translated_base_address” up to user mode to begin with. Just let the
kernel driver keep the base address. If you need the user-mode app to
pass an offset into that space, that’s fine. An offset can be
validated. A raw pointer cannot.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Osman TOKER wrote:

I changed the long int definitions but unfortunately the same error continues.
I’m not sure the casting definitions, i will look at this but i dont understand what u mean about user mode.

Really? I’m not sure how you can hope to be doing driver development if
you don’t understand the concepts of “kernel mode” and “user mode”.

Your driver doesn’t do anything on its own. A driver exists solely to
service requests from applications (which run in “user mode”). An
application will find your driver and create a file handle for it, then
call DeviceIoControl to send ioctl requests. That’s the only way any
part of your driver can run.

Those structures that you modified are sent from an application to your
driver. Your driver acts on them, and the returns information back to
the application. You can’t just modify the structure in the driver,
because the application will still be sending the old structure. The
two have to agree. You have to modify the structure in the application,
and then recompile the application.

The way this is currently architected, you will have to make other
changes in the application as well. Right now, your application asks
the driver for the base address of the board’s registers, and then hands
that address back to the driver for reading and writing. Besides being
a HUGE security hole (the application could pass back ANY kernel address
– your driver doesn’t check it), you now have the address size
problem. The pointer your driver sends back needs to be 64 bits wide.
That means your application needs to have a 64-bit-wide variable to hold
the address. If the application stores the address in an unsigned long,
you’ll still have the same crash. Even if you store the address in a
“void *”, if you compile the application as 32 bits, you will have the
same crash.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.