The original offending script is a bit on the heavy side, but I'm sure I
can come up with something that trips the overwrite. The trick might be
in systematically identifying the problem when it happens, since in my
case it was detected during a debugging session, based in part on compiler
specifics; I think the heap from which the memory is allocated depends on
the distribution of Perl, so I'm not sure how best to interrogate heap
integrity. One possible approach is to add a croak to callback.xs to
validate that the final byte written to the cursor pointer falls within
the code memory allocation, and then confirm that -- without your fix --
any use of the callback trips the error. (I think, at least by
inspection, the overwrite is likely to happen regardless of the callback
signature, although it's hard for me to say, because some of the callback
creation logic is dependent on what the compiler emits for the template
function. I was working with a callback that returned void and accepted 6
32-bit words on the stack.)
I'm looking at 0.57 source, with a callback.xs source control revision of
109. I apologize because I don't have my development environment set up
to build extensions from source, but I think something after line 804
(after the epilogue is written) like the following would help with
testing:
if (code + tomalloc <= cursor) {
croak("CallbackCreate cursor exceeds memory buffer allocation
boundary");
}
I suppose a WIN32_API_DEBUG printf message might help also, but would
presumably not break the test script. Of course, if the code does in fact
continue to exhibit an overwrite bug, it might destabilize the extension
enough to not run the check (since, by line 804, the corruption is already
committed, and could arguably have resulted in a segfault).
Anyway, I'm writing this "off the cuff," and I'm by no means an expert in
Perl extension development, particularly test scripts. I was actually
working on embedding Perl in a Windows application, and was using the
Callback extension to enable a script to interface with yet another native
Windows library. I've learned a lot about Perl guts, and have climbed
some of the learning curve around extension subroutines, but not high
enough to be of much help. I'm not sure if this is the sort of guidance
for which you were looking, but apart from some defensive programming, I'm
not sure how to detect the problem reliably. I was using precompiled
binaries from ActiveState, so it's entirely possible the behavior is
different with a different runtime heap, a different Perl allocation
scheme (ActiveState uses a VMem object attached to CPerlHost to implement
PerlMem_malloc), or a different compiler (which might make a different
template function, and thus, change how RelocateCode is called). I don't
see an obvious way to screen for the problem across compilers and across
different implementations of the interpreter, but if you'd like me to give
it more thought -- or focus on just ActiveState binaries -- I'm happy to
help if I can.
Best,
Jim
James M. Brackett
Financial Technology Practice
Milliman, Inc.
71 S. Wacker Drive
31st Floor
Chicago, IL 60606
Telephone: (312) 726-0677
FAX: (312) 726-5225
E-Mail: jim.brackett@milliman.com
"Cosimo Streppone via RT" <bug-Win32-API@rt.cpan.org>
01/13/2009 02:22 PM
Please respond to
bug-Win32-API@rt.cpan.org
To
jim.brackett@milliman.com
cc
Subject
[rt.cpan.org #42218] Win32::API::Callback Heap Allocation Size
<URL:
https://rt.cpan.org/Ticket/Display.html?id=42218 >
Jim wrote:
Show quoted text> Although I did not recompile from source, I did apply a binary
> patch to the DLL to replace the +3 with +4, and the modified binary
> worked perfectly, precisely filling the heap block with code, and not
> yielding any heap corruption.
Hi Jim,
I made the change, but I'd like to add a proper test case for that.
Can you send me the example script that caused the problem? Or can you
help me build a test case for this bug?
Thanks again.
**************************************************************************************
This communication is intended solely for the addressee and is
confidential. If you are not the intended recipient, any disclosure,
copying, distribution or any action taken or omitted to be taken in
reliance on it, is prohibited and may be unlawful. Unless indicated
to the contrary: it does not constitute professional advice or opinions
upon which reliance may be made by the addressee or any other party,
and it should be considered to be a work in progress. Unless otherwise
noted in this email or its attachments, this communication does not form
a Statement of Actuarial Opinion under American Academy of Actuaries guidelines.
**************************************************************************************