mirror of
https://github.com/lifting-bits/sleigh
synced 2026-06-21 13:56:12 +00:00
Add ASAN/UBSAN CI testing and fix signed left shift UB
Add a sanitizer CI job that builds and tests with AddressSanitizer and UndefinedBehaviorSanitizer using clang on Ubuntu for both stable and HEAD release tracks. Fix three UBSAN signed left shift errors found during sanitizer testing by casting signed values to unsigned before left shifting: - address.hh sign_extend(): left shift of negative value / overflow - slghpatexpress.cc LeftShiftExpression: left shift of negative value Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -254,3 +254,94 @@ jobs:
|
||||
|
||||
- name: ccache stats
|
||||
run: ccache -s
|
||||
|
||||
sanitizer:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CXX: clang++
|
||||
ASAN_OPTIONS: strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=1
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
release: [stable, HEAD]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Git User for Applying Patches
|
||||
run: |
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ccache
|
||||
|
||||
- name: Generate cache key
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CACHE_KEY=sanitizer_${{ matrix.release }}\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CACHE_TIMESTAMP=${current_date}\n")
|
||||
|
||||
- name: Update the cache (ccache)
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: "${{ github.workspace }}/ccache"
|
||||
key: ${{ env.CACHE_KEY }}_ccache_${{ env.CACHE_TIMESTAMP }}
|
||||
restore-keys: |
|
||||
${{ env.CACHE_KEY }}_ccache_
|
||||
|
||||
- name: Setup ccache
|
||||
working-directory: "${{ github.workspace }}"
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ccache")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_BASEDIR=${CMAKE_CURRENT_SOURCE_DIR}\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/ccache\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESS=true\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_COMPRESSLEVEL=10\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CCACHE_MAXSIZE=400M\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_CXX_COMPILER_LAUNCHER=ccache\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "CMAKE_C_COMPILER_LAUNCHER=ccache\n")
|
||||
execute_process(COMMAND ccache -z)
|
||||
|
||||
- name: Configure the project
|
||||
run: cmake --preset=ci-sanitize
|
||||
-Dsleigh_RELEASE_TYPE=${{ matrix.release }}
|
||||
-Dsleigh_BUILD_DOCUMENTATION=OFF
|
||||
|
||||
- name: Build the project
|
||||
run: cmake
|
||||
--build build/sanitize
|
||||
-j 4
|
||||
-v
|
||||
|
||||
- name: Test the project
|
||||
working-directory: build/sanitize
|
||||
run: ctest -VV
|
||||
|
||||
- name: Run the example
|
||||
run: cmake
|
||||
--build build/sanitize
|
||||
-j 4
|
||||
--target sleigh_example_runner
|
||||
|
||||
- name: Run the install target
|
||||
run: cmake --install build/sanitize
|
||||
--prefix install
|
||||
|
||||
- name: Smoketest sleigh lift
|
||||
run: |
|
||||
./install/bin/sleigh-lift --version
|
||||
./install/bin/sleigh-lift disassemble x86-64.sla 4881ecc00f0000
|
||||
./install/bin/sleigh-lift pcode x86-64.sla 4881ecc00f0000
|
||||
|
||||
- name: ccache stats
|
||||
run: ccache -s
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From 8afa7d89a368b358a5493b87804985ed9ac70a2f Mon Sep 17 00:00:00 2001
|
||||
From: "github-actions[bot]"
|
||||
<41898282+github-actions[bot]@users.noreply.github.com>
|
||||
Date: Wed, 25 Feb 2026 20:41:10 +0000
|
||||
Subject: [PATCH] Fix UBSAN signed left shift errors
|
||||
|
||||
Cast signed values to unsigned before left shifting to avoid undefined
|
||||
behavior when the signed value is negative or when the result cannot be
|
||||
represented in the signed type.
|
||||
|
||||
Fixes runtime errors detected by UndefinedBehaviorSanitizer:
|
||||
- address.hh sign_extend(): left shift of negative value
|
||||
- address.hh sign_extend(): left shift cannot be represented in type 'intb'
|
||||
- slghpatexpress.cc LeftShiftExpression: left shift of negative value
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/address.hh | 2 +-
|
||||
.../Features/Decompiler/src/decompile/cpp/slghpatexpress.cc | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
|
||||
index 45144daf3..0e75c68b8 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
|
||||
@@ -544,7 +544,7 @@ inline intb sign_extend(intb val,int4 bit)
|
||||
|
||||
{
|
||||
int4 sa = 8*sizeof(intb) - (bit+1);
|
||||
- val = (val << sa) >> sa;
|
||||
+ val = static_cast<intb>(static_cast<uintb>(val) << sa) >> sa;
|
||||
return val;
|
||||
}
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
|
||||
index 941097859..93cce378a 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
|
||||
@@ -969,7 +969,7 @@ intb LeftShiftExpression::getValue(ParserWalker &walker) const
|
||||
{
|
||||
intb leftval = getLeft()->getValue(walker);
|
||||
intb rightval = getRight()->getValue(walker);
|
||||
- return leftval << rightval;
|
||||
+ return static_cast<intb>(static_cast<uintb>(leftval) << rightval);
|
||||
}
|
||||
|
||||
intb LeftShiftExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
|
||||
@@ -977,7 +977,7 @@ intb LeftShiftExpression::getSubValue(const vector<intb> &replace,int4 &listpos)
|
||||
{
|
||||
intb leftval = getLeft()->getSubValue(replace,listpos); // Must be left first
|
||||
intb rightval = getRight()->getSubValue(replace,listpos);
|
||||
- return leftval << rightval;
|
||||
+ return static_cast<intb>(static_cast<uintb>(leftval) << rightval);
|
||||
}
|
||||
|
||||
void LeftShiftExpression::encode(Encoder &encoder) const
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From 8afa7d89a368b358a5493b87804985ed9ac70a2f Mon Sep 17 00:00:00 2001
|
||||
From: "github-actions[bot]"
|
||||
<41898282+github-actions[bot]@users.noreply.github.com>
|
||||
Date: Wed, 25 Feb 2026 20:41:10 +0000
|
||||
Subject: [PATCH] Fix UBSAN signed left shift errors
|
||||
|
||||
Cast signed values to unsigned before left shifting to avoid undefined
|
||||
behavior when the signed value is negative or when the result cannot be
|
||||
represented in the signed type.
|
||||
|
||||
Fixes runtime errors detected by UndefinedBehaviorSanitizer:
|
||||
- address.hh sign_extend(): left shift of negative value
|
||||
- address.hh sign_extend(): left shift cannot be represented in type 'intb'
|
||||
- slghpatexpress.cc LeftShiftExpression: left shift of negative value
|
||||
---
|
||||
Ghidra/Features/Decompiler/src/decompile/cpp/address.hh | 2 +-
|
||||
.../Features/Decompiler/src/decompile/cpp/slghpatexpress.cc | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
|
||||
index 45144daf3..0e75c68b8 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
|
||||
@@ -544,7 +544,7 @@ inline intb sign_extend(intb val,int4 bit)
|
||||
|
||||
{
|
||||
int4 sa = 8*sizeof(intb) - (bit+1);
|
||||
- val = (val << sa) >> sa;
|
||||
+ val = static_cast<intb>(static_cast<uintb>(val) << sa) >> sa;
|
||||
return val;
|
||||
}
|
||||
|
||||
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
|
||||
index 941097859..93cce378a 100644
|
||||
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
|
||||
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
|
||||
@@ -969,7 +969,7 @@ intb LeftShiftExpression::getValue(ParserWalker &walker) const
|
||||
{
|
||||
intb leftval = getLeft()->getValue(walker);
|
||||
intb rightval = getRight()->getValue(walker);
|
||||
- return leftval << rightval;
|
||||
+ return static_cast<intb>(static_cast<uintb>(leftval) << rightval);
|
||||
}
|
||||
|
||||
intb LeftShiftExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
|
||||
@@ -977,7 +977,7 @@ intb LeftShiftExpression::getSubValue(const vector<intb> &replace,int4 &listpos)
|
||||
{
|
||||
intb leftval = getLeft()->getSubValue(replace,listpos); // Must be left first
|
||||
intb rightval = getRight()->getSubValue(replace,listpos);
|
||||
- return leftval << rightval;
|
||||
+ return static_cast<intb>(static_cast<uintb>(leftval) << rightval);
|
||||
}
|
||||
|
||||
void LeftShiftExpression::encode(Encoder &encoder) const
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@@ -43,6 +43,7 @@ set(ghidra_patches
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0003-Ignore-floating-point-test-due-to-compilation-differ.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0004-Allow-positive-or-negative-NAN-in-decompiler-floatin.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0005-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/stable/0006-Fix-UBSAN-signed-left-shift-errors.patch"
|
||||
)
|
||||
|
||||
# Ghidra pinned commits used for pinning last known working HEAD commit
|
||||
@@ -65,6 +66,7 @@ if("${sleigh_RELEASE_TYPE}" STREQUAL "HEAD")
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0005-decompiler-Fix-strict-weak-ordering-TypePartialEnum.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0006-decompiler-Fix-strict-weak-ordering-PullRecord.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0007-decompiler-Fix-strict-weak-ordering-compareFinalOrde.patch"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/HEAD/0008-Fix-UBSAN-signed-left-shift-errors.patch"
|
||||
)
|
||||
string(SUBSTRING "${ghidra_git_tag}" 0 7 ghidra_short_commit)
|
||||
else()
|
||||
|
||||
Reference in New Issue
Block a user