![JAR search and dependency download from the Maven repository](/logo.png)
edu.columbia.cs.psl.phosphor.instrumenter.TaintAdapter Maven / Gradle / Ivy
The newest version!
package edu.columbia.cs.psl.phosphor.instrumenter;
import edu.columbia.cs.psl.phosphor.Configuration;
import edu.columbia.cs.psl.phosphor.TaintUtils;
import edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter;
import edu.columbia.cs.psl.phosphor.instrumenter.analyzer.TaggedValue;
import edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArray;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LocalVariableNode;
import java.util.ArrayList;
import java.util.List;
public class TaintAdapter extends MethodVisitor implements Opcodes {
protected LocalVariableManager lvs;
protected NeverNullArgAnalyzerAdapter analyzer;
protected String className;
public LocalVariableManager getLvs() {
return lvs;
}
static final Type taintTagType = Type.getType(Configuration.TAINT_TAG_DESC);
public static final Type getTagType(String internalName)
{
if(canRawTaintAccess(internalName))
return taintTagType;
return Type.INT_TYPE;
}
public static final boolean canRawTaintAccess(String internalName)
{
return !Configuration.MULTI_TAINTING || ( !(internalName.equals("java/lang/Float") ||
// internalName.equals("java/lang/Boolean") ||
// internalName.equals("java/lang/Byte") ||
// internalName.equals("java/lang/Short") ||
internalName.equals("java/lang/Character") ||
internalName.equals("java/lang/Double") ||internalName.equals("java/lang/Integer") ||
internalName.equals("java/lang/Long") || internalName.equals("java/lang/StackTraceElement")));
}
private TaintAdapter(MethodVisitor mv)
{
super(Configuration.ASM_VERSION,mv);
}
private TaintAdapter(int api, MethodVisitor mv)
{
super(api, mv);
}
public TaintAdapter(int access, String className, String name, String desc, String signature, String[] exceptions, MethodVisitor mv, NeverNullArgAnalyzerAdapter analyzer) {
super(Configuration.ASM_VERSION, mv);
this.analyzer = analyzer;
this.className = className;
}
public List fields;
public void setFields(List fields) {
this.fields = fields;
}
protected String classSource;
protected String classDebug;
protected String superName;
public void setSuperName(String parentName) {
this.superName = parentName;
}
public TaintAdapter(int access, String className, String name, String desc, String signature, String[] exceptions, MethodVisitor mv, NeverNullArgAnalyzerAdapter analyzer, String classSource, String classDebug) {
super(Configuration.ASM_VERSION, mv);
this.analyzer = analyzer;
this.className = className;
this.classSource = classSource;
this.classDebug = classDebug;
}
void ensureUnBoxedAt(int n, Type t) {
switch (n) {
case 0:
super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
super.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
break;
case 1:
Object top = analyzer.stack.get(analyzer.stack.size() - 1);
if (top == Opcodes.LONG || top == Opcodes.DOUBLE || top == Opcodes.TOP) {
super.visitInsn(DUP2_X1);
super.visitInsn(POP2);
super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
super.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
super.visitInsn(DUP_X2);
super.visitInsn(POP);
} else {
super.visitInsn(SWAP);
super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
super.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
super.visitInsn(SWAP);
}
break;
default:
LocalVariableNode[] d = storeToLocals(n);
super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
super.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
for (int i = n - 1; i >= 0; i--) {
loadLV(i, d);
}
freeLVs(d);
}
}
public boolean topHas0Taint() {
if (getTopOfStackObject() == Opcodes.TOP)
return Integer.valueOf(0).equals(analyzer.stackConstantVals.get(analyzer.stackConstantVals.size() - 3));
else
return Integer.valueOf(0).equals(analyzer.stackConstantVals.get(analyzer.stackConstantVals.size() - 2));
}
public boolean secondHas0Taint() {
int offset = 2;
if (getTopOfStackObject() == Opcodes.TOP)
offset++;
if (getStackElementSize(offset) == Opcodes.TOP)
offset++;
offset++;
return Integer.valueOf(0).equals(analyzer.stackConstantVals.get(analyzer.stackConstantVals.size() - offset));
}
protected void getTaintFieldOfBoxedType(String owner)
{
super.visitFieldInsn(GETFIELD, owner, "taint", Configuration.TAINT_TAG_DESC);
}
public void setLocalVariableSorter(LocalVariableManager lvs) {
this.lvs = lvs;
}
public boolean topOfStackIsNull() {
return stackElIsNull(0);
}
public Type getTopOfStackType() {
if(analyzer.stack == null)
throw new NullPointerException();
if(analyzer.stack.get(analyzer.stack.size() - 1) == Opcodes.TOP)
return getStackTypeAtOffset(1);
return getStackTypeAtOffset(0);
}
public Object getTopOfStackObject() {
return analyzer.stack.get(analyzer.stack.size() - 1);
}
/**
* Returns the type of the stack element n down from the top: n=0 -> top of
* stack
*
* @param n
* @return
*/
public Type getStackTypeAtOffset(int n) {
return getTypeForStackType(analyzer.stack.get(analyzer.stack.size() - 1 - n));
}
public boolean stackElIsNull(int n) {
return analyzer.stack.get(analyzer.stack.size() - 1 - n) == Opcodes.NULL;
}
public NeverNullArgAnalyzerAdapter getAnalyzer() {
return analyzer;
}
public void retrieveTopOfStackTaintArray() {
Type onStack = getTopOfStackType();
generateEmptyTaintArray(onStack.getDescriptor());
}
public void unconditionallyRetrieveTopOfStackTaintArray(boolean leaveOnStack) {
if (leaveOnStack)
super.visitInsn(DUP);
super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(TaintUtils.class), "getTaintArray", "(Ljava/lang/Object;)I",false);
}
public boolean topCarriesTaint()
{
Object t = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
if(t == Opcodes.TOP)
t = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
return t instanceof TaggedValue;
}
@Deprecated
public boolean topStackElCarriesTaints() {
Object o = analyzer.stack.get(analyzer.stack.size() - 1);
return isPrimitiveStackType(o);
}
public boolean topStackElIsNull() {
Object o = analyzer.stack.get(analyzer.stack.size() - 1);
return o == Opcodes.NULL;
}
/**
* Retrieve the taint of the object at the top of the stack (popping that
* object) Assumes that the top of the stack is an object (may or may not be
* null)
*/
protected void safelyFetchObjectTaint() {
//Check for null first.
// Check for common instanceof which are problematic
// nonInstrumentingMV.visitInsn(DUP);
// Label bail = new Label();
// Label end = new Label();
// nonInstrumentingMV.visitJumpInsn(IFNULL, bail);
// //Not null.
// nonInstrumentingMV.visitInsn(DUP);
// nonInstrumentingMV.visitTypeInsn(INSTANCEOF, Type.getInternalName(Tainted.class));
// nonInstrumentingMV.visitJumpInsn(IFNE, bail); //TODO handle numerics, other ignore classes for which we know the taint
if (className.equals("java/util/HashMap")) {
super.visitInsn(POP);
Configuration.taintTagFactory.generateEmptyTaint(mv);
} else
super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(TaintUtils.class), "getTaint", "(Ljava/lang/Object;)I",false);
// nonInstrumentingMV.visitLabel(bail);
// super.visitInsn(POP);
// super.visitInsn(ICONST_0);
// nonInstrumentingMV.visitLabel(end);
}
// protected void retrievePrimitiveArrayTaint(boolean leaveTAOnStack) {
//// System.out.println("Finding taint on " + getTopOfStackObject());
// //A TA
// super.visitInsn(SWAP);//TA A
// Label bailTo = new Label();
// Label end = new Label();
// nonInstrumentingMV.visitInsn(DUP);
// nonInstrumentingMV.visitJumpInsn(IFNULL, bailTo);
// super.visitInsn(DUP); //TA TA A
// if (leaveTAOnStack)
// super.visitInsn(DUP);
// super.visitInsn(ARRAYLENGTH);
//
// //Idx TA A
// super.visitInsn(IALOAD);//T A
// if (leaveTAOnStack) {
// super.visitInsn(DUP_X2);//T TA A T
// super.visitInsn(POP); //TA A T
// super.visitInsn(SWAP); //A TA T
// super.visitInsn(DUP2_X1);//A TA T A TA
// super.visitInsn(POP2);
// }
// nonInstrumentingMV.visitJumpInsn(GOTO, end);
// nonInstrumentingMV.visitLabel(bailTo);
// if (leaveTAOnStack)
// nonInstrumentingMV.visitInsn(SWAP);
// else
// nonInstrumentingMV.visitInsn(POP);
// nonInstrumentingMV.visitInsn(ICONST_0);
// nonInstrumentingMV.visitLabel(end);
// }
// protected void retrievePrimitiveArrayTaintFromTopArray(boolean leaveTAOnStack) {
// Label bailTo = new Label();
// Label end = new Label();
// nonInstrumentingMV.visitInsn(DUP);
// nonInstrumentingMV.visitJumpInsn(IFNULL, bailTo);
// super.visitInsn(DUP); //TA TA
// if (leaveTAOnStack)
// super.visitInsn(DUP); //TA TA TA
// super.visitInsn(ARRAYLENGTH);
// super.visitInsn(ICONST_M1);
// super.visitInsn(IADD);
// //Idx TA A
// super.visitInsn(IALOAD);//T TA
// nonInstrumentingMV.visitJumpInsn(GOTO, end);
// nonInstrumentingMV.visitLabel(bailTo);
// if (!leaveTAOnStack)
// nonInstrumentingMV.visitInsn(POP);
// nonInstrumentingMV.visitInsn(ICONST_0);
// nonInstrumentingMV.visitLabel(end);
// }
// protected void retrieveTopOfStackTaint() {
// retrieveTopOfStackTaint(false, true);
// }
// protected void retrieveTopOfStackTaint(boolean leavePrimitiveArrayOnStack, boolean onlyRemoveTaintArrays) {
//// System.out.println("getting taint for " + getTopOfStackObject() + " _ " + getTopOfStackType().getInternalName() + (leavePrimitiveArrayOnStack ? "T":"F") + (onlyRemoveTaintArrays ? "T" :"F"));
//
// if (getTopOfStackType().getInternalName().equals("java/lang/Object")) {
// if(leavePrimitiveArrayOnStack)
// super.visitInsn(DUP);
// safelyFetchObjectTaint();
// // System.out.println(analyzer.stack);
// } else if (Instrumenter.isIgnoredClass(getTopOfStackType().getInternalName())) {
// if (!leavePrimitiveArrayOnStack)
// super.visitInsn(POP);
// super.visitInsn(ICONST_0);//TODO make a sentinel to make this unique
// } else if (getTopOfStackType().getSort() == Type.ARRAY) {
//
// if (onlyRemoveTaintArrays && getTopOfStackType().getElementType().getSort() != Type.OBJECT && getTopOfStackType().getDimensions() > 1) {
// super.visitInsn(SWAP);
// super.visitInsn(POP);
// }
// if (getTopOfStackType().getElementType().getSort() != Type.OBJECT && getTopOfStackType().getDimensions() == 1) {
// if(onlyRemoveTaintArrays)
// {
// super.visitInsn(SWAP);
// super.visitInsn(POP);
// unconditionallyRetrieveTopOfStackTaintArray(leavePrimitiveArrayOnStack);
// }
//// retrievePrimitiveArrayTaint(!onlyRemoveTaintArrays);
// } else {
// unconditionallyRetrieveTopOfStackTaintArray(leavePrimitiveArrayOnStack);
// }
//
// } else {
// // System.out.println(getTopOfStackType());
// // System.out.println("top of stack is " + getTopOfStackType() + nonInstrumentingMV);
// // System.out.println(analyzer.stack);
// Label isNull = new Label();
// Label continu = new Label();
// nonInstrumentingMV.visitInsn(DUP);
// if(leavePrimitiveArrayOnStack)
// super.visitInsn(DUP);
// nonInstrumentingMV.visitJumpInsn(IFNULL, isNull);
// if (Instrumenter.isInterface(getTopOfStackType().getInternalName()))
// super.visitMethodInsn(Opcodes.INVOKEINTERFACE, getTopOfStackType().getInternalName(), "get" + TaintUtils.TAINT_FIELD, "()I",true);
// else
// super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getTopOfStackType().getInternalName(), "get" + TaintUtils.TAINT_FIELD, "()I",false);
// nonInstrumentingMV.visitJumpInsn(GOTO, continu);
// nonInstrumentingMV.visitLabel(isNull);
// nonInstrumentingMV.visitInsn(POP);
// nonInstrumentingMV.visitInsn(ICONST_0);
// nonInstrumentingMV.visitJumpInsn(GOTO, continu);
// nonInstrumentingMV.visitLabel(continu);
// // System.out.println(analyzer.stack);
// }
// }
// protected void retrieveTopOfStackTaintAndPop() {
// if (getTopOfStackType().getInternalName().equals("java/lang/Object")) {
// safelyFetchObjectTaint();
// // System.out.println(analyzer.stack);
// } else if (Instrumenter.isIgnoredClass(getTopOfStackType().getInternalName())) {
// super.visitInsn(POP);
// super.visitInsn(ICONST_0);//TODO make a sentinel to make this unique
// } else if (getTopOfStackType().getSort() == Type.ARRAY) {
//
// if (getTopOfStackType().getElementType().getSort() != Type.OBJECT && getTopOfStackType().getDimensions() > 1) {
// super.visitInsn(SWAP);
// super.visitInsn(POP);
// }
// // super.visitInsn(ICONST_0);//TODO
// // System.out.println(getTopOfStackType());
// if (getTopOfStackType().getElementType().getSort() != Type.OBJECT && getTopOfStackType().getDimensions() == 1) {
//// retrievePrimitiveArrayTaint(false);
// super.visitInsn(SWAP);
// super.visitInsn(POP);
// unconditionallyRetrieveTopOfStackTaintArray(false);
// // super.visitInsn(POP);
// // super.visitInsn(ICONST_0);
//
// } else {
// unconditionallyRetrieveTopOfStackTaintArray(false);
// }
//
// } else {
// // System.out.println(getTopOfStackType());
// // System.out.println("top of stack is " + getTopOfStackType() + nonInstrumentingMV);
// // System.out.println(analyzer.stack);
// Label isNull = new Label();
// Label continu = new Label();
// nonInstrumentingMV.visitInsn(DUP);
// nonInstrumentingMV.visitJumpInsn(IFNULL, isNull);
// if (Instrumenter.isInterface(getTopOfStackType().getInternalName()))
// super.visitMethodInsn(Opcodes.INVOKEINTERFACE, getTopOfStackType().getInternalName(), "get" + TaintUtils.TAINT_FIELD, "()I",true);
// else
// super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getTopOfStackType().getInternalName(), "get" + TaintUtils.TAINT_FIELD, "()I",false);
// nonInstrumentingMV.visitJumpInsn(GOTO, continu);
// nonInstrumentingMV.visitLabel(isNull);
// nonInstrumentingMV.visitInsn(POP);
// nonInstrumentingMV.visitInsn(ICONST_0);
// nonInstrumentingMV.visitJumpInsn(GOTO, continu);
// nonInstrumentingMV.visitLabel(continu);
// // System.out.println(analyzer.stack);
// }
// }
protected void generateUnconstrainedTaint(int reason) {
Configuration.taintTagFactory.generateEmptyTaint(mv);
}
/**
* Precondition: top stack element is an array Postconditoins: top stack
* element is the same array, second stack element is an int array of the
* same length.
*/
protected void generateEmptyTaintArray(String arrayDesc) {
Type arrayType = Type.getType(arrayDesc);
Label isNull = new Label();
Label done = new Label();
if (arrayType.getDimensions() == 2) {
FrameNode fn = getCurrentFrameNode();
super.visitInsn(DUP);
super.visitInsn(TaintUtils.IGNORE_EVERYTHING);
super.visitJumpInsn(IFNULL, isNull);
super.visitInsn(TaintUtils.IGNORE_EVERYTHING);
super.visitInsn(DUP);
super.visitInsn(DUP);
super.visitInsn(ARRAYLENGTH);
super.visitMultiANewArrayInsn("[[I", 1);
super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(TaintUtils.class), "create2DTaintArray", "(Ljava/lang/Object;[[I)[[I",false);
if(!(Configuration.taintTagFactory instanceof DataAndControlFlowTagFactory))
{
super.visitInsn(DUP);
super.visitInsn(ICONST_2);
super.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(TaintTagFactory.class), "generateEmptyTaintArray", "([Ljava/lang/Object;I)V", false);
}
super.visitInsn(SWAP);
FrameNode fn2 = getCurrentFrameNode();
super.visitJumpInsn(GOTO, done);
super.visitLabel(isNull);
acceptFn(fn);
super.visitInsn(ACONST_NULL);
super.visitInsn(SWAP);
super.visitLabel(done);
acceptFn(fn2);
} else if (arrayType.getDimensions() == 3) {
FrameNode fn = getCurrentFrameNode();
super.visitInsn(DUP);
super.visitInsn(TaintUtils.IGNORE_EVERYTHING);
super.visitJumpInsn(IFNULL, isNull);
super.visitInsn(TaintUtils.IGNORE_EVERYTHING);
super.visitInsn(DUP);
super.visitInsn(DUP);
super.visitInsn(ARRAYLENGTH);
super.visitMultiANewArrayInsn("[[[I", 1);
super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(TaintUtils.class), "create3DTaintArray", "(Ljava/lang/Object;[[[I)[[[I",false);
if(!(Configuration.taintTagFactory instanceof DataAndControlFlowTagFactory))
{
super.visitInsn(DUP);
super.visitInsn(ICONST_3);
super.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(TaintTagFactory.class), "generateEmptyTaintArray", "([Ljava/lang/Object;I)V", false);
}
super.visitInsn(SWAP);
FrameNode fn2 = getCurrentFrameNode();
super.visitJumpInsn(GOTO, done);
super.visitLabel(isNull);
acceptFn(fn);
super.visitInsn(ACONST_NULL);
super.visitInsn(SWAP);
super.visitLabel(done);
acceptFn(fn2);
} else if (arrayType.getDimensions() == 1) {
FrameNode fn = getCurrentFrameNode();
super.visitInsn(DUP);
super.visitInsn(TaintUtils.IGNORE_EVERYTHING);
super.visitJumpInsn(IFNULL, isNull);
super.visitInsn(TaintUtils.IGNORE_EVERYTHING);
Type wrapType = MultiDTaintedArray.getTypeForType(arrayType);
super.visitInsn(DUP);
super.visitTypeInsn(NEW, wrapType.getInternalName());
super.visitInsn(DUP_X1);
super.visitInsn(SWAP);
super.visitMethodInsn(INVOKESPECIAL, wrapType.getInternalName(), "", "("+arrayType.getDescriptor()+")V", false);
// super.visitInsn(SWAP);
super.visitInsn(SWAP);
FrameNode fn2 = getCurrentFrameNode();
super.visitJumpInsn(GOTO, done);
super.visitLabel(isNull);
acceptFn(fn);
super.visitInsn(ACONST_NULL);
super.visitInsn(SWAP);
super.visitLabel(done);
acceptFn(fn2);
} else {
throw new IllegalStateException("Can't handle casts to multi-d array type of dimension " + arrayType.getDimensions());
}
}
public static Object[] removeLongsDoubleTopVal(List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy