mirror of
https://github.com/hohn/codeql-info.git
synced 2025-12-16 20:53:04 +01:00
450 lines
33 KiB
HTML
450 lines
33 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en" data-content_root="../">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
||
<title>Detecting a potential buffer overflow — CodeQL</title>
|
||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=93459777" />
|
||
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
|
||
<script src="../_static/doctools.js?v=888ff710"></script>
|
||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
<link rel="icon" href="../_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="next" title="Using the guards library in C and C++" href="using-the-guards-library-in-cpp.html" />
|
||
<link rel="prev" title="Refining a query to account for edge cases" href="refining-a-query-to-account-for-edge-cases.html" />
|
||
|
||
<title>CodeQL docs</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/primer.css" type="text/css" />
|
||
|
||
|
||
</head><body>
|
||
<header class="Header">
|
||
<div class="Header-item--full">
|
||
<a href="https://codeql.github.com/docs" class="Header-link f2 d-flex flex-items-center">
|
||
<!-- <%= octicon "mark-github", class: "mr-2", height: 32 %> -->
|
||
<svg height="32" class="octicon octicon-mark-github mr-2" viewBox="0 0 16 16" version="1.1" width="32"
|
||
aria-hidden="true">
|
||
<path fill-rule="evenodd"
|
||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">
|
||
</path>
|
||
</svg>
|
||
<span class="hide-sm">CodeQL documentation</span>
|
||
</a>
|
||
</div>
|
||
<div class="Header-item hide-sm hide-md">
|
||
<script src="https://addsearch.com/js/?key=93b4d287e2fc079a4089412b669785d5&categories=!0xhelp.semmle.com,0xcodeql.github.com,1xdocs,1xcodeql-standard-libraries,1xcodeql-query-help"></script>
|
||
</div>
|
||
<div class="Header-item">
|
||
|
||
<details class="dropdown details-reset details-overlay d-inline-block">
|
||
<summary class="btn bg-gray-dark text-white border" aria-haspopup="true">
|
||
CodeQL resources
|
||
<div class="dropdown-caret"></div>
|
||
</summary>
|
||
|
||
<ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark">
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-overview">CodeQL overview</a></li>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
CodeQL tools
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-for-visual-studio-code">CodeQL for VS Code</a>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-cli">CodeQL CLI</a>
|
||
</li>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
CodeQL guides
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/writing-codeql-queries">Writing CodeQL queries</a></li>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-language-guides">CodeQL language guides</a>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
Reference docs
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/ql-language-reference/">QL language
|
||
reference</a>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-standard-libraries">CodeQL
|
||
standard-libraries</a>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-query-help">CodeQL
|
||
query help</a>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
Source files
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://github.com/github/codeql">CodeQL repository</a>
|
||
</ul>
|
||
</details>
|
||
|
||
</div>
|
||
|
||
</header>
|
||
<main class="bg-gray-light clearfix">
|
||
<nav class="SideNav position-sticky top-0 col-lg-3 col-md-3 float-left p-4 hide-sm hide-md overflow-y-auto">
|
||
|
||
<ul class="current">
|
||
<li class="toctree-l1"><a class="reference internal" href="../codeql-overview/index.html">CodeQL overview</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../codeql-for-visual-studio-code/index.html">CodeQL for Visual Studio Code</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../codeql-cli/index.html">CodeQL CLI</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../writing-codeql-queries/index.html">Writing CodeQL queries</a></li>
|
||
<li class="toctree-l1 current"><a class="reference internal" href="index.html">CodeQL language guides</a><ul class="current">
|
||
<li class="toctree-l2 current"><a class="reference internal" href="codeql-for-cpp.html">CodeQL for C and C++</a><ul class="current">
|
||
<li class="toctree-l3"><a class="reference internal" href="basic-query-for-cpp-code.html">Basic query for C and C++ code</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="codeql-library-for-cpp.html">CodeQL library for C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="functions-in-cpp.html">Functions in C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="expressions-types-and-statements-in-cpp.html">Expressions, types, and statements in C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="conversions-and-classes-in-cpp.html">Conversions and classes in C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="analyzing-data-flow-in-cpp.html">Analyzing data flow in C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="refining-a-query-to-account-for-edge-cases.html">Refining a query to account for edge cases</a></li>
|
||
<li class="toctree-l3 current"><a class="current reference internal" href="#">Detecting a potential buffer overflow</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="using-the-guards-library-in-cpp.html">Using the guards library in C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="using-range-analsis-in-cpp.html">Using range analysis for C and C++</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="hash-consing-and-value-numbering.html">Hash consing and value numbering</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-csharp.html">CodeQL for C#</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-go.html">CodeQL for Go</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-java.html">CodeQL for Java</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-javascript.html">CodeQL for JavaScript</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-python.html">CodeQL for Python</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-ruby.html">CodeQL for Ruby</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../ql-language-reference/index.html">QL language reference</a></li>
|
||
</ul>
|
||
|
||
|
||
</nav>
|
||
|
||
|
||
<div class="body col-sm-12 col-md-9 col-lg-9 float-left border-left">
|
||
|
||
<div class="hide-lg hide-xl px-4 pt-4">
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<ul>
|
||
<li class="nav-item nav-item-0"><a href="../contents.html">CodeQL</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="index.html"
|
||
>CodeQL language guides</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="codeql-for-cpp.html"
|
||
accesskey="U">CodeQL for C and C++</a> »</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<article class="p-4 col-lg-10 col-md-10 col-sm-12">
|
||
|
||
<section id="detecting-a-potential-buffer-overflow">
|
||
<span id="id1"></span><h1>Detecting a potential buffer overflow<a class="headerlink" href="#detecting-a-potential-buffer-overflow" title="Link to this heading">¶</a></h1>
|
||
<p>You can use CodeQL to detect potential buffer overflows by checking for allocations equal to <code class="docutils literal notranslate"><span class="pre">strlen</span></code> in C and C++. This topic describes how a C/C++ query for detecting a potential buffer overflow was developed.</p>
|
||
<section id="problemdetecting-memory-allocation-that-omits-space-for-a-null-termination-character">
|
||
<h2>Problem—detecting memory allocation that omits space for a null termination character<a class="headerlink" href="#problemdetecting-memory-allocation-that-omits-space-for-a-null-termination-character" title="Link to this heading">¶</a></h2>
|
||
<p>The objective of this query is to detect C/C++ code which allocates an amount of memory equal to the length of a null terminated string, without adding +1 to make room for a null termination character. For example the following code demonstrates this mistake, and results in a buffer overflow:</p>
|
||
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">processString</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">input</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">buffer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="n">strlen</span><span class="p">(</span><span class="n">input</span><span class="p">));</span>
|
||
|
||
<span class="w"> </span><span class="n">strcpy</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="p">...</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="basic-query">
|
||
<h2>Basic query<a class="headerlink" href="#basic-query" title="Link to this heading">¶</a></h2>
|
||
<p>Before you can write a query you need to decide what entities to search for and then define how to identify them.</p>
|
||
<section id="defining-the-entities-of-interest">
|
||
<h3>Defining the entities of interest<a class="headerlink" href="#defining-the-entities-of-interest" title="Link to this heading">¶</a></h3>
|
||
<p>You could approach this problem either by searching for code similar to the call to <code class="docutils literal notranslate"><span class="pre">malloc</span></code> in line 3 or the call to <code class="docutils literal notranslate"><span class="pre">strcpy</span></code> in line 5 (see example above). For our basic query, we start with a simple assumption: any call to <code class="docutils literal notranslate"><span class="pre">malloc</span></code> with only a <code class="docutils literal notranslate"><span class="pre">strlen</span></code> to define the memory size is likely to cause an error when the memory is populated.</p>
|
||
<p>Calls to <code class="docutils literal notranslate"><span class="pre">strlen</span></code> can be identified using the library <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/commons/StringAnalysis.qll/type.StringAnalysis$StrlenCall.html">StrlenCall</a> class, but we need to define a new class to identify calls to <code class="docutils literal notranslate"><span class="pre">malloc</span></code>. Both the library class and the new class need to extend the standard class <code class="docutils literal notranslate"><span class="pre">FunctionCall</span></code>, with the added restriction of the function name that they apply to:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import cpp
|
||
|
||
class MallocCall extends FunctionCall
|
||
{
|
||
MallocCall() { this.getTarget().hasGlobalName("malloc") }
|
||
}
|
||
</pre></div>
|
||
</div>
|
||
<blockquote class="pull-quote">
|
||
<div><p>Note</p>
|
||
<p>You could easily extend this class to include similar functions such as <code class="docutils literal notranslate"><span class="pre">realloc</span></code>, or your own custom allocator. With a little effort they could even include C++ <code class="docutils literal notranslate"><span class="pre">new</span></code> expressions (to do this, <code class="docutils literal notranslate"><span class="pre">MallocCall</span></code> would need to extend a common superclass of both <code class="docutils literal notranslate"><span class="pre">FunctionCall</span></code> and <code class="docutils literal notranslate"><span class="pre">NewExpr</span></code>, such as <code class="docutils literal notranslate"><span class="pre">Expr</span></code>).</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="finding-the-strlen-string-pattern">
|
||
<h3>Finding the <code class="docutils literal notranslate"><span class="pre">strlen(string)</span></code> pattern<a class="headerlink" href="#finding-the-strlen-string-pattern" title="Link to this heading">¶</a></h3>
|
||
<p>Before we start to write our query, there’s one remaining task. We need to modify our new <code class="docutils literal notranslate"><span class="pre">MallocCall</span></code> class, so it returns an expression for the size of the allocation. Currently this will be the first argument to the <code class="docutils literal notranslate"><span class="pre">malloc</span></code> call, <code class="docutils literal notranslate"><span class="pre">FunctionCall.getArgument(0)</span></code>, but converting this into a predicate makes it more flexible for future refinements.</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>class MallocCall extends FunctionCall
|
||
{
|
||
MallocCall() { this.getTarget().hasGlobalName("malloc") }
|
||
Expr getAllocatedSize() {
|
||
result = this.getArgument(0)
|
||
}
|
||
}
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="defining-the-basic-query">
|
||
<h3>Defining the basic query<a class="headerlink" href="#defining-the-basic-query" title="Link to this heading">¶</a></h3>
|
||
<p>Now we can write a query using these classes:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import cpp
|
||
|
||
class MallocCall extends FunctionCall
|
||
{
|
||
MallocCall() { this.getTarget().hasGlobalName("malloc") }
|
||
Expr getAllocatedSize() {
|
||
result = this.getArgument(0)
|
||
}
|
||
}
|
||
|
||
from MallocCall malloc
|
||
where malloc.getAllocatedSize() instanceof StrlenCall
|
||
select malloc, "This allocation does not include space to null-terminate the string."
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that there is no need to check whether anything is added to the <code class="docutils literal notranslate"><span class="pre">strlen</span></code> expression, as it would be in the corrected C code <code class="docutils literal notranslate"><span class="pre">malloc(strlen(string)</span> <span class="pre">+</span> <span class="pre">1)</span></code>. This is because the corrected code would in fact be an <code class="docutils literal notranslate"><span class="pre">AddExpr</span></code> containing a <code class="docutils literal notranslate"><span class="pre">StrlenCall</span></code>, not an instance of <code class="docutils literal notranslate"><span class="pre">StrlenCall</span></code> itself. A side-effect of this approach is that we omit certain unlikely patterns such as <code class="docutils literal notranslate"><span class="pre">malloc(strlen(string)</span> <span class="pre">+</span> <span class="pre">0</span></code>). In practice we can always come back and extend our query to cover this pattern if it is a concern.</p>
|
||
<blockquote class="pull-quote">
|
||
<div><p>Tip</p>
|
||
<p>For some projects, this query may not return any results. Possibly the project you are querying does not have any problems of this kind, but it is also important to make sure the query itself is working properly. One solution is to set up a test project with examples of correct and incorrect code to run the query against (the C code at the very top of this page makes a good starting point). Another approach is to test each part of the query individually to make sure everything is working.</p>
|
||
</div></blockquote>
|
||
<p>When you have defined the basic query then you can refine the query to include further coding patterns or to exclude false positives:</p>
|
||
</section>
|
||
</section>
|
||
<section id="improving-the-query-using-the-ssa-library">
|
||
<h2>Improving the query using the ‘SSA’ library<a class="headerlink" href="#improving-the-query-using-the-ssa-library" title="Link to this heading">¶</a></h2>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">SSA</span></code> library represents variables in static single assignment (SSA) form. In this form, each variable is assigned exactly once and every variable is defined before it is used. The use of SSA variables simplifies queries considerably as much of the local data flow analysis has been done for us. For more information, see <a class="reference external" href="https://en.wikipedia.org/wiki/Static_single_assignment_form">Static single assignment</a> on Wikipedia.</p>
|
||
<section id="including-examples-where-the-string-size-is-stored-before-use">
|
||
<h3>Including examples where the string size is stored before use<a class="headerlink" href="#including-examples-where-the-string-size-is-stored-before-use" title="Link to this heading">¶</a></h3>
|
||
<p>The query above works for simple cases, but does not identify a common coding pattern where <code class="docutils literal notranslate"><span class="pre">strlen(string)</span></code> is stored in a variable before being passed to <code class="docutils literal notranslate"><span class="pre">malloc</span></code>, as in the following example:</p>
|
||
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strlen</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
|
||
<span class="n">buffer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="n">len</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>To identify this case we can use the standard library <code class="docutils literal notranslate"><span class="pre">SSA.qll</span></code> (imported as <code class="docutils literal notranslate"><span class="pre">semmle.code.cpp.controlflow.SSA</span></code>).</p>
|
||
<p>This library helps us identify where values assigned to local variables may subsequently be used.</p>
|
||
<p>For example, consider the following code:</p>
|
||
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">myFunction</span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="n">condition</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"alpha"</span><span class="p">;</span><span class="w"> </span><span class="c1">// definition #1 of x</span>
|
||
|
||
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"x = %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"> </span><span class="c1">// use #1 of x</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">condition</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"beta"</span><span class="p">;</span><span class="w"> </span><span class="c1">// definition #2 of x</span>
|
||
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"gamma"</span><span class="p">;</span><span class="w"> </span><span class="c1">// definition #3 of x</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
|
||
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"x = %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"> </span><span class="c1">// use #2 of x</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>If we run the following query on the code, we get three results:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import cpp
|
||
import semmle.code.cpp.controlflow.SSA
|
||
|
||
from Variable var, Expr defExpr, Expr use
|
||
where exists(SsaDefinition ssaDef |
|
||
defExpr = ssaDef.getAnUltimateDefiningValue(var)
|
||
and use = ssaDef.getAUse(var))
|
||
select var, defExpr.getLocation().getStartLine() as dline, use.getLocation().getStartLine() as uline
|
||
</pre></div>
|
||
</div>
|
||
<p><strong>Results:</strong></p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p><code class="docutils literal notranslate"><span class="pre">var</span></code></p></th>
|
||
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">dline</span></code></p></th>
|
||
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">uline</span></code></p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
|
||
<td><p>3</p></td>
|
||
<td><p>5</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
|
||
<td><p>9</p></td>
|
||
<td><p>14</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
|
||
<td><p>11</p></td>
|
||
<td><p>14</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>It is often useful to also display the defining expression <code class="docutils literal notranslate"><span class="pre">defExpr</span></code>, if there is one. For example we might adjust the query above as follows:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import cpp
|
||
import semmle.code.cpp.controlflow.SSA
|
||
|
||
from Variable var, Expr defExpr, Expr use
|
||
where exists(SsaDefinition ssaDef |
|
||
defExpr = ssaDef.getAnUltimateDefiningValue(var)
|
||
and use = ssaDef.getAUse(var))
|
||
select var, defExpr.getLocation().getStartLine() as dline, use.getLocation().getStartLine() as uline, defExpr
|
||
</pre></div>
|
||
</div>
|
||
<p>Now we can see the assigned expression in our results:</p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p><code class="docutils literal notranslate"><span class="pre">var</span></code></p></th>
|
||
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">dline</span></code></p></th>
|
||
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">uline</span></code></p></th>
|
||
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">defExpr</span></code></p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
|
||
<td><p>3</p></td>
|
||
<td><p>5</p></td>
|
||
<td><p>alpha</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
|
||
<td><p>9</p></td>
|
||
<td><p>14</p></td>
|
||
<td><p>beta</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
|
||
<td><p>11</p></td>
|
||
<td><p>14</p></td>
|
||
<td><p>gamma</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
<section id="extending-the-query-to-include-allocations-passed-via-a-variable">
|
||
<h3>Extending the query to include allocations passed via a variable<a class="headerlink" href="#extending-the-query-to-include-allocations-passed-via-a-variable" title="Link to this heading">¶</a></h3>
|
||
<p>Using our experiments above we can expand our simple implementation of <code class="docutils literal notranslate"><span class="pre">MallocCall.getAllocatedSize()</span></code>. With the following refinement, if the argument is an access to a variable, <code class="docutils literal notranslate"><span class="pre">getAllocatedSize()</span></code> returns a value assigned to that variable instead of the variable access itself:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>Expr getAllocatedSize() {
|
||
if this.getArgument(0) instanceof VariableAccess then
|
||
exists(LocalScopeVariable v, SsaDefinition ssaDef |
|
||
result = ssaDef.getAnUltimateDefiningValue(v)
|
||
and this.getArgument(0) = ssaDef.getAUse(v))
|
||
else
|
||
result = this.getArgument(0)
|
||
}
|
||
</pre></div>
|
||
</div>
|
||
<p>The completed query will now identify cases where the result of <code class="docutils literal notranslate"><span class="pre">strlen</span></code> is stored in a local variable before it is used in a call to <code class="docutils literal notranslate"><span class="pre">malloc</span></code>. Here is the query in full:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import cpp
|
||
|
||
class MallocCall extends FunctionCall
|
||
{
|
||
MallocCall() { this.getTarget().hasGlobalName("malloc") }
|
||
|
||
Expr getAllocatedSize() {
|
||
if this.getArgument(0) instanceof VariableAccess then
|
||
exists(LocalScopeVariable v, SsaDefinition ssaDef |
|
||
result = ssaDef.getAnUltimateDefiningValue(v)
|
||
and this.getArgument(0) = ssaDef.getAUse(v))
|
||
else
|
||
result = this.getArgument(0)
|
||
}
|
||
}
|
||
|
||
from MallocCall malloc
|
||
where malloc.getAllocatedSize() instanceof StrlenCall
|
||
select malloc, "This allocation does not include space to null-terminate the string."
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="further-reading">
|
||
<h2>Further reading<a class="headerlink" href="#further-reading" title="Link to this heading">¶</a></h2>
|
||
<ul class="simple">
|
||
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/cpp/ql/src">CodeQL queries for C and C++</a></p></li>
|
||
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/cpp/ql/examples">Example queries for C and C++</a></p></li>
|
||
<li><p><a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/cpp/">CodeQL library reference for C and C++</a></p></li>
|
||
</ul>
|
||
<ul class="simple">
|
||
<li><p>“<a class="reference internal" href="../ql-language-reference/index.html#ql-language-reference"><span class="std std-ref">QL language reference</span></a>”</p></li>
|
||
<li><p>“<a class="reference internal" href="../codeql-overview/codeql-tools.html#codeql-tools"><span class="std std-ref">CodeQL tools</span></a>”</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</article>
|
||
|
||
<!-- GitHub footer, with links to terms and privacy statement -->
|
||
<div class="px-3 px-md-6 f6 py-4 d-sm-flex flex-justify-between flex-row-reverse flex-items-center border-top">
|
||
<ul class="list-style-none d-flex flex-items-center mb-3 mb-sm-0 lh-condensed-ultra">
|
||
<li class="mr-3">
|
||
<a href="https://twitter.com/github" title="GitHub on Twitter" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 273.5 222.3" class="d-block" height="18">
|
||
<path
|
||
d="M273.5 26.3a109.77 109.77 0 0 1-32.2 8.8 56.07 56.07 0 0 0 24.7-31 113.39 113.39 0 0 1-35.7 13.6 56.1 56.1 0 0 0-97 38.4 54 54 0 0 0 1.5 12.8A159.68 159.68 0 0 1 19.1 10.3a56.12 56.12 0 0 0 17.4 74.9 56.06 56.06 0 0 1-25.4-7v.7a56.11 56.11 0 0 0 45 55 55.65 55.65 0 0 1-14.8 2 62.39 62.39 0 0 1-10.6-1 56.24 56.24 0 0 0 52.4 39 112.87 112.87 0 0 1-69.7 24 119 119 0 0 1-13.4-.8 158.83 158.83 0 0 0 86 25.2c103.2 0 159.6-85.5 159.6-159.6 0-2.4-.1-4.9-.2-7.3a114.25 114.25 0 0 0 28.1-29.1"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li class="mr-3">
|
||
<a href="https://www.facebook.com/GitHub" title="GitHub on Facebook" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.3 15.4" class="d-block" height="18">
|
||
<path
|
||
d="M14.5 0H.8a.88.88 0 0 0-.8.9v13.6a.88.88 0 0 0 .8.9h7.3v-6h-2V7.1h2V5.4a2.87 2.87 0 0 1 2.5-3.1h.5a10.87 10.87 0 0 1 1.8.1v2.1h-1.3c-1 0-1.1.5-1.1 1.1v1.5h2.3l-.3 2.3h-2v5.9h3.9a.88.88 0 0 0 .9-.8V.8a.86.86 0 0 0-.8-.8z"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li class="mr-3">
|
||
<a href="https://www.youtube.com/github" title="GitHub on YouTube" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.17 13.6" class="d-block" height="16">
|
||
<path
|
||
d="M18.77 2.13A2.4 2.4 0 0 0 17.09.42C15.59 0 9.58 0 9.58 0a57.55 57.55 0 0 0-7.5.4A2.49 2.49 0 0 0 .39 2.13 26.27 26.27 0 0 0 0 6.8a26.15 26.15 0 0 0 .39 4.67 2.43 2.43 0 0 0 1.69 1.71c1.52.42 7.5.42 7.5.42a57.69 57.69 0 0 0 7.51-.4 2.4 2.4 0 0 0 1.68-1.71 25.63 25.63 0 0 0 .4-4.67 24 24 0 0 0-.4-4.69zM7.67 9.71V3.89l5 2.91z"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li class="mr-3 flex-self-start">
|
||
<a href="https://www.linkedin.com/company/github" title="GitHub on Linkedin" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" class="d-block" height="18">
|
||
<path
|
||
d="M3.94 2A2 2 0 1 1 2 0a2 2 0 0 1 1.94 2zM4 5.48H0V18h4zm6.32 0H6.34V18h3.94v-6.57c0-3.66 4.77-4 4.77 0V18H19v-7.93c0-6.17-7.06-5.94-8.72-2.91z"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="https://github.com/github" title="GitHub's organization" style="color: #959da5;">
|
||
<svg version="1.1" width="20" height="20" viewBox="0 0 16 16" class="octicon octicon-mark-github"
|
||
aria-hidden="true">
|
||
<path fill-rule="evenodd"
|
||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
|
||
</path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<ul class="list-style-none d-flex text-gray">
|
||
<li class="mr-3">©
|
||
<script type="text/javascript">document.write(new Date().getFullYear());</script> GitHub, Inc.</li>
|
||
<li class="mr-3"><a
|
||
href="https://docs.github.com/github/site-policy/github-terms-of-service"
|
||
class="link-gray">Terms </a></li>
|
||
<li><a href="https://docs.github.com/github/site-policy/github-privacy-statement"
|
||
class="link-gray">Privacy </a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<script type="text/javascript">
|
||
$(document).ready(function () {
|
||
$(".toggle > *").hide();
|
||
$(".toggle .name").show();
|
||
$(".toggle .name").click(function () {
|
||
$(this).parent().children().not(".name").toggle(400);
|
||
$(this).parent().children(".name").toggleClass("open");
|
||
})
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html> |