Bug 698325 - C++ Messaging .NET Binding: copied objects lead to obscure memory access violations.
Summary: C++ Messaging .NET Binding: copied objects lead to obscure memory access viol...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: qpid-sdk
Version: 1.3
Hardware: All
OS: Windows
high
high
Target Milestone: 3.0
: ---
Assignee: Chuck Rolke
QA Contact: Petra Svobodová
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-04-20 16:07 UTC by Chuck Rolke
Modified: 2014-09-24 15:02 UTC (History)
3 users (show)

Fixed In Version: 0.16
Doc Type: Bug Fix
Doc Text:
It was discovered that copied .NET Binding objects were not properly managed, which resulted in references to copies of deleted objects causing fatal System.AccessViolationException traps. The fix implements logic to detect deleted object references, and throw a catchable .NET exception that allows the user to continue.
Clone Of:
Environment:
Last Closed: 2014-09-24 15:02:36 UTC
Target Upstream Version:


Attachments (Terms of Use)
Setup instructions and code to test this bz using Managed C++ (2.20 KB, text/plain)
2011-12-23 14:52 UTC, Chuck Rolke
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHEA-2014:1296 0 normal SHIPPED_LIVE Red Hat Enterprise MRG Messaging 3.0 Release 2014-09-24 19:00:06 UTC

Description Chuck Rolke 2011-04-20 16:07:20 UTC
Description of problem:

See https://issues.apache.org/jira/browse/QPID-3193

The .NET Binding does not deal well with copied .NET binding objects.

(1) Message mA = new Message("a");
(2) Message mB = mA;
...
(N) mB.Dispose();

After disposing of message mB then message mA is clobbered. 'Message' is a 'ref class' type and messages mA and mB refer to the same object on managed heap. When message mB is disposed then the bound C++ Messaging object is deleted. Any reference to the bound message part of mA will result in an illegal memory reference (to 0).

All references to bound message objects need:
1. A lock to prevent aliased copies from deleting the bound C++ objects.
2. A NULL test with a throw to prevent accessing deleted bound C++ objects.

Version-Release number of selected component (if applicable):

2.0.0.1

How reproducible:

100%

Steps to Reproduce:
1. See description above.
  
Actual results:

Exception System.AccessViolationException: 
  Attempted to read or write protected memory. 
  This is often an indication that other memory is corrupt.
   at qpid.messaging.Message.getContentSize(Message* )
   at Org.Apache.Qpid.Messaging.Message.get_ContentSize() in 
      d:\qpid\cpp\bindings\qpid\dotnet\src\message.h:line 350
   at Org.Apache.Qpid.Messaging.Program.Main(String[] args) in 
      D:\qpid\cpp\...\csharp.example.helloworld.cs:line 80.


Expected results:

 A formal ObjectDisposedException.

Additional info:

 This could be fixed with the addition of:

   msclr::lock lk(lockObject);

   if (NULL == messagep)
      throw gcnew ObjecteDisposedException("Message");

 to each bound function and property accessor.

Comment 1 Chuck Rolke 2011-12-21 18:55:18 UTC
This problem is fixed upstream at checkin r1221824.
The following test program:

 class Program {

   static void Main(string[] args) {
    Message msgA = new Message("abc");
    Message msgB = msgA;

    // Now msgA and msgB are .NET references to the same .NET Message.
    // Disposing of either of them disposes of the other.
    msgB.Dispose();

    // Check that Message msgA is still safe
    Console.WriteLine("Message msgA IsDisposed : {0}", msgA.IsDisposed);

    // msgA is disposed. Reference it anyway and get the exception.
    try
    {
      Console.WriteLine("Message msgA content = {0}", msgA.GetContent());
    }
    catch (Exception e)
    {
      Console.WriteLine("Exception {0}.", e);
    }
  }
 }

Produces the following output:

Message msgA IsDisposed : True
Exception System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Org.Apache.Qpid.Messaging.Message'.
   at Org.Apache.Qpid.Messaging.Message.ThrowIfDisposed() 
     in d:\qpid\cpp\bindings\qpid\dotnet\src\message.cpp:line 54

   at Org.Apache.Qpid.Messaging.Message.GetContent() 
     in d:\qpid\cpp\bindings\qpid\dotnet\src\message.cpp:line 413

   at Org.Apache.Qpid.Messaging.Program.Main(String[] args) 
     in D:\qpid\cpp\bindings\qpid\dotnet\examples\example\example.cs:line 127.


Clearly the ObjectDisposedException provides useful information for a user
who expects his exception handler to actually work.

Comment 2 Chuck Rolke 2011-12-23 14:52:11 UTC
Created attachment 549357 [details]
Setup instructions and code to test this bz using Managed C++

Microsoft .NET Managed C++ behaves differently from other .NET languages.
I set up a C++ project to characterize and to test this bug and in the process had several difficulties getting started. This attachment may help testers who want to get started using C++ instead of C#.

Comment 3 Chuck Rolke 2013-01-23 19:42:34 UTC
This bug has been fixed for a while (since 0.16).

Comment 4 Petra Svobodová 2013-04-15 09:30:36 UTC
The bug was reproduced on qpid-cpp-win-3.0.0.5-1; on qpid-cpp-win-3.2.0.4-1 did not occur.

Comment 5 Petra Svobodová 2013-06-26 06:23:57 UTC
References to deleted objects are detected and correct type of exception (System.ObjectDisposedException) is raised.

Verified on packages qpid-cpp-win-3.22.5.1-1 on all supported Windows platforms: WindowsXP-x86, Windows7-x86 and x64, Windows Server2003-x86 and x64, Windows Server2008-x86, x64 and R2.

--> VERIFIED

Comment 8 errata-xmlrpc 2014-09-24 15:02:36 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHEA-2014-1296.html


Note You need to log in before you can comment on or make changes to this bug.