Skip to content

Commit

Permalink
Added configs for sandbox features, added TrapSite, began work on boo…
Browse files Browse the repository at this point in the history
…tstrapping TrapSite dynamic constants.
  • Loading branch information
danielperano committed Nov 4, 2023
1 parent e00ed9b commit 30875c7
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 22 deletions.
12 changes: 6 additions & 6 deletions Lang/src/main/java/chipmunk/vm/TrapHandler.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package chipmunk.vm;

import chipmunk.vm.jvm.TrapSite;

public interface TrapHandler {

default void runtimeTrap(Object payload){}

// TODO - replace this verbosity with dynamically computed constants
default void backJump(String cls, String method, int line){}
default void methodCall(String cls, String method, int line,
default void backJump(TrapSite site){}
default void methodCall(TrapSite site,
String targetCls, String targetMethodName, String targetMethodSignature){}

default void recursiveCall(String cls, String method, int line){}

default void arrayAlloc(String cls, String method, int line, int dimensions, int capacity){}
default void arrayAlloc(TrapSite site, int dimensions, int capacity){}

default void objectAlloc(String cls, String method, int line, String targetCls, String targetConstructorSignature){}
default void objectAlloc(TrapSite site, String targetCls, String targetConstructorSignature){}

}
133 changes: 117 additions & 16 deletions Lang/src/main/java/chipmunk/vm/jvm/JvmSandboxingVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@

package chipmunk.vm.jvm;

import chipmunk.vm.invoke.security.LinkingPolicy;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

Expand All @@ -40,29 +37,31 @@ public boolean sameBlock(Label s, Label e){

}

public enum TrapFlags {
BACK_JUMP,
METHOD_CALL,
RECURSIVE_CALL
}

protected final LinkingPolicy linkage;
protected final SandboxContext sandbox;
protected int lineNumber;
protected final List<Label> visited;
protected final List<TryCatch> guardedBlocks;
protected int trap;

public JvmSandboxingVisitor(MethodVisitor delegate, LinkingPolicy linkage){
public JvmSandboxingVisitor(MethodVisitor delegate, SandboxContext sandbox){
super(Opcodes.ASM9, delegate);
this.linkage = linkage;
this.sandbox = sandbox;

visited = new ArrayList<>();
guardedBlocks = new ArrayList<>();
}

@Override
public void visitLineNumber(int lineNumber, Label start){
this.lineNumber = lineNumber;
super.visitLineNumber(lineNumber, start);
}

@Override
public void visitJumpInsn(final int opcode, final Label label){
if(labelVisited(label)){
if(labelVisited(label) && sandbox.getTrapConfig().isEnabled(TrapFlag.BACK_JUMP)){
// Label has already been visited, so this is a backjump
// TODO - insert trap call for backjumps
// TODO - insert trap call
}
super.visitJumpInsn(opcode, label);
}
Expand Down Expand Up @@ -105,6 +104,45 @@ public void visitTryCatchBlock(final Label start, final Label end, Label handler
super.visitTryCatchBlock(start, end, handler, type);
}

@Override
public void visitTypeInsn(final int opcode, final String type){
if(opcode == Opcodes.NEW && sandbox.getTrapConfig().isEnabled(TrapFlag.OBJECT_ALLOC, TrapFlag.PRE_OBJECT_ALLOC)){
// TODO - insert trap call
super.visitLdcInsn(makeTrapSite(TrapSite.Position.PRE));

}else if(opcode == Opcodes.ANEWARRAY && sandbox.getTrapConfig().isEnabled(TrapFlag.ARRAY_ALLOC, TrapFlag.PRE_ARRAY_ALLOC)){
// TODO - insert trap call
}
super.visitTypeInsn(opcode, type);
if(opcode == Opcodes.NEW && sandbox.getTrapConfig().isEnabled(TrapFlag.OBJECT_ALLOC, TrapFlag.POST_OBJECT_ALLOC)){
// TODO - insert trap call
}else if(opcode == Opcodes.ANEWARRAY && sandbox.getTrapConfig().isEnabled(TrapFlag.ARRAY_ALLOC, TrapFlag.POST_ARRAY_ALLOC)){
// TODO - insert trap call
}
}

@Override
public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions){
if(sandbox.getTrapConfig().isEnabled(TrapFlag.ARRAY_ALLOC, TrapFlag.PRE_ARRAY_ALLOC)){
// TODO - insert trap call
}
super.visitMultiANewArrayInsn(descriptor, numDimensions);
if(sandbox.getTrapConfig().isEnabled(TrapFlag.ARRAY_ALLOC, TrapFlag.POST_ARRAY_ALLOC)){
// TODO - insert trap call
}
}

@Override
public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface){
if(sandbox.getTrapConfig().isEnabled(TrapFlag.METHOD_CALL, TrapFlag.PRE_METHOD_CALL)){
// TODO - insert trap call
}
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
if(sandbox.getTrapConfig().isEnabled(TrapFlag.METHOD_CALL, TrapFlag.POST_METHOD_CALL)){
// TODO - insert trap call
}
}

protected boolean labelVisited(Label l){
return visited.stream().anyMatch(label -> label == l);
}
Expand Down Expand Up @@ -137,4 +175,67 @@ protected void insertUncatchableHandler(TryCatch tc){
unmarkGuardedBlock(tc.start(), tc.end());
}

protected void generateBackJumpTrap(TrapSite.Position pos){
super.visitLdcInsn(makeTrapSite(pos));

}

protected ConstantDynamic makeTrapSite(TrapSite.Position pos){

var paramNames = Arrays.stream(Type.getArgumentTypes(sandbox.getMethodDescriptor()))
.map(Type::getClassName)
.toArray(String[]::new);

return new ConstantDynamic("trap$" + (trap++),
Type.getDescriptor(TrapSite.class),
new Handle(
Opcodes.H_INVOKESTATIC,
Type.getInternalName(JvmSandboxingVisitor.class),
"bootstrapTrapsite",
Type.getMethodDescriptor(
Type.getType(TrapSite.Position.class),
Type.getType(String.class),
Type.getType(String.class),
Type.getType(String.class),
Type.getType(String[].class),
Type.INT_TYPE
),
false
),
pos,
sandbox.getClassName(),
sandbox.getMethodName(),
Type.getReturnType(sandbox.getMethodDescriptor()).getClassName(),
paramNames,
lineNumber);
}

protected static TrapSite bootstrapTrapsite(TrapSite.Position pos, String className, String method, String returnType, String[] params, int line) throws ClassNotFoundException {
var signature = new Class<?>[params.length + 1];
signature[0] = classForName(returnType);

for(int i = 1; i < params.length; i++){
signature[i] = classForName(params[i - 1]);
}

return new TrapSite(pos, className, method, signature, line);
}

protected static Class<?> classForName(String name) throws ClassNotFoundException {
// TODO - arrays

return switch (name){
case "void" -> void.class;
case "boolean" -> boolean.class;
case "byte" -> byte.class;
case "char" -> char.class;
case "short" -> short.class;
case "int" -> int.class;
case "long" -> long.class;
case "float" -> float.class;
case "double" -> double.class;
default -> Class.forName(name);
};
}

}
65 changes: 65 additions & 0 deletions Lang/src/main/java/chipmunk/vm/jvm/SandboxContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.vm.jvm;

import chipmunk.vm.invoke.security.LinkingPolicy;

public class SandboxContext {

protected final String className;
protected final String methodName;
protected final String methodDescriptor;
protected final LinkingPolicy policy;
protected final TrapConfig trapConfig;

public SandboxContext(String className, String methodName, String methodDescriptor, LinkingPolicy policy, TrapConfig trapConfig){
this.className = className;
this.methodName = methodName;
this.methodDescriptor = methodDescriptor;
this.policy = policy;
this.trapConfig = trapConfig;
}

public SandboxContext(String className, String methodName, String methodDescriptor, LinkingPolicy policy){
this(className, methodName, methodDescriptor, policy, new TrapConfig());
}

public String getClassName(){
return className;
}

public String getMethodName(){
return methodName;
}

public String getMethodDescriptor(){
return methodDescriptor;
}

public LinkingPolicy getLinkingPolicy(){
return policy;
}

public TrapConfig getTrapConfig(){
return trapConfig;
}

}
47 changes: 47 additions & 0 deletions Lang/src/main/java/chipmunk/vm/jvm/TrapConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2023 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.vm.jvm;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class TrapConfig {

protected final Set<TrapFlag> enabledTraps;

public TrapConfig(){
enabledTraps = new HashSet<>();
}

public void enable(TrapFlag flag){
enabledTraps.add(flag);
}

public boolean isEnabled(TrapFlag... flags){
return Arrays.stream(flags).anyMatch(enabledTraps::contains);
}

public void disable(TrapFlag flag){
enabledTraps.remove(flag);
}

}
34 changes: 34 additions & 0 deletions Lang/src/main/java/chipmunk/vm/jvm/TrapFlag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.vm.jvm;

public enum TrapFlag {
BACK_JUMP,
METHOD_CALL,
PRE_METHOD_CALL,
POST_METHOD_CALL,
ARRAY_ALLOC,
PRE_ARRAY_ALLOC,
POST_ARRAY_ALLOC,
OBJECT_ALLOC,
PRE_OBJECT_ALLOC,
POST_OBJECT_ALLOC
}
29 changes: 29 additions & 0 deletions Lang/src/main/java/chipmunk/vm/jvm/TrapSite.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2023 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.vm.jvm;

public record TrapSite(Position position, String className, String methodName, Class<?>[] signature, int lineNumber) {

public enum Position {
PRE, POST
}

}

0 comments on commit 30875c7

Please sign in to comment.