以下の内容はhttps://daisuke20240310.hatenablog.com/entry/codeql_qlsより取得しました。


CodeQL(静的解析ツール)で使われるクエリの選ばれ方を調べた

前回 は、GitHub が開発した CodeQL(セキュリティ脆弱性を検出するオープンソースのツール)を、ローカル(CodeQL CLI )で使ってみました。

しかし、UAF(Use After Free)が入ったソースコードを準備しましたが、標準クエリでは、UAF を検出できませんでした。

今回は、そのあたりを深掘りして、UAF を検知させるところまでやってみたいと思います。

それでは、やっていきます。

はじめに

「セキュリティ」の記事一覧です。良かったら参考にしてください。

セキュリティの記事一覧
・第1回:Ghidraで始めるリバースエンジニアリング(環境構築編)
・第2回:Ghidraで始めるリバースエンジニアリング(使い方編)
・第3回:VirtualBoxにParrotOS(OVA)をインストールする
・第4回:tcpdumpを理解して出力を正しく見れるようにする
・第5回:nginx(エンジンエックス)を理解する
・第6回:Python+Flask(WSGI+Werkzeug+Jinja2)を動かしてみる
・第7回:Python+FlaskのファイルをCython化してみる
・第8回:shadowファイルを理解してパスワードを解読してみる
・第9回:安全なWebアプリケーションの作り方(徳丸本)の環境構築
・第10回:Vue.jsの2.xと3.xをVue CLIを使って動かしてみる(ビルドも行う)
・第11回:Vue.jsのソースコードを確認する(ビルド後のソースも見てみる)
・第12回:徳丸本:OWASP ZAPの自動脆弱性スキャンをやってみる
・第13回:徳丸本:セッション管理を理解してセッションID漏洩で成りすましを試す
・第14回:OWASP ZAPの自動スキャン結果の分析と対策:パストラバーサル
・第15回:OWASP ZAPの自動スキャン結果の分析と対策:クロスサイトスクリプティング(XSS)
・第16回:OWASP ZAPの自動スキャン結果の分析と対策:SQLインジェクション
・第17回:OWASP ZAPの自動スキャン結果の分析と対策:オープンリダイレクト
・第18回:OWASP ZAPの自動スキャン結果の分析と対策:リスク中すべて
・第19回:CTF初心者向けのCpawCTFをやってみた
・第20回:hashcatの使い方(GPU実行時間の見積りとパスワード付きZIPファイル)
・第21回:Scapyの環境構築とネットワークプログラミング
・第22回:CpawCTF2にチャレンジします(クリア状況は随時更新します)
・第23回:K&Rのmalloc関数とfree関数を理解する
・第24回:C言語、アセンブラでシェルを起動するプログラムを作る(ARM64)
・第25回:機械語でシェルを起動するプログラムを作る(ARM64)
・第26回:入門セキュリhttps://github.com/SECCON/SECCON2017_online_CTF.gitティコンテスト(CTFを解きながら学ぶ実践技術)を読んだ
・第27回:x86-64 ELF(Linux)のアセンブラをGDBでデバッグしながら理解する(GDBコマンド、関連ツールもまとめておく)
・第28回:入門セキュリティコンテスト(CTFを解きながら学ぶ実践技術)のPwnable問題をやってみる
・第29回:実行ファイルのセキュリティ機構を調べるツール「checksec」のまとめ
・第30回:setodaNote CTF Exhibitionにチャレンジします(クリア状況は随時更新します)
・第31回:常設CTFのksnctfにチャレンジします(クリア状況は随時更新します)
・第32回:セキュリティコンテストチャレンジブックの「Part2 pwn」を読んだ
・第33回:セキュリティコンテストチャレンジブックの「付録」を読んでx86とx64のシェルコードを作った
・第34回:TryHackMeを始めてみたけどハードルが高かった話
・第35回:picoCTFを始めてみた(Beginner picoMini 2022:全13問完了)
・第36回:picoCTF 2024:Binary Exploitationの全10問をやってみた(Hardの1問は後日やります)
・第37回:picoCTF 2024:Reverse Engineeringの全7問をやってみた(Windowsプログラムの3問は後日やります)
・第38回:picoCTF 2024:General Skillsの全10問をやってみた
・第39回:picoCTF 2024:Web Exploitationの全6問をやってみた(最後の2問は解けず)
・第40回:picoCTF 2024:Forensicsの全8問をやってみた(最後の2問は解けず)
・第41回:picoCTF 2024:Cryptographyの全5問をやってみた(最後の2問は手つかず)
・第42回:picoCTF 2023:General Skillsの全6問をやってみた
・第43回:picoCTF 2023:Reverse Engineeringの全9問をやってみた
・第44回:picoCTF 2023:Binary Exploitationの全7問をやってみた(最後の1問は後日やります)
・第45回:書籍「セキュリティコンテストのためのCTF問題集」を読んだ
・第46回:書籍「詳解セキュリティコンテスト」のReversingを読んだ
・第47回:書籍「詳解セキュリティコンテスト」のPwnableのシェルコードを読んだ
・第48回:書籍「バイナリファイル解析 実践ガイド」を読んだ
・第49回:書籍「詳解セキュリティコンテスト」Pwnableのスタックベースエクスプロイトを読んだ
・第50回:書籍「詳解セキュリティコンテスト」Pwnableの共有ライブラリと関数呼び出しを読んだ
・第51回:picoCTF 2025:General Skillsの全5問をやってみた
・第52回:picoCTF 2025:Reverse Engineeringの全7問をやってみた
・第53回:picoCTF 2025:Binary Exploitationの全6問をやってみた
・第54回:書籍「詳解セキュリティコンテスト」Pwnableの仕様に起因する脆弱性を読んだ
・第55回:システムにインストールされたものと異なるバージョンのglibcを使う方法
・第56回:書籍「詳解セキュリティコンテスト」Pwnableのヒープベースエクスプロイトを読んだ
・第57回:書籍「解題pwnable」の第1章「準備」を読んだ
・第58回:書籍「解題pwnable」の第2章「login1(スタックバッファオーバーフロー1)」を読んだ
・第59回:書籍「解題pwnable」の第3章「login2(スタックバッファオーバーフロー2)」を読んだ
・第60回:書籍「解題pwnable」の第4章「login3(スタックバッファオーバーフロー3)」を読んだ
・第61回:書籍「解題pwnable」の第5章「rot13(書式文字列攻撃)」を読んだ
・第62回:GitHubが開発した静的解析ツール(脆弱性検出ツール)のCodeQLを使ってみる
・第63回:CodeQL(静的解析ツール)で使われるクエリの選ばれ方を調べた ← 今回

以下は、CodeQL の公式サイトです。

codeql.github.com

また、CodeQL CLI の公式ドキュメントは以下です。ありがたいことに、日本語のドキュメントがあります。

docs.github.com

このページにリンクがある ライセンスのページ を見ると、CodeQL は、GitHub で公開されているリポジトリのように、オープンソースに使うことは許されていますが、GitHub のプライベートリポジトリのような公開されていないソフトウェアに使う場合は、商用ライセンスが必要になるようです。

標準クエリとは

まず、現状の標準クエリが、どのようなクエリを使用しているかを特定するところから始めたいと思います。

公式ドキュメントの以下に書かれています。

ここのデフォルト値というところが標準クエリだと思います。標準クエリを使用した場合に、どのような内容が指摘されるのかは、なんとなく分かります。しかし、標準クエリが、具体的に、どうやって決まっているのか、どのクエリが標準クエリに含まれるのかは分かりません。

docs.github.com

前回、標準クエリを実行したときのログを見直すと、60個のクエリ(.qlファイル)が実行されていることが分かります。これがどこで定義されているのかを調べていきます。

実行されているクエリのパスを見ると、全て、qlpacks/codeql/cpp-queries のクエリが実行されていることが分かります。

前回、動作確認で使ったコマンドを、再度実行してみます。長いので、cpp-queries だけを抽出しています。

$ ./codeql resolve packs | grep cpp-queries
      codeql/cpp-queries@1.4.2: (query) /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/qlpack.yml

このクエリパック(qlpack.yml)の内容を確認します。前回、実行したときのログ([1/60] Loaded /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/DoubleFree.qlx. など)と比較したところ、.ql(クエリのソースコード).qlx(クエリをコンパイルした中間コード) の違いはありますが、一致しました。つまり、標準クエリは、codeql/cpp-queries@1.4.2 であると推測できます。

$ ./codeql resolve queries codeql/cpp-queries@1.4.2
Recording pack reference codeql/cpp-queries at /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2.
Recording pack reference codeql/suite-helpers at /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/.codeql/libraries/codeql/suite-helpers/1.0.25.
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/DoubleFree.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/IncorrectCheckScanf.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/NewFreeMismatch.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/OverflowStatic.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/UseAfterFree.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Arithmetic/IntMultToLong.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Format/SnprintfOverflow.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Format/WrongNumberOfFormatArguments.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Format/WrongTypeFormatArguments.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Memory Management/AllocaInLoop.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Memory Management/PointerOverflow.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Memory Management/SuspiciousCallToStrncat.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/OO/UnsafeUseOfThis.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/RedundantNullCheckSimple.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Likely Bugs/Underspecified Functions/TooFewArguments.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-014/MemsetMayBeDeleted.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-078/ExecTainted.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-079/CgiXss.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-089/SqlTainted.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-120/BadlyBoundedWrite.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-134/UncontrolledFormatString.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-190/ArithmeticUncontrolled.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-190/ComparisonWithWiderType.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-253/HResultBooleanConversion.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-311/CleartextFileWrite.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-311/CleartextTransmission.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-319/UseOfHttp.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-326/InsufficientKeySize.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-327/OpenSslHeartbleed.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-416/UseOfUniquePointerAfterLifetimeEnds.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-497/ExposedSystemData.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-611/XXE.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-676/DangerousFunctionOverflow.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-676/DangerousUseOfCin.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-704/WcharCharConversion.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-732/OpenCallMissingModeArgument.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Diagnostics/ExtractedFiles.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Diagnostics/ExtractionWarnings.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Diagnostics/FailedExtractorInvocations.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Summary/LinesOfCode.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Summary/LinesOfUserCode.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/CompilerErrors.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/DatabaseQuality.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/ExtractionMetrics.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/MissingIncludes.ql
/home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/SucceededIncludes.ql

CodeQLパック

以下のページに、CodeQLパックについて書かれています。CodeQLパックは、クエリパック、ライブラリパック、モデルパックの 3種類があるそうです。今回調べているのは、クエリパックです。

docs.github.com

上記ページでは、標準の CodeQLパックの一覧が書かれており、C/C++ については、codeql/cpp-queries のようです。翻訳のせいかもしれませんが、言葉の定義がフラフラしてるので、非常に読みにくいです。とにかく、cpp-code-scanning.qls が標準のクエリスイート(.qls)であることが分かります。

上記ページの中で、具体的に説明しているのは以下の部分です。

クエリスイートの説明
クエリスイートの説明

ちなみに、c-cpp の CodeQLパックは、他に、cpp-allcpp-examples がありました。

CodeQLパックのqlpack.yml

以下のページによると、CodeQLパックのルートディレクトリには、qlpack.yml があります。qlpack.yml には、CodeQLパック内のクエリをコンパイルする方法、CodeQLパックが依存するライブラリ、クエリスイート定義を検索する場所が書かれているとのことです。

docs.github.com

上記ページの qlpack.yml の読み方を参考にしながら、具体的に cpp-queries@1.4.2 の qlpack.yml の内容を見てみます。

defaultSuitedefaultSuiteFile は、どちらか一方だけ書くことが出来るようです(両方書かなくてもよい)。これらは実行するクエリを指定する異なる方法ということです。defaultSuite は、直接クエリファイル(.ql)を指定します。defaultSuiteFile はクエリスイート(.qls)を指定します。

defaultSuiteFile: codeql-suites/cpp-code-scanning.qls とあるので、おそらく、何も指定しなければ、cpp-code-scanning.qls が実行される(つまり、標準クエリ)、ということだと思います。

c-cpp の他の CodeQLパックの cpp-allcpp-examples にも、qlpack.yml があって、内容を確認しましたが、defaultSuitedefaultSuiteFile という記述はありませんでした。

---
library: false
warnOnImplicitThis: true
compileForOverlayEval: false
name: codeql/cpp-queries
version: 1.4.2
buildMetadata:
  sha: 4d681f05bd671f8b5e31624f16a2b4d75e61c071
  cliVersion: 2.22.0
dependencies:
  codeql/cpp-all: 5.1.0
  codeql/suite-helpers: 1.0.25
  codeql/util: 2.0.12
suites: codeql-suites
extractor: cpp
groups:
 - cpp
 - queries
defaultSuiteFile: codeql-suites/cpp-code-scanning.qls

よく分かっていませんが、cpp-code-scanning.qls を読む必要がありそうです。

CodeQLクエリスイート

以下のページを見ると、クエリスイートとは、複数のクエリを効率よく指定するためのファイルと理解しました。

cpp-code-scanning.qls の内容を理解するために、以下のページで、クエリスイートの読み方を確認します。

docs.github.com

description は説明です。queries は指定したパス(今回はカレントディレクトリ)を再帰的にスキャンするとあります。apply は指定ファイルを適用する(指定したファイルを展開する)ということのようです。

- description: Standard Code Scanning queries for C and C++
- queries: .
- apply: code-scanning-selectors.yml
  from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml

queries: . なので、cpp-code-scanning.qls と同じフォルダにある qlsファイルが 6個と、exclude-slow-queries.yml が入っています。これらが全て有効ということです。

いや、queries: . は、qlpack.yml が存在する CodeQLパックのルートディレクトリという意味かもしれません。apply で、codeql-suites/exclude-slow-queries.yml が指定されていますが、このパスが、CodeQLパックのルートディレクトリをカレントディレクトリとしたパス指定になっているためです。

メタデータ

cpp-code-scanning.qls を読むには、メタデータについて知る必要があります。

メタデータについては以下です。

codeql.github.com

kind は、アラートクエリなのか、パスクエリなのかを識別します。クエリには、アラートクエリ(kind が problem)とパスクエリ(kind が path-problem)があるようです。まだ、全く分かっていません。

precision とは、真陽性の割合を指定します。low、medium、high、very-high が指定できるようです。

problem.severity は、重要度です。error、warning、recommendation が指定できます。

tags contain は、カテゴリによるグループ分けです。correctness、maintainability、readability、security が指定できるようです。

precision と problem.severity の組み合わせで、そのクエリが有効になるかどうかが決まるようです。リンク先を見てもさっぱり分かりませんでしたが、ひとまず、進めてみます。

cpp-code-scanning.qls

code-scanning-selectors.yml を見ていきます。

想定したより、かなり複雑です。詳細は分かっていませんが、再帰的にスキャンされたクエリの中で、このルールに沿ったものが抽出される、ということだと思います。

- description: Selectors for selecting the Code-Scanning-relevant queries for a language
- include:
    kind:
    - problem
    - path-problem
    - alert
    - path-alert
    precision:
    - high
    - very-high
    problem.severity:
    - error
    - warning
    tags contain:
    - security
- include:
    kind:
    - diagnostic
- include:
    kind:
    - metric
    tags contain:
    - summary
- exclude:
    deprecated: //
- exclude:
    query path:
      - /^experimental\/.*/
      - Metrics/Summaries/FrameworkCoverage.ql
      - /Diagnostics/Internal/.*/
- exclude:
    tags contain:
      - modeleditor
      - modelgenerator

cpp-security-extended.qls

これだけ見ても分からないので、上のクエリスイートの説明のキャプチャより、cpp-security-extended.qls と比較します。

- description: Security-extended queries for C and C++
- queries: .
- apply: security-extended-selectors.yml
  from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml

違いを見ます。code-scanning-selectors.yml が security-extended-selectors.yml に変わってるだけです。

$ diff -upr cpp-code-scanning.qls cpp-security-extended.qls
--- cpp-code-scanning.qls       2025-06-10 03:51:33.000000000 +0900
+++ cpp-security-extended.qls   2025-06-10 03:51:33.000000000 +0900
@@ -1,5 +1,5 @@
-- description: Standard Code Scanning queries for C and C++
+- description: Security-extended queries for C and C++
 - queries: .
-- apply: code-scanning-selectors.yml
+- apply: security-extended-selectors.yml
   from: codeql/suite-helpers
 - apply: codeql-suites/exclude-slow-queries.yml

security-extended-selectors.yml を見ます。

- description: Selectors for selecting the security-extended queries for a language
- include:
    kind:
    - problem
    - path-problem
    precision:
    - high
    - very-high
    tags contain:
    - security
- include:
    kind:
    - problem
    - path-problem
    precision:
    - medium
    problem.severity:
    - error
    - warning
    tags contain:
    - security
- include:
    kind:
    - diagnostic
- include:
    kind:
    - metric
    tags contain:
    - summary
- exclude:
    deprecated: //
- exclude:
    query path:
      - /^experimental\/.*/
      - Metrics/Summaries/FrameworkCoverage.ql
      - /Diagnostics/Internal/.*/
- exclude:
    tags contain:
      - modeleditor
      - modelgenerator

違いを見ます。少し分かりにくいですが、security-extended-selectors.yml の方は、precision に medium も含んでいるところが大きな違いでしょうか。

$ diff -upr code-scanning-selectors.yml security-extended-selectors.yml
--- code-scanning-selectors.yml 2025-06-10 03:53:21.000000000 +0900
+++ security-extended-selectors.yml     2025-06-10 03:53:21.000000000 +0900
@@ -1,13 +1,19 @@
-- description: Selectors for selecting the Code-Scanning-relevant queries for a language
+- description: Selectors for selecting the security-extended queries for a language
 - include:
     kind:
     - problem
     - path-problem
-    - alert
-    - path-alert
     precision:
     - high
     - very-high
+    tags contain:
+    - security
+- include:
+    kind:
+    - problem
+    - path-problem
+    precision:
+    - medium
     problem.severity:
     - error
     - warning

cpp-security-extended.qls を実行してみます。

前回の標準クエリで実行されたクエリ数は 60 でしたが、今回は 97クエリと、37クエリが増えました。クエリのファイル名で比較したところ、cpp-security-extended.qls は、標準クエリの 60クエリを全て含んでいました。つまり、cpp-security-extended.qls は、純粋に 37クエリが追加されたということです。

$ codeql/codeql database analyze db_uaf cpp-security-extended.qls --format csv --output out_uaf_extended.csv
Running queries.
[1/97] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/DoubleFree.ql.
[2/97] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/IncorrectCheckScanf.ql.
[3/97] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Critical/NewFreeMismatch.ql.
(途中割愛)
[95/97] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/ExtractionMetrics.ql.
[96/97] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/MissingIncludes.ql.
[97/97] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/SucceededIncludes.ql.
Shutting down query evaluator.
Interpreting results.
CodeQL scanned 3 out of 3 C/C++ files in this invocation. Typically CodeQL is configured to analyze a single CodeQL language per invocation, so check other invocations to determine overall coverage information.

標準クエリと cpp-security-extended.qls の結果の CSV を比較します。

use_after_free.c は、1件の warning が増えました。ちなみに、標準クエリでは、error しか検出されていませんでした。

$ diff -upr out_uaf.csv out_uaf_extended.csv 
--- out_uaf.csv   2025-06-29 15:30:49.859549168 +0900
+++ out_uaf_extended.csv  2025-07-01 18:50:16.247412372 +0900
@@ -12,3 +12,6 @@
 "Likely overrunning write","Buffer write operations that do not control the length of data written may overflow","error","This 'scanf string argument' operation requires 255 bytes but the destination is only 20 bytes.","/use_after_free_fix.c","98","32","98","41"
 "Likely overrunning write","Buffer write operations that do not control the length of data written may overflow","error","This 'scanf string argument' operation requires 255 bytes but the destination is only 20 bytes.","/use_after_free_fix.c","101","32","101","39"
 "Likely overrunning write","Buffer write operations that do not control the length of data written may overflow","error","This 'scanf string argument' operation requires 255 bytes but the destination is only 20 bytes.","/use_after_free_fix.c","118","36","118","42"
+"Uncontrolled process operation","Using externally controlled strings in a process operation can allow an attacker to execute malicious commands.","warning","The value of this argument may come from [[""value read by scanf""|""relative:///use_after_free.c:128:36:128:42""]] and is being passed to system.","/use_after_free.c","132","28","132","34"
+"Uncontrolled process operation","Using externally controlled strings in a process operation can allow an attacker to execute malicious commands.","warning","The value of this argument may come from [[""value read by scanf""|""relative:///use_after_free_fix.c:118:36:118:42""]] and is being passed to system.","/use_after_free_fix.c","119","28","119","34"
+"Unbounded write","Buffer write operations that do not control the length of data written may overflow.","error","This 'call to strcpy' with input from [[""a command-line argument""|""relative:///heap_overflow.c:7:27:7:30""]] may overflow the destination.","/heap_overflow.c","21","5","21","10"

標準クエリとcpp-security-extended.qlsの違いの深掘り

標準クエリと、cpp-security-extended.qls の違いは、code-scanning-selectors.yml と security-extended-selectors.yml の違いで、これらの違いは、precision が medium と追加で指定されていることだと思いました。

cpp-security-extended.qls を実行したときに、37クエリが増えました。この増えた 37クエリを見て、どこが違うのかを実際にクエリの内容を確認します。

増えた 37クエリのうちの 1つが、CleartextBufferWrite.ql です。以下は、CleartextBufferWrite.ql の先頭のメタデータです。確かに、@precision medium がありました。

/**
 * @name Cleartext storage of sensitive information in buffer
 * @description Storing sensitive information in cleartext can expose it
 *              to an attacker.
 * @kind path-problem
 * @problem.severity warning
 * @security-severity 7.5
 * @precision medium
 * @id cpp/cleartext-storage-buffer
 * @tags security
 *       external/cwe/cwe-312
 */

増えたクエリである CleartextSqliteDatabase.ql も確認しました。こちらも、@precision medium がありました。

precision が medium のクエリを追加する、ということで理解しました。

cpp-security-and-quality.qls

ついでに、cpp-security-and-quality.qls の方も見ていきます。cpp-security-extended.qls のクエリに加えて、保守性、信頼性のクエリが追加されているということです。

cpp-security-and-quality.qls は以下です。

- description: Security-and-quality queries for C and C++
- queries: .
- apply: security-and-quality-selectors.yml
  from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml

違いを見ます。security-extended-selectors.yml が、security-and-quality-selectors.yml に変わっているだけです。

$ diff -upr cpp-security-extended.qls cpp-security-and-quality.qls 
--- cpp-security-extended.qls 2025-06-10 03:51:33.000000000 +0900
+++ cpp-security-and-quality.qls  2025-06-10 03:51:33.000000000 +0900
@@ -1,5 +1,5 @@
-- description: Security-extended queries for C and C++
+- description: Security-and-quality queries for C and C++
 - queries: .
-- apply: security-extended-selectors.yml
+- apply: security-and-quality-selectors.yml
   from: codeql/suite-helpers
 - apply: codeql-suites/exclude-slow-queries.yml

security-and-quality-selectors.yml を見ます。

- description: Selectors for selecting the security-and-quality queries for a language
- include:
    kind:
    - problem
    - path-problem
    precision:
    - high
    - very-high
- include:
    kind:
    - problem
    - path-problem
    precision: medium
    problem.severity:
      - error
      - warning
- include:
    kind:
    - diagnostic
- include:
    kind:
    - metric
    tags contain:
    - summary
- exclude:
    deprecated: //
- exclude:
    query path:
      - /^experimental\/.*/
      - Metrics/Summaries/FrameworkCoverage.ql
      - /Diagnostics/Internal/.*/
- exclude:
    tags contain:
      - modeleditor
      - modelgenerator
      - 'model-generator'

違いを見ます。tags contain はカテゴリ分けらしいですが、security-extended-selectors.yml との差は、tags contain が security が無くなっただけのようです。つまり、tags contain は、何でもよいという条件になったということでしょうか。

$ diff -upr security-extended-selectors.yml security-and-quality-selectors.yml
--- security-extended-selectors.yml   2025-06-10 03:53:21.000000000 +0900
+++ security-and-quality-selectors.yml    2025-06-10 03:53:21.000000000 +0900
@@ -1,4 +1,4 @@
-- description: Selectors for selecting the security-extended queries for a language
+- description: Selectors for selecting the security-and-quality queries for a language
 - include:
     kind:
     - problem
@@ -6,19 +6,14 @@
     precision:
     - high
     - very-high
-    tags contain:
-    - security
 - include:
     kind:
     - problem
     - path-problem
-    precision:
-    - medium
+    precision: medium
     problem.severity:
-    - error
-    - warning
-    tags contain:
-    - security
+      - error
+      - warning
 - include:
     kind:
     - diagnostic
@@ -38,3 +33,4 @@
     tags contain:
       - modeleditor
       - modelgenerator
+      - 'model-generator'

cpp-security-and-quality.qls を実行してみます。

実行されたクエリ数が 97クエリから 181クエリと、84クエリが増えました。クエリのファイル名で比較したところ、cpp-security-and-quality.qls は、cpp-security-extended.qls の 97クエリを含んでいました。つまり、cpp-security-extended.qls は、単純に 84クエリが追加されたということです。

$ codeql/codeql database analyze db_uaf cpp-security-and-quality.qls --format csv --output out_uaf_quality.csv
Running queries.
[1/181] Loaded /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Best Practices/BlockWithTooManyStatements.qlx.
[2/181] Loaded /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Best Practices/ComplexCondition.qlx.
[3/181] Loaded /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Best Practices/Exceptions/AccidentalRethrow.qlx.
(途中割愛)
[179/181] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/ExtractionMetrics.ql.
[180/181] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/MissingIncludes.ql.
[181/181] No need to rerun /home/user/svn/CodeQL/v2.22.0-bundle/codeql/qlpacks/codeql/cpp-queries/1.4.2/Telemetry/SucceededIncludes.ql.
(途中割愛)
Shutting down query evaluator.
Interpreting results.
CodeQL scanned 3 out of 3 C/C++ files in this invocation. Typically CodeQL is configured to analyze a single CodeQL language per invocation, so check other invocations to determine overall coverage information.

cpp-security-extended.qlsとcpp-security-and-quality.qlsの違いの深掘り

先ほどと同じように、cpp-security-extended.qls と cpp-security-and-quality.qls の違いについて、具体的に増えたクエリを見て、確認します。

ちなみに、cpp-security-extended.qls を実行したときに増えたクエリのうち、先ほど確認した 2つのクエリは、どちらも、@tags security となっていました。

cpp-security-and-quality.qls を実行して、増えた 84クエリのうちの 1つが、以下の AccidentalRethrow.ql(の先頭のメタデータ部分)です。

確かに、security は無く、それ以外の 3つのカテゴリに属しているようです。

/**
 * @name Accidental rethrow
 * @description When there is nothing to rethrow, attempting to rethrow an exception will terminate the program.
 * @kind problem
 * @problem.severity warning
 * @precision high
 * @id cpp/rethrow-no-exception
 * @tags reliability
 *       correctness
 *       exceptions
 */

増えたクエリである Adding365DaysPerYear.ql も確認しました。こちらも、tags に security は含まれていませんでした。

cpp-security-extended.qls と cpp-security-and-quality.qls の違いは、tags の条件の違いだった、ということで理解しました。

おわりに

今回は、CodeQL CLI で使われるクエリが、どうやって選ばれているかについて調べてみました。ようやく分かった気がします。

一方で、当初の目標だった Use After Free が検知できなかった理由ですが、実は、標準クエリに、UseAfterFree.ql が含まれていました。もちろん、cpp-security-extended.qls と cpp-security-and-quality.qls にも含まれています。

つまり、UseAfterFree.ql を実行していたにもかかわらず、UAF を検知できなかったということになり、これは、具体的にクエリの内容を見ないと分からないということになりました。

次回は、クエリの内容の理解をしていきます。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。




以上の内容はhttps://daisuke20240310.hatenablog.com/entry/codeql_qlsより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14