Files
codeql-workshop-dataflow-c/readme-low-level.org
2025-03-17 19:36:58 -07:00

3.6 KiB

CodeQL AST in dot and pdf

The control flow graph is narrowed to the function of interest,

  int copy_mem(unsigned int unused, dyn_input_t *input,
               unsigned int input_types) {...}

from ./tests-common/test_part1.c, so we do the same for the AST.

  # Produce ast in dot format
  codeql database analyze                             \
         --format=dot --output=ast.dot                \
         -j8 -v --ram=16000                           \
         --rerun                                      \
         --                                           \
         cpp-dataflow-part1-database                  \
         graphs/ast.ql                            

  # Convert dot to pdf
  dot -Tpdf < ast.dot/cpp/print-ast.dot > ast.dot/cpp/print-ast.pdf
  dot -Tsvg < ast.dot/cpp/print-ast.dot > ast.dot/cpp/print-ast.svg

  # View the graph
  open ast.dot/cpp/print-ast.pdf

  # This comes from
  tests-common/test_part1.c

CodeQL CFG in dot and pdf

The whole control flow graph is very large, so the query narrows it to the function of interest,

  int copy_mem(unsigned int unused, dyn_input_t *input,
               unsigned int input_types) {...}

from ./tests-common/test_part1.c

  # Produce CFG in dot format
  codeql database analyze                             \
         --format=dot --output=cfg.dot                \
         -j8 -v --ram=16000                           \
         --rerun                                      \
         --                                           \
         cpp-dataflow-part1-database                  \
         graphs/cfg.ql                            


  # Convert dot to pdf
  dot -Tpdf < cfg.dot/cpp/print-cfg.dot > cfg.dot/cpp/print-cfg.pdf
  dot -Tsvg < cfg.dot/cpp/print-cfg.dot > cfg.dot/cpp/print-cfg.svg

  # View the graph
  open cfg.dot/cpp/print-cfg.pdf

Original source code

  int copy_mem(unsigned int unused, dyn_input_t *input,
               unsigned int input_types) {
    memcpy(input[0].ptr.buf, input[1].ptr.buf,
           input[1].ptr.size); // NON_COMPLIANT - type not checked
    copy_mem_nested(input);    // NON_COMPLIANT - type not checked

    if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
    }

    memcpy(input[0].ptr.buf, input[1].ptr.buf,
           input[1].ptr.size); // NON_COMPLIANT - guard doesn't control all paths
    copy_mem_nested(input);    // NON_COMPLIANT - guard doesn't control all paths

    if (DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM) == 100) {
      memcpy(input[0].ptr.buf, input[1].ptr.buf,
             input[1].ptr.size); // NON_COMPLIANT - useless type check
    }

    if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
      return 1;
    }

    memcpy(input[0].ptr.buf, input[1].ptr.buf,
           input[1].ptr.size); // COMPLIANT - type checked
    copy_mem_nested(input);    // COMPLIANT - type checked

    return 0;
  }

AST

The ast is inlined here. For better viewing, open the pdf (./ast.dot/cpp/print-ast.pdf) separately.

./ast.dot/cpp/print-ast.svg

CFG

The cfg is inlined here. For better viewing, open the pdf (./cfg.dot/cpp/print-cfg.pdf) separately.

./cfg.dot/cpp/print-cfg.svg