Skip to content

Commit bb9de5b

Browse files
Add CodeQL scanner configuration (#3167)
Borrowing from the Arduiino-ESP32
1 parent b0bc62b commit bb9de5b

File tree

3 files changed

+251
-0
lines changed

3 files changed

+251
-0
lines changed

.github/codeql/codeql-config.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: "CodeQL config"
2+
3+
packs:
4+
- trailofbits/cpp-queries
5+
- githubsecuritylab/codeql-cpp-queries
6+
- githubsecuritylab/codeql-python-queries
7+
8+
queries:
9+
- uses: security-extended
10+
- uses: security-and-quality
11+
12+
query-filters:
13+
- exclude:
14+
query path:
15+
- /^experimental\/.*/
16+
- exclude:
17+
tags contain:
18+
- experimental
19+
- exclude:
20+
problem.severity:
21+
- recommendation
22+
- exclude:
23+
id: tob/cpp/use-of-legacy-algorithm # We use legacy algorithms in many places for integrity checks
24+
- exclude:
25+
id: cpp/dead-code-goto # Too many false positives in no-build mode
26+
27+
paths-ignore:
28+
- tests/**

.github/scripts/process_sarif.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/usr/bin/env python3
2+
3+
# This script is used to process the SARIF file generated by CodeQL and
4+
# to rename files back to .ino and adjust line numbers to match the original .ino files.
5+
6+
import json
7+
import sys
8+
import os
9+
10+
def process_artifact_location(artifact_location, renamed_files):
11+
"""
12+
Process a single artifact location to rename .cpp files back to .ino
13+
"""
14+
if 'uri' in artifact_location:
15+
uri = artifact_location['uri']
16+
if uri in renamed_files:
17+
print(f"Renaming file: {uri} -> {renamed_files[uri]}")
18+
artifact_location['uri'] = renamed_files[uri]
19+
return True
20+
return False
21+
22+
def process_region(region):
23+
"""
24+
Adjust line numbers in a region by decreasing them by 1
25+
"""
26+
if 'startLine' in region:
27+
region['startLine'] = max(1, region['startLine'] - 1)
28+
if 'endLine' in region:
29+
region['endLine'] = max(1, region['endLine'] - 1)
30+
31+
def process_physical_location(physical_location, renamed_files):
32+
"""
33+
Process a physical location to rename files and adjust line numbers
34+
"""
35+
file_renamed = False
36+
37+
if 'artifactLocation' in physical_location:
38+
if process_artifact_location(physical_location['artifactLocation'], renamed_files):
39+
file_renamed = True
40+
41+
# Adjust line numbers if the file was renamed
42+
if file_renamed and 'region' in physical_location:
43+
process_region(physical_location['region'])
44+
45+
return file_renamed
46+
47+
48+
def process_sarif_file(sarif_file, renamed_files_file):
49+
"""
50+
Process SARIF file to rename files back to .ino and adjust line numbers
51+
"""
52+
# Read the renamed files mapping
53+
with open(renamed_files_file, 'r') as f:
54+
renamed_files = json.load(f)
55+
56+
print(f"Loaded {len(renamed_files)} file mappings:")
57+
for cpp_file, ino_file in renamed_files.items():
58+
print(f" {cpp_file} -> {ino_file}")
59+
60+
61+
# Read the SARIF file
62+
with open(sarif_file, 'r') as f:
63+
sarif_data = json.load(f)
64+
65+
files_processed = 0
66+
67+
# Process each run
68+
if 'runs' in sarif_data:
69+
for run in sarif_data['runs']:
70+
# Process results
71+
if 'results' in run:
72+
for result in run['results']:
73+
# Process all locations in the result
74+
if 'locations' in result:
75+
for location in result['locations']:
76+
if 'physicalLocation' in location:
77+
if process_physical_location(location['physicalLocation'], renamed_files):
78+
files_processed += 1
79+
80+
# Process related locations if they exist
81+
if 'relatedLocations' in result:
82+
for location in result['relatedLocations']:
83+
if 'physicalLocation' in location:
84+
if process_physical_location(location['physicalLocation'], renamed_files):
85+
files_processed += 1
86+
87+
# Process artifacts if they exist
88+
if 'artifacts' in run:
89+
for artifact in run['artifacts']:
90+
if 'location' in artifact and 'uri' in artifact['location']:
91+
uri = artifact['location']['uri']
92+
if uri in renamed_files:
93+
artifact['location']['uri'] = renamed_files[uri]
94+
files_processed += 1
95+
96+
print(f"Processed {files_processed} file references")
97+
98+
# Write the processed SARIF file
99+
with open(sarif_file, 'w') as f:
100+
json.dump(sarif_data, f, indent=2)
101+
102+
def main():
103+
if len(sys.argv) != 3:
104+
print("Usage: python3 sarif_nobuild.py <sarif_file> <renamed_files_file>")
105+
sys.exit(1)
106+
107+
sarif_file = sys.argv[1]
108+
renamed_files_file = sys.argv[2]
109+
110+
# Check if files exist
111+
if not os.path.exists(sarif_file):
112+
print(f"SARIF file not found: {sarif_file}")
113+
sys.exit(1)
114+
115+
if not os.path.exists(renamed_files_file):
116+
print(f"Renamed files mapping not found: {renamed_files_file}")
117+
sys.exit(1)
118+
119+
try:
120+
process_sarif_file(sarif_file, renamed_files_file)
121+
print("SARIF file processed successfully")
122+
except Exception as e:
123+
print(f"Error processing SARIF file: {e}")
124+
import traceback
125+
traceback.print_exc()
126+
sys.exit(1)
127+
128+
if __name__ == "__main__":
129+
main()

.github/workflows/codeql.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: CodeQL Analysis
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- master
8+
pull_request:
9+
paths:
10+
- "**/*.c"
11+
- "**/*.cpp"
12+
- "**/*.h"
13+
- "**/*.ino"
14+
- "**/*.py"
15+
- ".github/workflows/*.yml"
16+
- ".github/workflows/*.yaml"
17+
18+
permissions:
19+
actions: read
20+
contents: read
21+
pull-requests: read
22+
security-events: write
23+
24+
jobs:
25+
codeql-analysis:
26+
name: CodeQL ${{ matrix.language }} analysis
27+
runs-on: ubuntu-latest
28+
strategy:
29+
matrix:
30+
language: [python, actions, cpp]
31+
32+
steps:
33+
- name: Checkout repository
34+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
35+
36+
- name: Process .ino files
37+
if: matrix.language == 'cpp'
38+
run: |
39+
# Create a mapping file to track renamed files
40+
echo "{}" > renamed_files.json
41+
42+
# Find all .ino files and process them
43+
find . -name "*.ino" -type f | while read -r file; do
44+
echo "Processing $file"
45+
46+
# Get the relative path from repository root
47+
rel_path=$(realpath --relative-to=. "$file")
48+
cpp_path="${rel_path%.ino}.cpp"
49+
50+
# Create new .cpp file with Arduino.h include
51+
echo "#include <Arduino.h>" > "$cpp_path"
52+
53+
# Append the original content
54+
cat "$file" >> "$cpp_path"
55+
56+
# Update the mapping file
57+
jq --arg ino "$rel_path" --arg cpp "$cpp_path" '. += {($cpp): $ino}' renamed_files.json > temp.json && mv temp.json renamed_files.json
58+
59+
# Remove the original .ino file
60+
rm "$file"
61+
62+
echo "Converted $file to $cpp_path"
63+
done
64+
65+
echo "Renamed files mapping:"
66+
cat renamed_files.json
67+
68+
- name: Initialize CodeQL
69+
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
70+
with:
71+
build-mode: none
72+
languages: ${{ matrix.language }}
73+
config-file: ./.github/codeql/codeql-config.yml
74+
75+
- name: Run CodeQL Analysis
76+
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
77+
with:
78+
category: "/language:${{ matrix.language }}"
79+
output: sarif-results
80+
upload: failure-only
81+
82+
- name: Process SARIF file
83+
if: matrix.language == 'cpp'
84+
run: |
85+
sarif_file="sarif-results/${{ matrix.language }}.sarif"
86+
87+
# Run the Python script to process the SARIF file
88+
python3 .github/scripts/process_sarif.py "$sarif_file" "renamed_files.json"
89+
90+
- name: Upload SARIF file
91+
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
92+
with:
93+
sarif_file: sarif-results/${{ matrix.language }}.sarif
94+
category: "/language:${{ matrix.language }}"

0 commit comments

Comments
 (0)