[Mono-list] IntPtr safety (was: need some help with PInvoke..)

Jonathan Pryor jonpryor@vt.edu
10 Jul 2003 22:27:33 -0400


Inline...

On Thu, 2003-07-10 at 18:42, David Jeske wrote:
> Looks like my PInvoke and Marshaling lesson is done. Thanks again for
> the great help! This post is just a few general discussion comments on
> IntPtr wrt VB and Security.
> 
> On Thu, Jul 10, 2003 at 02:13:33PM -0400, Jonathan Pryor wrote:
> > Well, to speak on .NET's behalf, .NET has a highly flexible security
> > system.  You can't invoke DllImported functions unless your app has the
> > appropriate security rights -- generally, that the app is running on the
> > local machine.  If you're running it from a network share, or from a web
> > site (similar to Java Applets), then your app will get a
> > SecurityException.
> 
> Is there a way to disallow an assembly from calling any function which
> takes an IntPtr paramater or void* paramater? It seems to me that this
> would be required to stop sandboxed code from segfaulting the
> system. Otherwise I can just hand an HWND IntPtr I get from "secure
> ok" S.W.F code, and hand it to "secure ok" Gtk code, and poof. :)

Yes.  System.Security.Permissions.SecurityPermission is needed with
SecurityPermissionFlag.UnmanagedCode specified in order to perform a
P/Invoke.

Programs can't specify this permission, though, they can only request it
(or demand it, and if they can't get it, a SecurityException is thrown).

Administrators are the people who specify what permissions an
application actually receives.

That's about the limits of my knowledge -- Security isn't my forte.  You
might find the following topics interesting.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconrequestingpermissions.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconsecuritysyntax.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcodeaccesssecurity.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconinheritancedemands.asp

> > >  - If I want to reference the data in-place in unmanaged memory, I use
> > >    an unsafe struct and a struct pointer.
> > > 
> > >  - Since an IntPtr is basically a void*, I don't see why I would ever
> > >    use it, unless the external call actually takes a void*.
> > 
> > You would use it if you need to expose the member to languages other
> > than C#/C++.  For example, Visual Basic has no syntax for "unsafe" code,
> > and thus you couldn't use Visual Basic to perform your 2nd option.  If
> > you want your code to be usable by other languages, you'll need to
> > provide an appropriate wrapper.
> 
> I guess this is my confusion. HWND* is _safer_ than IntPtr, because it
> is a pointer to a specific type. It's the operations on HWND* that are
> unsafe. It seems like it would be better if VB (and other languages
> without unsafe) had the ability to express HWND*, and simply not
> operate on it.
> 
> Certainly this:
>     .field  public   valuetype HDF* p
> 
> Is better than this:
>     .field  public   native int p
> 
> Ohh well... maybe it'll get in the queue for .NET 2.0. although I'm
> much more excited about parametric types than I am worried about this.

I suspect this was done in the name of "simplification."  "Pointers are
bad" (say that with the South Park Counselor Mr. Mackey's voice ;-), and
hence must be avoided at all costs.  At least, thus goes conventional
wisdom.

You can't use references to replace pointers, as references imply
garbage collection.  You can't use structures, as they're always a
copy.  So, if "pointers are bad" (whatever the reason), then the only
choice left is IntPtr.

Which, as you note, is non-ideal.  But it's the current solution, and
likely to remain the *only* cross-language solution (unless you want to
add pointers to the Common Language Subset ;-).  And if they're not part
of the CLS, then it's not an appropriate cross-language solution.

So it's not really an issue of runtime support.  C# and C++ both allow
you to use pointers, and both run within the runtime.  Instead, it's a
matter of language support.  Unless you want VB, JavaScript, Java, Perl,
Python, Lisp (or some dialect), O'Caml, etc. to support pointers -- and
have the stomach to actually suggest this to their users! -- pointers
can't be considered as a solution.

 - Jon