On Fri, Jun 7, 2024 at 1:19 PM Ron Pressler <ron.press...@oracle.com> wrote:
> > > On 6 Jun 2024, at 18:37, David Lloyd <david.ll...@redhat.com> wrote: > > > > Just bumping this one more time. I intend to start by opening a JIRA to > add the two proposed methods to `ReflectionFactory`, and go from there. I > guess that we might need a JEP for the proposed serialization restrictions, > which is going to be considerably more involved, so I'm putting that off as > a second step for now, pending further discussion. > > > Hi. > > Seven years before the upcoming delivery of JEP 471 we [announced that the > world of accessing JDK internals would be coming to an end]( > https://openjdk.org/jeps/260). Four years later, the JDK [started > enforcing that](https://openjdk.org/jeps/403), but to give extra time to > laggards who have not yet adapted to either refraining from accessing > internals or instructing their users on the proper configuration of the JDK > to allow doing so, we left some unsupported mechanisms in place to > temporarily allow hacking around the restrictions until they can properly > adapt. Now, three years later, we're starting the process of removing the > temporary hacks, although we don't yet know how long the process should > last. > > My first question is, how many more years do you think we should wait for > libraries to finish the process by which they either refrain from accessing > internals or instruct their users on the proper configuration that allows > them to do so? Knowing how long we should wait for the libraries that have > not yet finished their adaptation in the past seven years, and how far > along they are in the process, could help inform how long we should wait > until the actual removal of Unsafe. > > My second question has to do with the consideration that any serialization > procedure should no longer bypass constructors (at least not without > `--add-opens`, that is). I'd be interested to know about the difficulties > serialization libraries have encountered in their process of migrating away > from accessing internals and toward custom serializers for JDK classes, > such as what public constructors are missing. This would help us identify > what constructors we should add to support serialization that doesn't > violate integrity. > The first thing to understand is that, unlike APIs in the JDK which may only be implemented *in* the JDK, serialization is governed by a specification [1]. This specification is still implemented by multiple external libraries (including the OpenJDK ORB) as well as the JDK itself. We aren't talking about libraries which invent some arbitrary kind of serialization that requires unsafe object creation. We're talking about libraries which conform to some or all of the serialization specification. If you look back at the history of the discussion of serialization support with regards to the JDK (which is referenced in the history of this email thread), it was determined at the time of Java 9 that serialization would be considered an exception to the rule of reflection restrictions, for purely pragmatic reasons. Brian Goetz has talked frequently about the limitations of existing serialization and how this impacts the platform in various ways. He's also hinted at a future where some alternative serialization mechanism exists which would presumably avoid the need for the things we find in `ReflectionFactory`. However we don't live in that world just yet. So, to answer your first question ("How many more years...") I would start by modifying the question. It's not about waiting for libraries; I think this greatly mischaracterizes the problem. It's about waiting for OpenJDK to have a new serialization mechanism. Until then, there is no replacement, so we're in a holding pattern, like it or not. At best we're talking about small, monotonic improvements which bring the platform closer to the goal of integrity. And so the answer to the first question is, "however many years it takes for there to be an alternative, blessed OpenJDK serialization mechanism", which presumably will involve both language and core library modifications. For your second question, serialization *must*, by specification, bypass constructors in the bottom part of the serializable class's type hierarchy which correspond to serializable classes (most frequently this means everything other than `Object` itself, but occasionally there are more levels involved). If the platform were to drop that support, then all serialization libraries would break, including the OpenJDK ORB, and the specification would be unimplementable. The serialization specification is not deprecated. Nor are the classes which support serialization in the JDK. So in my opinion it would not yet be appropriate to break these things. In order to tackle this particular corner of platform integrity, those two problems must be addressed first and foremost, and such an action would necessarily involve a deprecation cycle on serialization as a whole. I would also like to be very clear that I am not proposing adding a mechanism to bypass constructors. Such a mechanism already exists on ReflectionFactory, and has not been deprecated. I am proposing that any caller which already has permission to do such a thing (and the other integrity-bypassing things already provided by this existing API) should also have permission to implement the remainder of the specification as well (reading and writing fields), and to do so using this same API, rather than Unsafe. In my view this is absolutely a monotonic step in the right direction (i.e. towards platform integrity), since we're putting all of the "offenders" into one bucket based on use case. It might be shocking to discover the existence of these APIs if one wasn't already aware of them. Presently, these APIs have essentially no restrictions (ignoring security manager). They're even easier to access than Unsafe, in fact. Therefore, I would suggest that another monotonic improvement would be to restrict these APIs under a command-line switch, like FFM is. In this way, we've unambiguously moved towards platform integrity, at least as far as it is currently possible to do so. Nothing would be enabled that isn't already possible, and some things that are now possible would be unambiguously restricted. Requiring `--add-opens` for ORBs/serialization probably isn't practical. It is important to note that in addition to user classes, a large number of JDK classes are serializable, spanning many packages. The burden on users would be extremely high in this case. Is it really better for users to have to list every package containing a serializable class, than to opt in wholesale to saying "I want serialization to be allowed for module X"? We don't (and wouldn't) do the same for native access for example, even though a similar level of access is given. In fact one *could* use native access to achieve the same thing, though this would be unfortunate on several levels. Another reason that requiring `--add-opens` would be inadequate is that ReflectionFactory allows bypassing not just access restrictions, but also certain provisions of the language and JVM specifications. Do we really want any open package to be accessible in this way? Do we really want this API to remain unrestricted? I would think that we would all agree that we do not. Yet, deprecation is not yet indicated for the reasons given above. I think restriction is the only answer here. And if this API is already restricted, why not let the implicit contract of that restriction carry the user's intent to grant serialization access to certain modules? Surely it could be made clear what such access entails, much as we do for FFM which has similar risks (and more). [1] https://docs.oracle.com/en/java/javase/22/docs/specs/serialization/index.html -- - DML • he/him