Beispiel #1
0
 private Expr CollectBooleanAssignment(IdentifierExpr glob, Variable assignedVar)
 {
     return(new NAryExpr(Token.NoToken, new FunctionCall(collectBoolFunc), new List <Expr>()
     {
         glob, IdentifierExpr.Ident(assignedVar)
     }));
 }
Beispiel #2
0
        public void AbstractNonTaintedImplementations()
        {
            var impls        = program.TopLevelDeclarations.OfType <Implementation>();
            var taintedImpls =
                impls.Where(x =>
                            allDeps[x.Proc].Values.Any(d => Utils.VariableUtils.IsTainted(d))
                            );
            var nonTaintedImpls = new HashSet <Implementation>();

            if (false)
            {
                throw new NotImplementedException("Don't exercise abstraction as it causes mismatch of signatures on two sides");
                //TODO: We get into parsing problems (print_tokens\(source,v2)) when one side is abstracted, and we get
                //different modsets later given the implementation for one and stub for another
                new HashSet <Implementation>(impls.Where(x => !taintedImpls.Contains(x))); //make a copy since topleveldecl changes
                nonTaintedImpls
                .Iter(x =>
                {
                    var modset = new VarSet(allDeps[x.Proc].ModSet());
                    Utils.VariableUtils.PruneLocals(x, modset);
                    modset.RemoveWhere(v => x.Proc.OutParams.Contains(v));
                    x.Proc.Modifies = modset.Select(v => IdentifierExpr.Ident(v)).ToList();
                    Utils.DependenciesUtils.AddCalleeDependencySpecs(program, x.Proc, allDeps[x.Proc]);
                }
                      );
                Console.WriteLine("[Abstract non-taint] Abstracted {0} procedures [{1}]", nonTaintedImpls.Count(),
                                  String.Join(",", nonTaintedImpls.Select(x => x.Name)));
            }

            //get the number of tainted outputs (outputs whose summaries are potentially changed)
            var outvars         = new List <Variable>();
            var botTaintOutVars = new List <Variable>();

            program.TopLevelDeclarations.OfType <Procedure>().Iter(x =>
            {
                if (!allDeps.ContainsKey(x))
                {
                    return;
                }
                allDeps[x].Keys.Iter(y => outvars.Add(y));
                var procBottomUpTaintVars = new List <Variable>();
                allDeps[x].Keys.Where(k => allDeps[x][k].Contains(Utils.VariableUtils.BottomUpTaintVar)).Iter(y => procBottomUpTaintVars.Add(y));
                botTaintOutVars.AddRange(procBottomUpTaintVars);
                //new: add an annotation to indicate that none of the variables are bottom up tainted
                var ens        = new Ensures(true, (Expr)Expr.True);
                ens.Attributes = new QKeyValue(Token.NoToken, "bottomup_tainted_vars",
                                               procBottomUpTaintVars.Select(v => (object)v.Name).ToList(), null);
                x.Ensures.Add(ens);
            });
            Console.WriteLine("#outputs with no bottomuptaint / #outputs = {0} / {1} ", outvars.Count - botTaintOutVars.Count, outvars.Count);

            //Do the removal after you are done with nonTaintedImpls, otherwise that becomes an empty set
            program.RemoveTopLevelDeclarations(x => nonTaintedImpls.Contains(x));
        }
Beispiel #3
0
        private Cmd InstrumentAssignCmd(AssignCmd assignCmd, Block enclBlock)
        {
            if (assignCmd.Lhss.Count > 1)
            {
                Console.WriteLine("Ignoring parallel assigns from statement taint {0}", assignCmd);
                return(null);
            }
            var assignedVar = assignCmd.Lhss[0].DeepAssignedVariable;
            var lhss        = new List <AssignLhs>();
            var rhss        = new List <Expr>();
            //lhs := rhs
            //out := if b_l then out else f(out, rhs)
            //lhs := upd(a, i, v)
            //out := if b_l then out else g(out, i, v)
            var glob   = IdentifierExpr.Ident(globalCollectAssignmentsVar);
            var bConst = LookupOrCreateNewGuardConst(assignCmd, enclBlock);

            lhss.Add(new SimpleAssignLhs(Token.NoToken, glob));
            Expr expr;
            var  assignType = assignedVar.TypedIdent.Type;

            if (assignType.IsBool)
            {
                expr = CollectBooleanAssignment(glob, assignedVar);
            }
            else if (assignType.IsInt)
            {
                expr = CollectIntAssignment(glob, assignedVar);
            }
            else if (assignType.IsMap)
            {
                expr = CollectMapAssignment(glob, assignCmd.Rhss[0]);
            }
            else
            {
                Console.WriteLine("Skipping unexpected assignment during statement taint instrumentation {0}", assignCmd);
                return(null);
            }
            if (expr == null)
            {
                return(null);
            }
            var iteArgs = new List <Expr>()
            {
                IdentifierExpr.Ident(bConst), glob, expr
            };

            rhss.Add(new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), iteArgs));
            return(new AssignCmd(Token.NoToken, lhss, rhss));
        }
Beispiel #4
0
        private void CheckCandidateAssert(Constant c)
        {
            //TODO: generalize to allow multiple roots
            Debug.Assert(entryPoints.Count() == 1, "Currently only considering a single main in mergedProgram");

            var expr = houdiniConsts
                       .Where(y => y != c)
                       .Aggregate((Expr)Expr.True, (x, y) => Expr.And(x, Expr.Not(IdentifierExpr.Ident(y))));

            expr = Expr.And(expr, IdentifierExpr.Ident(c));
            var axm = new Axiom(Token.NoToken, expr);

            mergedProg.AddTopLevelDeclaration(axm);
            InvokeCorralCommandLine(c);
            mergedProg.RemoveTopLevelDeclaration(axm);
        }
Beispiel #5
0
            /// <summary>
            /// Returns a set {m_i, updateexpr_i} for all m_i that are updated
            /// </summary>
            /// <param name="map"></param>
            /// <param name="index"></param>
            /// <param name="value"></param>
            /// <param name="btype"></param>
            /// <returns></returns>
            private List <Tuple <IdentifierExpr, Expr> > VisitMapStore(IdentifierExpr mv, Expr index, Expr value)
            {
                //get AS set and ASFunc for this map. lookup by name
                //create m@1,..
                //create n parallel assignments with 1 ite
                //m@1[index], m@2[index],.. = ite(AS(index,AS1), value, m@1[index]), ite(...),..
                var aSites = currAllocSiteMapInfo.ContainsKey(index) ? currAllocSiteMapInfo[index] : (new HashSet <Expr>());

                if (aSites.Count == 0)
                {
                    //Case where AS(index) = {}
                    var splitMapVar = GetOrCreateSplitMap(mv.Decl, SplitConsts.externalAlloc);
                    return(new List <Tuple <IdentifierExpr, Expr> >()
                    {
                        Tuple.Create(IdentifierExpr.Ident(splitMapVar), value)
                    });
                }
                var btype = value.Type;

                if (btype == null)
                {
                    Console.WriteLine("Stop here");
                }
                Debug.Assert(btype != null);
                var iteArgs = new List <Tuple <IdentifierExpr, Expr> >(); //list of (mv', ite(cond,trueExpr,falseExpr)) tuples

                aSites
                .Iter(x =>
                {
                    var cond = Utils.DeclUtils.MkFuncApp(allocSiteFunc, new List <Expr>()
                    {
                        index, x
                    });                                                                                     //AS(index,AS1)
                    var splitMapVar = GetOrCreateSplitMap(mv.Decl, x.ToString());                           //m@AS1
                    var arg         = Expr.Select(IdentifierExpr.Ident(splitMapVar), new Expr[] { index }); //m@AS1[index]
                    if (arg.Type == null)
                    {
                        arg.Type = (splitMapVar.TypedIdent.Type as MapType).Result;
                        //Console.WriteLine("Inserted missing type for  mapselect expr {0}", arg);
                        insertedTypeWarnings.Add(Tuple.Create((Expr)arg, "mapselect"));
                    }

                    Debug.Assert(arg.Type != null);
                    var iteFunc = Utils.DeclUtils.MkOrGetFunc(prog, SplitConsts.iteFuncName, btype,
                                                              new List <Microsoft.Boogie.Type>()
                    {
                        Microsoft.Boogie.Type.Bool, btype, btype
                    });
                    var iteVal =
                        Utils.DeclUtils.MkFuncApp(iteFunc, new List <Expr>()
                    {
                        (Expr)cond, value, (Expr)arg
                    });                                                                                           //ite(AS(index,AS1), value, m@AS1[index])
                    if (iteVal.Type == null)
                    {
                        //Console.WriteLine("Inserted missing type for ite expr {0}", iteVal);
                        insertedTypeWarnings.Add(Tuple.Create((Expr)iteVal, "ite"));
                        iteVal.Type = arg.Type;
                    }
                    iteArgs.Add(Tuple.Create(IdentifierExpr.Ident(splitMapVar), (Expr)iteVal));
                }
                      );
                return(iteArgs);
            }
Beispiel #6
0
            /// <summary>
            /// M := E
            /// </summary>
            /// <param name="lhs"></param>
            /// <param name="rhs"></param>
            /// <returns></returns>
            private AssignCmd VisitEntireMapAssignment(AssignLhs lhs, Expr rhs)
            {
                Debug.Assert(lhs.DeepAssignedVariable.TypedIdent.Type.IsMap);
                var ac = new AssignCmd(Token.NoToken, new List <AssignLhs>()
                {
                    lhs
                }, new List <Expr>()
                {
                    rhs
                });

                //M := old(M)
                if (!
                    (rhs is OldExpr &&
                     ((OldExpr)rhs).Expr is IdentifierExpr &&
                     ((IdentifierExpr)((OldExpr)rhs).Expr).Decl == lhs.DeepAssignedVariable)
                    )
                {
                    Console.WriteLine("Don't handle direct stores M := e yet, found {0}", ac.ToString());
                    unhandledCommands.Add(ac);
                    return(ac);
                }
                var splitVars = allAllocSites
                                .Select(x => GetOrCreateSplitMap(lhs.DeepAssignedVariable, x))
                                .ToList();

                ac.Lhss = splitVars.Select(x => (AssignLhs) new SimpleAssignLhs(Token.NoToken, IdentifierExpr.Ident(x))).ToList();
                ac.Rhss = splitVars.Select(x => (Expr) new OldExpr(Token.NoToken, (Expr)IdentifierExpr.Ident(x))).ToList();
                return(ac);
            }
Beispiel #7
0
            private void CreateMainProcedure(Function reach)
            {
                //blocks
                List <Block>    mainBlocks = new List <Block>();
                List <Variable> locals     = new List <Variable>();

                HashSet <Constant> blockCallConsts = new HashSet <Constant>();

                foreach (Implementation impl in prog.TopLevelDeclarations.Where(x => x is Implementation))
                {
                    // skip this impl if it is not marked as an entrypoint
                    if (useProvidedEntryPoints && !QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "entrypoint"))
                    {
                        continue;
                    }

                    impl.Attributes      = BoogieUtil.removeAttr("entrypoint", impl.Attributes);
                    impl.Proc.Attributes = BoogieUtil.removeAttr("entrypoint", impl.Proc.Attributes);

                    // skip initialization procedure
                    if (QKeyValue.FindBoolAttribute(impl.Attributes, AvnAnnotations.InitialializationProcAttr) ||
                        QKeyValue.FindBoolAttribute(impl.Proc.Attributes, AvnAnnotations.InitialializationProcAttr))
                    {
                        continue;
                    }

                    entrypoints.Add(impl.Name);

                    //allocate params
                    var args = new List <Variable>();
                    var rets = new List <Variable>();


                    impl.OutParams.ForEach(v => rets.Add(BoogieAstFactory.MkLocal(v.Name + "_" + impl.Name, v.TypedIdent.Type)));
                    if (Options.allocateParameters)
                    {
                        // use impl.Proc here to pickup scalar/pointer attributes
                        impl.Proc.InParams.ForEach(v =>
                        {
                            var l = BoogieAstFactory.MkLocal(v.Name + "_" + impl.Name, v.TypedIdent.Type);
                            // We are delibrately dropping the attributes so that
                            // all parameters are initialized by allocation
                            //l.Attributes = v.Attributes;
                            args.Add(l);
                        });
                        locals.AddRange(args);
                    }
                    else
                    {
                        impl.Proc.InParams.ForEach(v =>
                        {
                            var g = BoogieAstFactory.MkGlobal(v.Name + "_" + impl.Name, v.TypedIdent.Type);
                            //g.Attributes = v.Attributes;
                            args.Add(g);
                        });
                        globalParams.AddRange(args);
                    }


                    locals.AddRange(rets);

                    //call
                    var blockCallConst = new Constant(Token.NoToken,
                                                      new TypedIdent(Token.NoToken, "__block_call_" + impl.Name, btype.Bool), false);
                    blockCallConsts.Add(blockCallConst);
                    blockEntryPointConstants[blockCallConst.Name] = impl.Name;
                    impl2BlockingConstant[impl.Name] = blockCallConst;
                    var blockCallAssumeCmd = new AssumeCmd(Token.NoToken, IdentifierExpr.Ident(blockCallConst));

                    var cmds = new List <Cmd>();
                    cmds.Add(blockCallAssumeCmd);
                    if (Options.allocateParameters) // allocate parameters if option is enabled
                    {
                        var argMallocCmds = AllocatePointersAsUnknowns(args);
                        cmds.AddRange(argMallocCmds);
                    }

                    // The beginning of an entry point must be reachable: assume reach(true);
                    cmds.Add(new AssumeCmd(Token.NoToken, new NAryExpr(Token.NoToken,
                                                                       new FunctionCall(reach), new List <Expr> {
                        Expr.True
                    })));

                    var callCmd = new CallCmd(Token.NoToken, impl.Name, args.ConvertAll(x => (Expr)IdentifierExpr.Ident(x)),
                                              rets.ConvertAll(x => IdentifierExpr.Ident(x)));
                    callCmd.Attributes = new QKeyValue(Token.NoToken, AvUtil.AvnAnnotations.AvhEntryPointAttr, new List <object>(), callCmd.Attributes);

                    cmds.Add(callCmd);
                    //succ
                    var txCmd = new ReturnCmd(Token.NoToken);
                    var blk   = BoogieAstFactory.MkBlock(cmds, txCmd);
                    mainBlocks.Add(blk);
                }
                foreach (Procedure proc in prog.TopLevelDeclarations.OfType <Procedure>())
                {
                    proc.Attributes = BoogieUtil.removeAttr("entrypoint", proc.Attributes);
                }
                // add global variables to prog
                // globals.Iter(x => prog.AddTopLevelDeclaration(x));
                //add the constants to the prog
                blockCallConsts.Iter(x => prog.AddTopLevelDeclaration(x));
                //TODO: get globals of type refs/pointers and maps
                var initCmd = (AssumeCmd)BoogieAstFactory.MkAssume(Expr.True);

                var globalCmds = new List <Cmd>()
                {
                    initCmd
                };
                //add call to corralExtraInit
                var init = Instrumentations.GetEnvironmentAssumptionsProc(prog);

                if (init != null && !Options.DelayInitialization)
                {
                    globalCmds.Add(BoogieAstFactory.MkCall(init, new List <Expr>(), new List <Variable>()));
                }

                // Dont initialize Boogie instrumentation variables
                prog.GlobalVariables
                .Where(g => g.Name == "alloc" || BoogieUtil.checkAttrExists(AvnAnnotations.AllocatorVarAttr, g.Attributes))
                .Where(g => !BoogieUtil.checkAttrExists("scalar", g.Attributes))
                .Iter(g => g.AddAttribute("scalar"));

                // initialize globals
                prog.GlobalVariables
                .Where(g => g.Name != "alloc" && !BoogieUtil.checkAttrExists(AvnAnnotations.AllocatorVarAttr, g.Attributes))
                .Iter(g => g.Attributes = BoogieUtil.removeAttrs(new HashSet <string> {
                    "scalar", "pointer"
                }, g.Attributes));

                globalCmds.AddRange(AllocatePointersAsUnknowns(prog.GlobalVariables.Select(x => (Variable)x).ToList()));

                if (init != null && Options.DelayInitialization)
                {
                    globalCmds.Add(BoogieAstFactory.MkCall(init, new List <Expr>(), new List <Variable>()));
                }

                // globals for parameters
                prog.AddTopLevelDeclarations(globalParams);

                //first block
                var transferCmd =
                    mainBlocks.Count > 0 ? (TransferCmd)(new GotoCmd(Token.NoToken, mainBlocks)) : (TransferCmd)(new ReturnCmd(Token.NoToken));
                Block blkStart = new Block(Token.NoToken, "CorralMainStart", globalCmds, transferCmd);
                var   blocks   = new List <Block>();

                blocks.Add(blkStart);
                blocks.AddRange(mainBlocks);
                var mainProcImpl = BoogieAstFactory.MkImpl(AvnAnnotations.CORRAL_MAIN_PROC, new List <Variable>(), new List <Variable>(), locals, blocks);

                mainProcImpl[0].AddAttribute("entrypoint");
                prog.AddTopLevelDeclarations(mainProcImpl);
            }
Beispiel #8
0
            //Change the body of any stub that returns a pointer into calling unknown()
            //TODO: only do this for procedures with a single return with a pointer type
            private void MkStubImplementation(List <Implementation> stubImpls, Procedure p)
            {
                List <Cmd>      cmds      = new List <Cmd>();
                List <Variable> localVars = new List <Variable>();

                stubs.Add(p.Name);
                foreach (var op in p.OutParams)
                {
                    if (IsPointerVariable(op))
                    {
                        cmds.Add(AllocatePointerAsUnknown(op));
                    }
                    else
                    {
                        // Avoid using Havoc -- we'll let this fall on the floor as an
                        // uninitialized variable. AVN will take care of concretizing it
                        //cmds.Add(BoogieAstFactory.MkHavocVar(op));
                    }
                }
                foreach (var v in p.Modifies.Select(ie => ie.Decl))
                {
                    if (IsPointerVariable(v))
                    {
                        cmds.Add(AllocatePointerAsUnknown(v));
                    }
                    else
                    {
                        // unsupported
                        Console.WriteLine("Warning: demonic havoc of global {0} in {1}", v.Name, p.Name);
                    }
                }
                foreach (var ip in p.InParams)
                {
                    if (!BoogieUtil.checkAttrExists("ref", ip.Attributes))
                    {
                        continue;
                    }
                    string mapName = QKeyValue.FindStringAttribute(ip.Attributes, "ref");
                    if (mapName == null)
                    {
                        Utils.Print(String.Format("Expecting a map <name> with {:ref <name>} annotation on procedure {0}", p.Name),
                                    Utils.PRINT_TAG.AV_WARNING);
                        continue;
                    }
                    var mapVars = prog.TopLevelDeclarations.OfType <Variable>().Where(x => x.Name == mapName && x.TypedIdent.Type.IsMap);
                    if (mapVars.Count() != 1)
                    {
                        Utils.Print(String.Format("Mapname {0} provided in {{:ref}} for parameter {1} for procedure {2} has {3} matches, expecting exactly 1 match",
                                                  mapName, ip.Name, p.Name, mapVars.Count()),
                                    Utils.PRINT_TAG.AV_WARNING);
                        continue;
                    }
                    var tmpVar = BoogieAstFactory.MkLocal("__tmp_" + ip.Name, ip.TypedIdent.Type);
                    localVars.Add(tmpVar);
                    cmds.Add(AllocatePointerAsUnknown(tmpVar));
                    cmds.Add(BoogieAstFactory.MkMapAssign(mapVars.First(), IdentifierExpr.Ident(ip), IdentifierExpr.Ident(tmpVar)));
                }
                if (cmds.Count == 0)
                {
                    return;                  //don't create a body if no statements
                }
                var blk  = BoogieAstFactory.MkBlock(cmds, new ReturnCmd(Token.NoToken));
                var blks = new List <Block>()
                {
                    blk
                };
                //don't insert the proc as it already exists
                var impl = BoogieAstFactory.MkImpl(p.Name,
                                                   DropAnnotations(p.InParams),
                                                   DropAnnotations(p.OutParams),
                                                   new List <Variable>(), blks);

                ((Implementation)impl[1]).LocVars.AddRange(localVars);
                stubImpls.Add((Implementation)impl[1]);
            }