Skip to content

Commit

Permalink
fix sec man bug and provide additional security
Browse files Browse the repository at this point in the history
  • Loading branch information
GraxCode committed May 9, 2020
1 parent 6a0b02e commit 2733c4d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
52 changes: 52 additions & 0 deletions src/me/nov/threadtear/security/VMExtraSecurity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.nov.threadtear.security;

import java.net.URL;

import org.apache.commons.io.IOUtils;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;

import me.nov.threadtear.Threadtear;
import me.nov.threadtear.io.Conversion;

public class VMExtraSecurity implements Opcodes {
public static InsnList rewriteSetAccessible0(String blockRegex) {
InsnList il = new InsnList();
LabelNode jump = new LabelNode();
il.add(new VarInsnNode(ALOAD, 0));
il.add(new TypeInsnNode(INSTANCEOF, "java/lang/reflect/Member"));
il.add(new JumpInsnNode(IFEQ, jump));
il.add(new VarInsnNode(ALOAD, 0));
il.add(new TypeInsnNode(CHECKCAST, "java/lang/reflect/Member"));
il.add(new MethodInsnNode(INVOKEINTERFACE, "java/lang/reflect/Member", "getName", "()Ljava/lang/String;"));
il.add(new LdcInsnNode(blockRegex));
il.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "matches", "(Ljava/lang/String;)Z"));
il.add(new JumpInsnNode(IFEQ, jump));
il.add(new InsnNode(RETURN));
il.add(jump);
il.add(new FrameNode(F_NEW, 2, new Object[] { "java/lang/reflect/AccessibleObject", INTEGER }, 0, null));
il.add(new VarInsnNode(ALOAD, 0));
il.add(new VarInsnNode(ILOAD, 1));
il.add(new FieldInsnNode(PUTFIELD, "java/lang/reflect/AccessibleObject", "override", "Z"));
il.add(new InsnNode(RETURN));
return il;
}

public static ClassNode rewriteAccessibleObject() {
String classFile = "/java/lang/reflect/AccessibleObject.class";
URL url = VMExtraSecurity.class.getResource(classFile);
try {
ClassNode loadedNode = Conversion.toNode(IOUtils.toByteArray(url));
MethodNode setAccessible0 = loadedNode.methods.stream().filter(m -> m.name.equals("setAccessible0")).findFirst().get();
setAccessible0.instructions = rewriteSetAccessible0("(me\\.nov|java\\.lang|sun\\.).*");
setAccessible0.maxStack = 2;
setAccessible0.maxLocals = 2;
setAccessible0.tryCatchBlocks = null;
setAccessible0.localVariables = null;
return loadedNode;
} catch (Exception e) {
Threadtear.logger.error("Couldn't rewrite AccessibleObject, {}", e.toString());
return null;
}
}
}
4 changes: 2 additions & 2 deletions src/me/nov/threadtear/security/VMSecurityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public class VMSecurityManager extends SecurityManager {
private static boolean grantAll;
private static boolean checkReflection;
private static boolean checkReflection = true;

@Override
public void checkPermission(Permission perm) {
Expand Down Expand Up @@ -106,7 +106,7 @@ private boolean checkReflection(String pkg) {

public static void allowReflection(boolean allow) {
if (grantAccess())
checkReflection = allow;
checkReflection = !allow;
}

private final void throwIfNotGranted() {
Expand Down
14 changes: 12 additions & 2 deletions src/me/nov/threadtear/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import me.nov.threadtear.Threadtear;
import me.nov.threadtear.io.Conversion;
import me.nov.threadtear.security.VMExtraSecurity;
import me.nov.threadtear.util.asm.*;

public class VM extends ClassLoader implements Opcodes {
Expand Down Expand Up @@ -55,11 +56,20 @@ private boolean isForbiddenName(String name) {

@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.contains("/"))
throw new IllegalArgumentException();
if (name.matches(RT)) {
if (name.equals("java.lang.reflect.AccessibleObject")) {
if (loaded.containsKey(name)) {
return loaded.get(name);
}
Class<?> acc = bytesToClass(name, Conversion.toBytecode0(VMExtraSecurity.rewriteAccessibleObject()));
Threadtear.logger.warning("Redefined java.lang.reflect.AccessibleObject for more security, a class called setAccessible(true).");
loaded.put(name, acc);
return acc;
}
return super.loadClass(name, resolve);
}
if (name.contains("/"))
throw new IllegalArgumentException();
if (loaded.containsKey(name)) {
return loaded.get(name);
}
Expand Down

0 comments on commit 2733c4d

Please sign in to comment.