public Stream createStream(Location location, ObjectType type, ConstantPoolGen cpg, RepositoryLookupFailureCallback lookupFailureCallback) { Instruction ins = location.getHandle().getInstruction(); try { if (ins instanceof InvokeInstruction) { if (!Hierarchy.isSubtype(type, baseClassType)) return null; Stream stream = new Stream(location, type.getClassName(), baseClassType.getClassName()) .setIsOpenOnCreation(true) .setIgnoreImplicitExceptions(true); if (bugType != null) stream.setInteresting(bugType); return stream; } } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); } return null; }
protected boolean instanceEscapes(InvokeInstruction inv, int instanceArgNum) { //ConstantPoolGen cpg = getCPG(); // String className = inv.getClassName(cpg); //System.out.print("[Passed as arg="+instanceArgNum+" at " + inv + "]"); boolean escapes = (inv.getOpcode() == Constants.INVOKESTATIC || instanceArgNum != 0); //if (escapes) System.out.print("[Escape at " + inv + " argNum=" + instanceArgNum + "]"); if (FindOpenStream.DEBUG && escapes) System.out.println("ESCAPE at " + location); // Record the fact that this might be a stream escape if (stream.getOpenLocation() != null) resourceTracker.addStreamEscape(stream, location); return escapes; }
private Set<MethodAndSink> getSinks(ConstantPoolGen cpg, InvokeInstruction invoke, TaintFrame frame) { String className = getInstanceClassName(cpg, invoke, frame); String methodName = "." + invoke.getMethodName(cpg) + invoke.getSignature(cpg); String fullMethodName = className.concat(methodName); Set<InjectionSink> sinks = injectionSinks.get(fullMethodName); if (sinks != null) { assert !sinks.isEmpty() : "empty set of sinks"; return getMethodAndSinks(fullMethodName, sinks); } try { if (className.endsWith("]")) { // not a real class return Collections.emptySet(); } JavaClass javaClass = Repository.lookupClass(className); assert javaClass != null; return getSuperSinks(javaClass, methodName); } catch (ClassNotFoundException ex) { AnalysisContext.reportMissingClass(ex); } return Collections.emptySet(); }
private static String getInstanceClassName(ConstantPoolGen cpg, InvokeInstruction invoke, TaintFrame frame) { try { int instanceIndex = frame.getNumArgumentsIncludingObjectInstance(invoke, cpg) - 1; if (instanceIndex != -1) { assert instanceIndex < frame.getStackDepth(); Taint instanceTaint = frame.getStackValue(instanceIndex); String className = instanceTaint.getRealInstanceClassName(); if (className != null) { return className; } } } catch (DataflowAnalysisException ex) { assert false : ex.getMessage(); } String dottedClassName = invoke.getReferenceType(cpg).toString(); return ClassName.toSlashedClassName(dottedClassName); }
private String getInstanceClassName(InvokeInstruction invoke) { try { int instanceIndex = getFrame().getNumArgumentsIncludingObjectInstance(invoke, cpg) - 1; if (instanceIndex != -1) { assert instanceIndex < getFrame().getStackDepth(); Taint instanceTaint = getFrame().getStackValue(instanceIndex); String className = instanceTaint.getRealInstanceClassName(); if (className != null) { return className; } } } catch (DataflowAnalysisException ex) { assert false : ex.getMessage(); } String dottedClassName = invoke.getReferenceType(cpg).toString(); return ClassName.toSlashedClassName(dottedClassName); }
private void taintMutableArguments(TaintMethodConfig methodConfig, InvokeInstruction obj) { if (methodConfig != null && methodConfig.isConfigured()) { return; } Collection<Integer> mutableStackIndices = getMutableStackIndices(obj.getSignature(cpg)); for (Integer index : mutableStackIndices) { assert index >= 0 && index < getFrame().getStackDepth(); try { Taint stackValue = getFrame().getStackValue(index); Taint taint = Taint.merge(stackValue, getDefaultValue()); if (stackValue.hasValidVariableIndex()) { // set back the index removed during merging taint.setVariableIndex(stackValue.getVariableIndex()); } taint.setRealInstanceClass(stackValue.getRealInstanceClass()); taint.addLocation(getTaintLocation(), false); getFrame().setValue(getFrame().getStackLocation(index), taint); setLocalVariableTaint(taint, taint); } catch (DataflowAnalysisException ex) { throw new InvalidBytecodeException("Not enough values on the stack", ex); } } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); if(sig.startsWith("(Ljava/lang/String;)")) { if(method.startsWith("set")) { // Targeting : x.setPassword("abc123") String methodLowerCase = method.toLowerCase(); for (String password : PASSWORD_WORDS) { if (methodLowerCase.contains(password)) { return new InjectionPoint(new int[]{0}, HARD_CODE_PASSWORD_TYPE); } } } else if(PASSWORD_WORDS.contains(method.toLowerCase())) { // Targeting : DSL().user("").password(String x) return new InjectionPoint(new int[]{0}, HARD_CODE_PASSWORD_TYPE); } } return InjectionPoint.NONE; }
/** * Check if the readObject is doing multiple external call beyond the basic readByte, readBoolean, etc.. * @param m * @param classContext * @return * @throws CFGBuilderException * @throws DataflowAnalysisException */ private boolean hasCustomReadObject(Method m, ClassContext classContext,List<String> classesToIgnore) throws CFGBuilderException, DataflowAnalysisException { ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); int count = 0; for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); //ByteCode.printOpCode(inst,cpg); if(inst instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) inst; if (!READ_DESERIALIZATION_METHODS.contains(invoke.getMethodName(cpg)) && !classesToIgnore.contains(invoke.getClassName(cpg))) { count +=1; } } } return count > 3; }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException { MethodGen methodGen = classContext.getMethodGen(m); ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); if (methodGen == null || methodGen.getInstructionList() == null) { return; //No instruction .. nothing to do } for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); if (inst instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) inst; String methodName = invoke.getMethodName(cpg); if ("enableDefaultTyping".equals(methodName)) { JavaClass clz = classContext.getJavaClass(); bugReporter.reportBug(new BugInstance(this, DESERIALIZATION_TYPE, HIGH_PRIORITY) .addClass(clz) .addMethod(clz, m) .addCalledMethod(cpg, invoke) .addSourceLine(classContext, m, location) ); } } } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); if(method.equals("registerReceiver")){ if(sig.contains("Ljava/lang/String;")){ if(sig.contains(";I)")){ return new InjectionPoint(new int[]{2}, ANDROID_REGISTER_RECEIVER_TYPE); }else{ return new InjectionPoint(new int[]{1}, ANDROID_REGISTER_RECEIVER_TYPE); } } } return InjectionPoint.NONE; }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); // System.out.println(invoke.getClassName(cpg)); if(sig.contains("Ljava/lang/String;")) { if("loadUrl".equals(method)){ if(sig.contains("Ljava/util/Map;")){ return new InjectionPoint(new int[]{1}, WEBVIEW_LOAD_DATA_URL_TYPE); }else{ return new InjectionPoint(new int[]{0}, WEBVIEW_LOAD_DATA_URL_TYPE); } }else if("loadData".equals(method)){ return new InjectionPoint(new int[]{2}, WEBVIEW_LOAD_DATA_URL_TYPE); }else if("loadDataWithBaseURL".equals(method)){ //BUG return new InjectionPoint(new int[]{4}, WEBVIEW_LOAD_DATA_URL_TYPE); } } return InjectionPoint.NONE; }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); // System.out.println(sig); if(sig.contains("Ljava/lang/String;")) { if(method.contains("send") && method.contains("Broadcast") && !method.contains("Sticky")){ // System.out.println(method); if("sendOrderedBroadcastAsUser".equals(method)){ return new InjectionPoint(new int[]{5}, ANDROID_BROADCAST_TYPE); } if("sendOrderedBroadcast".equals(method) && sig.contains("Landroid/content/BroadcastReceiver;")){ return new InjectionPoint(new int[]{5}, ANDROID_BROADCAST_TYPE); } return new InjectionPoint(new int[]{0}, ANDROID_BROADCAST_TYPE); } } return InjectionPoint.NONE; }
public boolean matches(Instruction instruction, ConstantPoolGen cpg) { if(instruction != null && instruction instanceof InvokeInstruction) { InvokeInstruction invokeInstruction = (InvokeInstruction) instruction; if (classesNames.size() != 0 && !classesNames.contains(invokeInstruction.getClassName(cpg))) { return false; } else if (methodNames.size() != 0 && !methodNames.contains(invokeInstruction.getMethodName(cpg))) { return false; } else if (argSignatures.size() != 0 && !argSignatures.contains(invokeInstruction.getSignature(cpg))) { return false; } return true; } return false; }
@Override public void onInstruction(Instruction i) { //if (shouldVisit(i)) { if (i instanceof FieldInstruction) { registerCoupling(((FieldInstruction) i).getFieldType(constants())); } else if (i instanceof InvokeInstruction) { final InvokeInstruction ii = (InvokeInstruction) i; registerCoupling(ii.getReferenceType(constants())); Stream.of(ii.getArgumentTypes(constants())).forEach(a -> registerCoupling(a)); registerCoupling(ii.getReturnType(constants())); } /* else if (i instanceof TypedInstruction) { final Type ti = ((TypedInstruction) i).getType(constants()); if (!ti.getSignature().equals("<null object>")) { registerCoupling(ti); } }*/ //} }
private static Map<InstructionHandle, Call> buildCallMap(CFG cfg, ConstantPoolGen cpg) { Map<InstructionHandle, Call> callMap = new HashMap<InstructionHandle, Call>(); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { InstructionHandle handle = i.next().getHandle(); Instruction ins = handle.getInstruction(); if (ins instanceof InvokeInstruction) { InvokeInstruction inv = (InvokeInstruction) ins; Call call = new Call(inv.getClassName(cpg), inv.getName(cpg), inv.getSignature(cpg)); callMap.put(handle, call); } } return callMap; }
private static boolean apply_permfilter(Instruction instr, PermissionFilter pf, ConstantPoolGen cpgen) { boolean ret = false; if (instr instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) instr; String isig = get_invoke_sig(invoke, cpgen); // Util.log(isig); for (String perm : pf.filters) { boolean used = PermissionMap.checkPermUse(isig, perm); if (used) { Util.log("Matched: " + isig + " <==> " + perm); ret = true; break; } } } return ret; }
private void killLoadsOfObjectsPassed(InvokeInstruction ins) { try { XMethod called = Hierarchy2.findExactMethod(ins, methodGen.getConstantPool(), Hierarchy.ANY_METHOD); FieldSummary fieldSummary = AnalysisContext.currentAnalysisContext().getFieldSummary(); Set<XField> touched = fieldSummary.getFieldsWritten(called); if (!touched.isEmpty()) { getFrame().killLoadsOf(touched); } int passed = getNumWordsConsumed(ins); ValueNumber[] arguments = allocateValueNumberArray(passed); getFrame().killLoadsWithSimilarName(ins.getClassName(cpg), ins.getMethodName(cpg)); getFrame().getTopStackWords(arguments); for (ValueNumber v : arguments) getFrame().killAllLoadsOf(v); } catch (DataflowAnalysisException e) { AnalysisContext.logError("Error in killLoadsOfObjectsPassed", e); } }
@CheckForNull Use getUse(ConstantPoolGen cpg, Instruction ins) { if (ins instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) ins; String mName = invoke.getMethodName(cpg); String cName = invoke.getClassName(cpg); if (mName.equals("setAttribute") && cName.equals("javax.servlet.http.HttpSession")) return Use.STORE_INTO_HTTP_SESSION; if (mName.equals("writeObject") && (cName.equals("java.io.ObjectOutput") || cName.equals("java.io.ObjectOutputStream"))) return Use.PASSED_TO_WRITE_OBJECT; } return null; }
private boolean isSafeValue(Location location, ConstantPoolGen cpg) throws CFGBuilderException { Instruction prevIns = location.getHandle().getInstruction(); if (prevIns instanceof LDC || prevIns instanceof GETSTATIC) return true; if (prevIns instanceof InvokeInstruction) { String methodName = ((InvokeInstruction) prevIns).getMethodName(cpg); if (methodName.startsWith("to") && methodName.endsWith("String") && methodName.length() > 8) return true; } if (prevIns instanceof AALOAD) { CFG cfg = classContext.getCFG(method); Location prev = getPreviousLocation(cfg, location, true); if (prev != null) { Location prev2 = getPreviousLocation(cfg, prev, true); if (prev2 != null && prev2.getHandle().getInstruction() instanceof GETSTATIC) { GETSTATIC getStatic = (GETSTATIC) prev2.getHandle().getInstruction(); if (getStatic.getSignature(cpg).equals("[Ljava/lang/String;")) return true; } } } return false; }
public boolean mightCloseResource(BasicBlock basicBlock, InstructionHandle handle, ConstantPoolGen cpg) throws DataflowAnalysisException { InvokeInstruction inv = toInvokeInstruction(handle.getInstruction()); if (inv == null) return false; String className = inv.getClassName(cpg); String methodName = inv.getName(cpg); String methodSig = inv.getSignature(cpg); try { if (methodName.equals("unlock") && methodSig.equals("()V") && Hierarchy.isSubtype(className, "java.util.concurrent.locks.Lock")) { return true; } } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); } return false; }
private void handleInstanceMethod(InvokeInstruction obj) { assert returnsString(obj); consumeStack(obj); String className = obj.getClassName(getCPG()); String methodName = obj.getName(getCPG()); // System.out.println(className + "." + methodName); if (methodName.equals("intern") && className.equals("java.lang.String")) { sawStringIntern = true; pushValue(staticStringTypeInstance); } else if (methodName.equals("toString") || className.equals("java.lang.String")) { pushValue(dynamicStringTypeInstance); // System.out.println(" dynamic"); } else { pushReturnType(obj); } }
/** * Find the declared exceptions for the method called by given instruction. * * @param inv * the InvokeInstruction * @param cpg * the ConstantPoolGen used by the class the InvokeInstruction * belongs to * @return array of ObjectTypes of thrown exceptions, or null if we can't * find the method implementation */ public static @CheckForNull ObjectType[] findDeclaredExceptions(InvokeInstruction inv, ConstantPoolGen cpg) { XMethod method = findInvocationLeastUpperBound(inv, cpg, inv instanceof INVOKESTATIC ? Hierarchy.STATIC_METHOD : Hierarchy.INSTANCE_METHOD); if (method == null) return null; String[] exceptions = method.getThrownExceptions(); if (exceptions == null) return new ObjectType[0]; ObjectType[] result = new ObjectType[exceptions.length]; for (int i = 0; i < exceptions.length; ++i) { result[i] = ObjectTypeFactory.getInstance(ClassName.toDottedClassName(exceptions[i])); } return result; }
private void registerInstructionSinks() throws DataflowAnalysisException { TypeQualifierAnnotation returnValueAnnotation = null; if (!xmethod.getSignature().endsWith(")V")) { returnValueAnnotation = TypeQualifierApplications.getEffectiveTypeQualifierAnnotation(xmethod, typeQualifierValue); } for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction ins = location.getHandle().getInstruction(); if (ins instanceof ReturnInstruction && !(ins instanceof RETURN)) { // Return instruction which returns a value modelReturn(returnValueAnnotation, location); } else { short opcode = ins.getOpcode(); if (opcode == Constants.PUTFIELD || opcode == Constants.PUTSTATIC) { modelFieldStore(location); } else if (location.getHandle().getInstruction() instanceof InvokeInstruction) { modelArguments(location); } } } }
private void handleInvoke(InvokeInstruction inv) { ResourceValueFrame frame = getFrame(); int numSlots = frame.getNumSlots(); int numConsumed = getNumWordsConsumed(inv); // See if the resource instance is passed as an argument int instanceArgNum = -1; for (int i = numSlots - numConsumed, argCount = 0; i < numSlots; ++i, ++argCount) { ResourceValue value = frame.getValue(i); if (value.equals(ResourceValue.instance())) { instanceArgNum = argCount; break; } } if (instanceArgNum >= 0 && instanceEscapes(inv, instanceArgNum)) frame.setStatus(ResourceValueFrame.ESCAPED); handleNormalInstruction(inv); }
public Stream createStream(Location location, ObjectType type, ConstantPoolGen cpg, RepositoryLookupFailureCallback lookupFailureCallback) { Instruction ins = location.getHandle().getInstruction(); try { if (ins instanceof InvokeInstruction) { if (!Hierarchy.isSubtype(type, baseClassType)) return null; Stream stream = new Stream(location, type.getClassName(), baseClassType.getClassName()).setIsOpenOnCreation(true) .setIgnoreImplicitExceptions(true); if (bugType != null) stream.setInteresting(bugType); return stream; } } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); } return null; }
/** * Add a method annotation for the method which is called by given * instruction. * * @param methodGen the method containing the call * @param inv the InvokeInstruction * @return this object */ public BugInstance addCalledMethod(MethodGen methodGen, InvokeInstruction inv) { ConstantPoolGen cpg = methodGen.getConstantPool(); String className = inv.getClassName(cpg); String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); addMethod(className, methodName, methodSig); describe("METHOD_CALLED"); return this; }
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { // See if the instruction is an InvokeInstruction Instruction ins = handle.getInstruction(); if (!(ins instanceof InvokeInstruction)) return null; InvokeInstruction inv = (InvokeInstruction) ins; String methodName = inv.getMethodName(cpg); boolean isStatic = inv.getOpcode() == Constants.INVOKESTATIC; boolean isCtor = methodName.equals("<init>"); int actualMode = 0; if (isStatic) actualMode |= STATIC; if (isCtor) actualMode |= CONSTRUCTOR; if (!isStatic && !isCtor) actualMode |= INSTANCE; // Intersection of actual and desired modes must be nonempty. if ((actualMode & mode) == 0) return null; // Check class name, method name, and method signature. if (!methodNameMatcher.match(methodName) || !methodSigMatcher.match(inv.getSignature(cpg)) || !classNameMatcher.match(inv.getClassName(cpg))) return null; // It's a match! return new MatchResult(this, bindingSet); }
/** * @param aInstruction * @param aPoolGen */ public InvokeReference( InvokeInstruction aInstruction, ConstantPoolGen aPoolGen) { super(aInstruction, aPoolGen); }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; //1. Verify if the class used has a known sink String fullMethodName = getFullMethodName(invoke, cpg); //This will skip the most common lookup if ("java/lang/Object.<init>()V".equals(fullMethodName)) { return InjectionPoint.NONE; } InjectionPoint injectionPoint = injectionMap.get(fullMethodName); if (injectionPoint != null) { return injectionPoint; } try { //2. Verify if the super classes match a known sink JavaClass classDef = Repository.lookupClass(invoke.getClassName(cpg)); for (JavaClass superClass : classDef.getSuperClasses()) { if ("java.lang.Object".equals(superClass.getClassName())) { continue; } String superClassFullMethodName = superClass.getClassName().replace('.','/') + "." + invoke.getMethodName(cpg) + invoke.getSignature(cpg); injectionPoint = injectionMap.get(superClassFullMethodName); if (injectionPoint != null) { return injectionPoint; } } } catch (ClassNotFoundException e) { AnalysisContext.reportMissingClass(e); } return InjectionPoint.NONE; }
@Override protected void analyzeLocation(ClassContext classContext, Method method, InstructionHandle handle, ConstantPoolGen cpg, InvokeInstruction invoke, TaintFrame fact, String currentMethod) throws DataflowAnalysisException { SourceLineAnnotation sourceLine = SourceLineAnnotation.fromVisitedInstruction(classContext, method, handle); checkSink(cpg, invoke, fact, sourceLine, currentMethod); InjectionPoint injectionPoint = getInjectionPoint(invoke, cpg, handle); for (int offset : injectionPoint.getInjectableArguments()) { int priority = getPriorityFromTaintFrame(fact, offset); if (priority == Priorities.IGNORE_PRIORITY) { continue; } Taint parameterTaint = fact.getStackValue(offset); InjectionSink injectionSink = new InjectionSink(this, injectionPoint.getBugType(), priority, classContext, method, handle, injectionPoint.getInjectableMethod()); injectionSink.addLines(parameterTaint.getAllLocations()); injectionSink.addUnknownSources(parameterTaint.getUnknownLocations()); if (parameterTaint.hasParameters()) { // add sink to multi map Set<InjectionSink> sinkSet = injectionSinks.get(currentMethod); if (sinkSet == null) { sinkSet = new HashSet<InjectionSink>(); } assert !sinkSet.contains(injectionSink) : "duplicate sink"; sinkSet.add(injectionSink); injectionSinks.put(currentMethod, sinkSet); sinkTaints.put(new MethodAndSink(currentMethod, injectionSink), parameterTaint); } else { // sink cannot be influenced by other methods calls, so report it immediately bugReporter.reportBug(injectionSink.generateBugInstance(true)); } return; } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { InjectionPoint injectionPoint = null; for (InjectionSource source : getInjectionSource()) { injectionPoint = source.getInjectableParameters(invoke, cpg, handle); if (injectionPoint != InjectionPoint.NONE) { break; } } if (injectionPoint == null || injectionPoint == InjectionPoint.NONE) { injectionPoint = super.getInjectionPoint(invoke, cpg, handle); } return injectionPoint; }
@Override public void analyzeInstruction(Instruction ins) throws DataflowAnalysisException { //Print the bytecode instruction if it is globally configured if (FindSecBugsGlobalConfig.getInstance().isDebugPrintInvocationVisited() && ins instanceof InvokeInstruction) { ByteCode.printOpCode(ins, cpg); } else if (FindSecBugsGlobalConfig.getInstance().isDebugPrintInstructionVisited()) { ByteCode.printOpCode(ins, cpg); } super.analyzeInstruction(ins); }
/** * Regroup the method invocations (INVOKEINTERFACE, INVOKESPECIAL, * INVOKESTATIC, INVOKEVIRTUAL) * * @param obj one of the invoke instructions */ private void visitInvoke(InvokeInstruction obj) { assert obj != null; try { TaintMethodConfig methodConfig = getMethodConfig(obj); ObjectType realInstanceClass = (methodConfig == null) ? null : methodConfig.getOutputTaint().getRealInstanceClass(); Taint taint = getMethodTaint(methodConfig); assert taint != null; if (FindSecBugsGlobalConfig.getInstance().isDebugTaintState()) { taint.setDebugInfo(obj.getMethodName(cpg) + "()"); } if (taint.isUnknown()) { taint.addLocation(getTaintLocation(), false); } taintMutableArguments(methodConfig, obj); transferTaintToMutables(methodConfig, taint); // adds variable index to taint too Taint taintCopy = new Taint(taint); // return type is not always the instance type taintCopy.setRealInstanceClass(realInstanceClass); modelInstruction(obj, getNumWordsConsumed(obj), getNumWordsProduced(obj), taintCopy); } catch (Exception e) { String className = ClassName.toSlashedClassName(obj.getReferenceType(cpg).toString()); String methodName = obj.getMethodName(cpg); String signature = obj.getSignature(cpg); throw new RuntimeException("Unable to call " + className + '.' + methodName + signature, e); } }
private TaintMethodConfig getMethodConfig(InvokeInstruction obj) { String signature = obj.getSignature(cpg); String returnType = getReturnType(signature); String className = getInstanceClassName(obj); String methodName = obj.getMethodName(cpg); String methodId = "." + methodName + signature; TaintMethodConfig config = taintConfig.getMethodConfig(getFrame(), methodDescriptor, className, methodId); if (config != null) { config = getConfigWithReplaceTags(config, className, methodName); } if (config != null && config.isConfigured()) { return config; } if (taintConfig.isClassTaintSafe(returnType)) { return TaintMethodConfig.SAFE_CONFIG; } if (config != null) { return config; } if (Constants.CONSTRUCTOR_NAME.equals(methodName) && !taintConfig.isClassTaintSafe("L" + className + ";")) { try { int stackSize = getFrame().getNumArgumentsIncludingObjectInstance(obj, cpg); return TaintMethodConfig.getDefaultConstructorConfig(stackSize); } catch (DataflowAnalysisException ex) { throw new InvalidBytecodeException(ex.getMessage(), ex); } } return null; }