INFO2222 · Computing 2 Usability and Security
Software and System Security
Weeks 9-10 explain how software defects become vulnerabilities and how program analysis finds them: static analysis (without running the code), dynamic analysis (running and observing it), and symbolic analysis (exploring paths with a solver). Selecting the right technique for a given bug and stating its trade-offs is exactly how the exam frames this, alongside memory-corruption concepts.
What this chapter covers
- 01Memory-corruption bugs (use-after-free, memory leaks) and why manual testing misses subtle defects
- 02Static analysis: reason about code without running it via the AST, control-flow graph (CFG) and data-flow analysis
- 03What static analysis catches (unused imports/variables, potential division-by-zero, obvious logic bugs) and misses (runtime-only issues)
- 04Dynamic analysis: run the code with instrumentation (sanitizers, fuzzers) to find memory leaks, crashes and runtime errors
- 05Dynamic analysis needs an oracle (a definition of 'wrong') and good test inputs, and may still miss cases
- 06Symbolic analysis: treat inputs as symbolic, collect path constraints, and use an SMT solver (e.g. Z3) to find satisfying inputs
- 07Symbolic analysis' strength (excellent coverage, can produce witnesses/proofs) and weakness (expensive, slow, deep-loop path explosion)
- 08The cost/speed/coverage trade-off across static, dynamic and symbolic; blockchain/DeFi attack sources at recognition level
Match each defect to the analysis technique that best finds it
- +1(1) Unused 'import math' → static analysis. Building the AST reveals an import that is never referenced without running the code; this is a classic cheap static-analysis finding (tools like flake8/ESLint).
- +1(2) divide(10, 0) → static analysis (control-flow / data-flow) flags the potential division-by-zero path by tracing that b can be 0 into a division, again without execution. (Dynamic analysis would also catch it at runtime, but static finds it earliest and cheapest.)
- +1(3) Gradual memory exhaustion over a long run → dynamic analysis. A memory leak only manifests while the program executes, so you run it with instrumentation (a sanitizer/profiler) and observe growing memory — static analysis cannot see this runtime behaviour.
- +1(4) Need a concrete input hitting the nested x > 10 and y == x + 1 branch → symbolic analysis. Treat x and y as symbolic, collect the path constraints x > 10 and y = x + 1, and feed them to an SMT solver (Z3), which returns a satisfying witness such as x = 11, y = 12.
Key terms
- Use-after-free / memory leak
- Memory-corruption defects. Use-after-free accesses memory that has already been released; a memory leak fails to release memory so consumption grows over time. Both typically manifest only while the program runs, making them targets for dynamic analysis.
- Static analysis
- Analysing code without running it, using the Abstract Syntax Tree (AST), the control-flow graph (CFG, all possible execution paths) and data-flow analysis. It is fast and cheap and finds unused imports/variables, potential division-by-zero and obvious logic errors, but misses runtime-only issues.
- Dynamic analysis
- Analysing a program by executing it on inputs and observing behaviour, often with instrumentation (sanitizers, fuzzers, profilers). It finds real runtime bugs — memory leaks, crashes — but needs an oracle (a definition of 'wrong') and good test inputs, and may miss untested cases.
- Symbolic analysis
- Treating inputs as symbolic unknowns and systematically exploring paths, collecting path constraints and using an SMT solver (e.g. Z3) to decide satisfiability and produce concrete witness inputs. It gives excellent coverage and can yield proofs, but is expensive and slow.
- Path explosion
- The core limitation of symbolic execution: the number of feasible paths grows combinatorially with branches and loops, so deep loops and complex code overwhelm the solver with too many paths and cause timeouts.
- SMT solver (Z3)
- A Satisfiability-Modulo-Theories solver that decides whether a set of path constraints is satisfiable and, if so, returns a concrete assignment (e.g. sat [x = 11, y = 12]) — the witness input that reaches a target branch.
Software and System Security FAQ
When should I use static, dynamic or symbolic analysis?
Use static analysis for structural and path-visible issues you can find without running the code — unused imports, obvious logic errors, potential division-by-zero — because it is fast and cheap. Use dynamic analysis for defects that only appear at runtime, such as memory leaks and crashes, by executing with instrumentation, but remember it needs good test inputs and an oracle. Use symbolic analysis when you need to reach a specific deep branch or prove a property: it collects path constraints and asks a solver for a witness input, at higher cost.
What are the trade-offs between the three techniques?
Static analysis is low-cost and fast with moderate coverage but cannot see runtime behaviour. Dynamic analysis is medium cost and finds real runtime bugs but depends on the inputs you try and an oracle for correctness. Symbolic analysis has excellent, systematic coverage and can generate proofs or witnesses, but is expensive and slow and suffers from path explosion on deep loops, so solver timeouts are common. In practice they are complementary.
Why does symbolic execution struggle with big programs?
Because of path explosion: each branch can double the number of paths to explore, and loops multiply this further, so the count of feasible paths grows combinatorially. The SMT solver then faces an intractable number of path conditions and hits timeouts. That is why symbolic execution offers excellent coverage in principle but is expensive and often limited to smaller code or bounded exploration in practice.
Can AI help me with program analysis in INFO2222?
Yes, as a study aid. Sia can help you decide which analysis technique fits a described defect, explain what an AST, control-flow graph or SMT solver does, and reason through the cost/coverage trade-offs and path explosion. Use it to rehearse the selection logic for the security quizzes and exam; it does not do graded assessment for you, and the University of Sydney academic-integrity policy applies.
Exam move
Make the analysis-technique selection automatic, because that is the exam's framing. Build a small mental table: static = no execution, cheap/fast, catches structural and path-visible bugs (unused imports, division-by-zero) but not runtime issues; dynamic = run it with instrumentation, finds leaks and crashes, needs inputs and an oracle; symbolic = symbolic inputs plus an SMT solver (Z3) for witness inputs and great coverage, but expensive with path explosion on deep loops. Practise matching mixed defect lists to techniques and stating one justification each. Keep the memory-corruption concepts (use-after-free, leaks) and the AST/CFG/data-flow vocabulary as recall items, and treat blockchain/DeFi attack sources at recognition level only. Confirm the exam scope in the Week 12 revision on Canvas.
Working through Software and System Security in INFO2222? Sia is AskSia’s AI Computer Science tutor — ask any INFO2222 Software and System Security question and get a clear, step-by-step explanation grounded in how INFO2222 is taught and assessed. Read this chapter free, then take your hardest questions to Sia.