[foreign-abi] minimizing the surface of restricted native access
Jorn Vernee
jorn.vernee at oracle.com
Mon Dec 2 15:58:35 UTC 2019
I really like how the patch looks. It makes more operations safe, and
allows users to apply safety where possible (as shown by the tests).
I noticed that there is a bounds check in `rebase`, but this is not
needed -> if an address is OOB, we still can not access it after a
rebase any ways. I can see how this can help to fail fast in some cases,
but we've already soon OOB pointers being useful, so sooner or later we
might encounter a use-case where this bounds check would be prohibitive.
e.g. even if a MemoryAddress is inaccessible because it's out of bounds,
it could still be useful to rebase it onto another segment in order to
get a MemoryAddress object tied to the lifetime of that segment.
One minor suggestion I have wrt the patch is that you could create a
Util::resizeNativeUnchecked(MemoryAddress, long) that does the resize,
so that the cast can be removed from callers (looks a little less
cluttered imo).
Jorn
On 02/12/2019 15:55, Maurizio Cimadamore wrote:
> Following up on this piece of feedback, Jorn and I came up with a more
> robust strategy; instead of converting an address to an unchecked
> address, the API will instead allow creation of an 'unsafe' native
> memory segment with its own temporal bounds and spatial bounds:
>
> /**
> * Returns a new native memory segment with given base address and
> size. The returned segment has its own temporal
> * bounds, and can therefore be closed; closing such a segment
> does <em>not</em> result in any resource being
> * deallocated.
> * @param base the desired base address
> * @param byteSize the desired size.
> * @return a new native memory segment with given base address and
> size.
> * @throws IllegalArgumentException if {@code base} does not
> encapsulate a native memory address.
> */
> public static MemorySegment ofNativeUnchecked(MemoryAddress base,
> long byteSize) { ... }
>
>
> This allows clients to pass an address to be used as a 'base', a
> desired size and obtain a new segment with that base and size. This of
> course overrides whatever size information might have been previously
> available in the input address (hence the unsafety). This method can
> thus create segments which can be used as a target of a
> MemoryAddress::rebase operation, in case the user wants to break free
> from the restriction of the Nothing segment.
>
> I went ahead and implemented the rebase+ofNativeUnchecked approach:
>
> http://cr.openjdk.java.net/~mcimadamore/panama/nothing_segment/
>
> I think the results are pleasing; StdLibTest already showcases a
> couple of calls which require rebasing:
>
> * strcat - result of strcat needs to be rebased against segment
> associated with first parameter of strcat (safe)
> * qsort - the upcall needs to rebase its incoming addresses against
> the segment associated with the native array to be sorted (safe)
> * Tm struct - since this struct is constructed out of a pointer
> returned by a native call (gmtime), best we can do here is to rebase
> that pointer against a fresh unchecked segment whose size is the
> (known) size of the Tm struct (unsafe)
>
> When writing the patch, I liked the fact that things failed if the
> dereference address was 'not trusted' - and I also appreciated the
> usefulness of veering into unsafe territory, but in a more gentle way
> which still allows for bounds and liveness checks.
>
> Maurizio
>
> On 27/11/2019 18:32, Ioannis Tsakpinis wrote:
>>> But what if a client really wants to dereference a_random_ pointer
>>> generated by a library? In this case, the client has no well-known
>>> segment which can be used as a rebase target, so, what can be done?
>>> This
>>> is where we need to veer into restricted native access territory, and
>>> provide some escape hatch by which an untrusted address can be made
>>> trusted again. There are many ways to do that; perhaps the simplest is
>>> to add a new method on MemoryAddress:
>>>
>>> MemoryAddress asUnchecked()
>>>
>>> which returns a new memory address which point to same location as the
>>> original address, but whose access is neither spatially, nor temporally
>>> checked.
>> This doesn't sound so good.:)
More information about the panama-dev
mailing list