RFR (S) 8150465: Unsafe methods to produce uninitialized arrays

Aleksey Shipilev aleksey.shipilev at oracle.com
Fri Feb 26 07:01:39 UTC 2016


Unsafe is unsafe, no doubt about it.

But if you accept the premise that Unsafe.allocateUninitializedArray is
wrong because it can leak data from previous allocation if used
incorrectly, then you should equally accept that compilers should not do
the same automatic optimization too. Even more so, because the compiler
code is much harder to audit for these mistakes; and programmers *do*
make mistakes in that complicated compiler code.

Notable examples in C2 are OptimizeStringConcat allocating uninitialized
array for String (pretty much what we are targeting to do here), and
subsequent arraycopy eliminating the array zeroing in a "tightly
coupled" allocation. But, we do these optimizations already.

Unsafe users *have* to provide an additional protection to avoid such
leakage, pretty much how compilers *have* to guarantee safety in those
situations too.

Even without Unsafe.allocateUninitializedArray, I can certainly
construct the buggy JDK code that will leak uninitialized memory to
untrusted code: a simple mistake in offset calculation for
Unsafe.getX(long,long) is enough to leak. Yet, we don't nuke the raw
memory accessors from Unsafe, because they are useful, and we do
understand those are sharp tools, and we should be extra careful using
them.

The same goes for any other Unsafe method. If you treat
U.allocateUninitializedArray with the same respect you treating other
tools in that toolbox, everything is fine. If you don't, then stay away
from Unsafe to begin with. Unsafe is unsafe, there is no doubt about it.

-Aleksey

On 02/26/2016 01:57 AM, Jim Graham 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