RFR (S) 8150465: Unsafe methods to produce uninitialized arrays
Paul Sandoz
paul.sandoz at oracle.com
Tue Mar 1 15:03:20 UTC 2016
Hi Jim,
My comment was not an intent to stifle discussion (which it thankfully did not do!) or to exactly equate functionality, it was just pointing out that the unsafe approach of non-zeroing is not uncharted territory when we are all at sea with Unsafe.
FWIW (you may know this already perhaps) Unsafe.allocateMemory is used in the constructor of DirectByteBuffer [*], which zeros out the contents, and is safe because it’s all carefully performed in the constructor.
Paul.
[*]
DirectByteBuffer(int cap) { // package-private
super(-1, 0, cap, cap);
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
Bits.reserveMemory(size, cap);
long base = 0;
try {
base = unsafe.allocateMemory(size);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(size, cap);
throw x;
}
unsafe.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {
address = base;
}
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
att = null;
}
> On 25 Feb 2016, at 23:57, Jim Graham <james.graham at oracle.com> wrote:
>
> Just to play devil's advocate here.
>
> It's true that from a code correctness-safety perspective Unsafe programmers can already shoot themselves in the foot with uninitialized allocations, but from the security point of view the two methods don't have the same opportunity to leak information.
>
> Unsafe.allocateMemory returns a long, which is just a long to any untrusted code since it can't use the Unsafe methods to access the data in it.
>
> The new uninitialized array allocation returns a primitive array which can be inspected by untrusted code for any stale elements that hold private information from a previous allocation - should that array ever be leaked to untrusted code...
>
> ...jim
>
> On 2/25/2016 7:47 AM, Paul Sandoz wrote:
>>
>>> On 25 Feb 2016, at 15:36, Aleksey Shipilev <aleksey.shipilev at oracle.com> wrote:
>>>
>>> On 02/25/2016 05:13 PM, Andrew Haley wrote:
>>>> On 02/25/2016 01:44 PM, Aleksey Shipilev wrote:
>>>>> Of course, you will still see garbage data if after storing the array
>>>>> elements into the uninitialized array you would publish it racily. But
>>>>> the same is true for the "regular" allocations and subsequent writes.
>>>>> The only difference is whether you see "real" garbage, or some
>>>>> "synthetic" garbage like zeros. It is, of course, a caller
>>>>> responsibility to publish array safely in both cases, if garbage is
>>>>> unwanted.
>>>>
>>>> Of course, my worry with this optimization assumes that programmers
>>>> make mistakes. But you did say "complicated processing is done after
>>>> the allocation." And that's where programmers make mistakes.
>>>
>>> Of course they do; at least half of the Unsafe methods is suitable for
>>> shooting oneself in a foot in creative ways. Unsafe is a sharp tool, and
>>> Unsafe callers are trusted in their madness. This is not your average
>>> Joe's use case, for sure.
>>>
>>
>> FTR the contents of the memory allocated by Unsafe.allocateMemory are also uninitialized.
>>
>> Paul.
>>
More information about the jdk9-dev
mailing list