diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-08-04 01:58:33 -0700 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-08-08 13:42:36 +1000 |
commit | 498a2ce7397b909c0bebf36affeb1ee5a1c03d6a (patch) | |
tree | abcfcf39af3231ade6402d30acca548704711311 /src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala | |
parent | 2b172be8c83c3146d3fd5ab01546c171ab18fa46 (diff) | |
download | scala-498a2ce7397b909c0bebf36affeb1ee5a1c03d6a.tar.gz scala-498a2ce7397b909c0bebf36affeb1ee5a1c03d6a.tar.bz2 scala-498a2ce7397b909c0bebf36affeb1ee5a1c03d6a.zip |
SD-193 Lock down lambda deserialization
The old design allowed a forged `SerializedLambda` to be
deserialized into a lambda that could call any private method
in the host class.
This commit passes through the list of all lambda impl methods
to the bootstrap method and verifies that you are deserializing
one of these.
The new test case shows that a forged lambda can no longer call
the private method, and that the new encoding is okay with a large
number of lambdas in a file.
We already have method handle constants in the constant pool
to support the invokedynamic through LambdaMetafactory, so
the only additional cost will be referring to these in
the boostrap args for `LambdaDeserialize`, 2 bytes per lambda.
I checked this with an example:
https://gist.github.com/retronym/e343d211f7536d06f1fef4b499a0a177
Fixes SD-193
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala index c2010d2828..1dbb18722f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala @@ -283,7 +283,21 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) { List( coreBTypes.jliMethodHandlesLookupRef, coreBTypes.StringRef, - coreBTypes.jliMethodTypeRef + coreBTypes.jliMethodTypeRef, + ArrayBType(jliMethodHandleRef) + ), + coreBTypes.jliCallSiteRef + ).descriptor, + /* itf = */ coreBTypes.srLambdaDeserialize.isInterface.get) + lazy val lambdaDeserializeAddTargets = + new scala.tools.asm.Handle(scala.tools.asm.Opcodes.H_INVOKESTATIC, + coreBTypes.srLambdaDeserialize.internalName, "bootstrapAddTargets", + MethodBType( + List( + coreBTypes.jliMethodHandlesLookupRef, + coreBTypes.StringRef, + coreBTypes.jliMethodTypeRef, + ArrayBType(coreBTypes.jliMethodHandleRef) ), coreBTypes.jliCallSiteRef ).descriptor, |