Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
3c54816
fix(tests): Now fault tolerance handlers in cpp tests are extern "C"
EmilioCorigliano Apr 16, 2026
226708a
fix(tests): updated the annotations to match what ASPIS wants
EmilioCorigliano Apr 19, 2026
9cc7222
feat(testing): now all the technique combinations are tested for each…
EmilioCorigliano Apr 19, 2026
d8e6cf3
fix(pipeline): update CI/CD to cache llvm build
EmilioCorigliano Apr 20, 2026
fd98afc
test(pipeline): temporarely removed some tests that fail the pipeline
EmilioCorigliano Apr 21, 2026
0206e75
fix(pipeline): updated llvm-build path
EmilioCorigliano Apr 21, 2026
d0a8ab0
feat(REDDI): port REDDI in ASPIS mainline
EmilioCorigliano Mar 2, 2026
d1b4456
feat(REDDI): Duplicate entrypoint in-place and bugfix
EmilioCorigliano Mar 31, 2026
9ca403c
fix(build_system): Now also FDSC and SEDDI have the DUPLICATE_ALL flag
EmilioCorigliano Apr 15, 2026
a06e624
feat(EDDI): Restored possibility to use private error blocks for each…
EmilioCorigliano Apr 16, 2026
67415dc
fix(debug_locations): Fixed findNearestDebugLoc
EmilioCorigliano Apr 16, 2026
28321a5
feat(EDDI): Supporting indirect function calls
EmilioCorigliano Apr 17, 2026
23efda8
fix(EDDI): Handle std::thread class and methods as to exclude from du…
EmilioCorigliano Apr 19, 2026
abed47b
fix(duplicated global variables): Now code is protected against dupli…
osmandagli Apr 26, 2026
d930406
Fix out-of-bounds access in EDDI when searching the second half of th…
osmandagli Apr 26, 2026
24fe95a
fixed the EDDI tries to execute inline assambly and returns NULL
osmandagli Apr 26, 2026
2f07dc8
Added checks for the array, structs, and pointers
osmandagli Apr 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/actions/prepare-llvm-cache/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Prepare LLVM Cache
description: Restore or build the cached LLVM toolchain.

inputs:
llvm-commit:
description: LLVM commit to build.
required: true

runs:
using: composite
steps:

- name: Restore LLVM Repository Cache
id: restore-llvm-project-cache
uses: actions/cache/restore@v4
with:
path: ${{ github.workspace }}/llvm-project/
key: llvm-project-${{ runner.os }}-${{ inputs.llvm-commit }}

- name: Clone LLVM
if: steps.restore-llvm-project-cache.outputs.cache-hit != 'true'
shell: bash
run: |
git clone --filter=blob:none --no-checkout https://github.com/llvm/llvm-project.git llvm-project
cd llvm-project
git fetch --depth 1 origin ${{ inputs.llvm-commit }}
git checkout FETCH_HEAD

- name: Save LLVM Project Cache
if: steps.restore-llvm-project-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/llvm-project/
key: llvm-project-${{ runner.os }}-${{ inputs.llvm-commit }}


- name: Restore LLVM Build Cache
id: restore-llvm-cache
uses: actions/cache/restore@v4
with:
path: ${{ github.workspace }}/llvm-build/
key: llvm-${{ runner.os }}-${{ inputs.llvm-commit }}

- name: Build LLVM
if: steps.restore-llvm-cache.outputs.cache-hit != 'true'
shell: bash
working-directory: ${{ github.workspace }}/llvm-project
run: |
builddir="${{ github.workspace }}/llvm-build/"
cmake -G Ninja \
-B "$builddir" \
-S llvm \
-DLLVM_ENABLE_PROJECTS="clang" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=OFF \
-DLLDB_INCLUDE_TESTS=OFF \
-DLIBCLC_TARGETS_TO_BUILD="RISCV;X86"
cmake --build "$builddir"

- name: Save LLVM Build Cache
if: steps.restore-llvm-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/llvm-build/
key: llvm-${{ runner.os }}-${{ inputs.llvm-commit }}
91 changes: 50 additions & 41 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
name: ASPIS main CI
env:
LLVM_COMMIT: 2078da43e25a4623cab2d0d60decddf709aaea28 # llvmorg-21.1.8
CMAKE_VERSION: 4.3.0
MOLD_LINKER_FLAGS: -fuse-ld=mold
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 10G
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_COMPILERCHECK: content
CCACHE_NOHASHDIR: "true"
on: [push]
jobs:
compile-ASPIS:
Expand All @@ -8,64 +17,64 @@ jobs:
uses: actions/checkout@v4
with:
path: ASPIS
- name: Cache LLVM build
uses: actions/cache@v4
id: llvm-cache

- name: Install system dependencies
run: |
sudo apt update
sudo apt install -y cmake ninja-build build-essential mold curl ca-certificates ccache

- name: Prepare LLVM Cache
uses: ./ASPIS/.github/actions/prepare-llvm-cache
with:
path: /mnt/build/
key: llvm-build-${{ hashFiles('llvm-project/**', 'ASPIS/CMakeLists.txt') }}
restore-keys: |
llvm-build-
- name: Checking out LLVM project
uses: actions/checkout@master
if: steps.llvm-cache.outputs.cache-hit != 'true'
llvm-commit: ${{ env.LLVM_COMMIT }}

- name: Restore ccache
id: restore-ccache
uses: actions/cache/restore@v4
with:
repository: llvm/llvm-project
ref: llvmorg-21.1.8
path: llvm-project
- name: Compiling LLVM
if: steps.llvm-cache.outputs.cache-hit != 'true'
shell: bash
working-directory: ./llvm-project
run: |
builddir="/mnt/build/"
sudo mkdir -p $builddir
sudo chmod 777 $builddir
cmake -G Ninja \
-B "$builddir" \
-S llvm \
-DLLVM_ENABLE_PROJECTS="clang" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=OFF \
-DLLDB_INCLUDE_TESTS=OFF \
-DLIBCLC_TARGETS_TO_BUILD="RISCV;X86"
cmake --build "$builddir"
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ runner.os }}-${{ github.ref_name }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}-${{ github.sha }}
restore-keys: |
ccache-${{ runner.os }}-${{ github.ref_name }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}-
ccache-${{ runner.os }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}-

- name: Compiling ASPIS
shell: bash
working-directory: ./ASPIS
working-directory: ${{ github.workspace }}/ASPIS
run: |
mkdir build
cmake -B build -DLLVM_DIR=/mnt/build/lib/cmake/llvm/
cmake --build build
ccache --set-config=max_size=${CCACHE_MAXSIZE}
ccache --zero-stats
ccache --show-config
ccache --show-stats

mkdir build
cmake -B build -DLLVM_DIR=${{ github.workspace }}/llvm-build/lib/cmake/llvm/
cmake --build build

- name: Save ccache
if: steps.build-llvm.outcome == 'success' && steps.restore-ccache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ runner.os }}-${{ github.ref_name }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}-${{ github.sha }}

- name: Cache pip
uses: actions/cache@v4
id: pip-cache
with:
path: ~/.cache/pip
key: pip-${{ hashFiles('ASPIS/testing/requirements.txt') }}
key: pip-${{ hashFiles('${{ github.workspace }}/ASPIS/testing/requirements.txt') }}
restore-keys: |
pip-
- name: Install Python requirements
shell: bash
if: steps.llvm-cache.outputs.cache-hit != 'true'
working-directory: ./ASPIS/testing
if: steps.restore-ccache.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/ASPIS/testing
run: |
pip install -r requirements.txt
- name: Testing ASPIS
shell: bash
working-directory: ./ASPIS/testing
working-directory: ${{ github.workspace }}/ASPIS/testing
run: |
pytest test.py --tests-file config/tests.toml
pytest test.py --tests-file config/racfed+eddi.toml
pytest test.py --tests-file config/racfed.toml
pytest test.py

7 changes: 7 additions & 0 deletions aspis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ parse_commands() {

Hardening mechanism:
--eddi (Default) Enable EDDI.
--reddi Enable Recursive-EDDI.
--seddi Enable Selective-EDDI.
--fdsc Enable Full Duplication with Selective Checking.
--no-dup Completely disable data duplication.
Expand Down Expand Up @@ -201,6 +202,9 @@ EOF
--eddi)
dup=0
;;
--reddi)
dup=3
;;
--seddi)
dup=1
;;
Expand Down Expand Up @@ -366,6 +370,9 @@ run_aspis() {
2)
exe $OPT -load-pass-plugin=$DIR/build/passes/libFDSC.so --passes="eddi-verify" $build_dir/out.ll -o $build_dir/out.ll $eddi_options
;;
3)
exe $OPT -load-pass-plugin=$DIR/build/passes/libREDDI.so --passes="eddi-verify" $build_dir/out.ll -o $build_dir/out.ll $eddi_options
;;
*)
echo -e "\t--no-dup specified!"
esac
Expand Down
31 changes: 24 additions & 7 deletions passes/ASPIS.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/Pass.h"
#include <llvm/IR/Instructions.h>
#include "Utils/Utils.h"
#include <map>
#include <set>

Expand Down Expand Up @@ -33,28 +34,44 @@ class EDDI : public PassInfoMixin<EDDI> {
std::set<Function*> CompiledFuncs;
std::map<Value*, StringRef> FuncAnnotations;
std::set<Function*> OriginalFunctions;

std::set<Instruction *> InstructionsToRemove;
std::set<Function*> toHardenConstructors;
std::set<Function*> toHardenFunctions;
std::set<Value*> toHardenVariables;
std::set<Value*> DuplicatedCalls;

std::string entryPoint;

// Map of <original, duplicate> for which we need to always use the duplicate in place of the original
std::map<Value*, Value*> ValuesToAlwaysDup;
LinkageMap linkageMap;

bool duplicateAll;
bool MultipleErrBBEnabled;

void preprocess(Module &Md);
void fixDuplicatedConstructors(Module &Md);
std::set<Function *> getVirtualMethodsFromConstructor(Function *Fn);
int isUsedByStore(Instruction &I, Instruction &Use);
Instruction* cloneInstr(Instruction &I, std::map<Value *, Value *> &DuplicatedInstructionMap);
void duplicateOperands (Instruction &I, std::map<Value *, Value *> &DuplicatedInstructionMap, BasicBlock &ErrBB);
Value* getPtrFinalValue(Value &V);
Value* comparePtrs(Value &V1, Value &V2, IRBuilder<> &B);
void addConsistencyChecks(Instruction &I, std::map<Value *, Value *> &DuplicatedInstructionMap, BasicBlock &ErrBB);
void fixFuncValsPassedByReference(Instruction &I, std::map<Value *, Value *> &DuplicatedInstructionMap, IRBuilder<> &B);
int transformCallBaseInst(CallBase *CInstr, std::map<Value *, Value *> &DuplicatedInstructionMap, IRBuilder<> &B, BasicBlock &ErrBB) ;
Function *getFunctionDuplicate(Function *Fn);
Function *getFunctionFromDuplicate(Function *Fn);
Constant *duplicateConstant(Constant *C, std::map<Value *, Value *> &DuplicatedInstructionMap);
void duplicateGlobals(Module &Md, std::map<Value *, Value *> &DuplicatedInstructionMap);
void duplicateGlobals (Module &Md, std::map<Value *, Value *> &DuplicatedInstructionMap);
bool isAllocaForExceptionHandling(AllocaInst &I);
int transformCallBaseInst(CallBase *CInstr, std::map<Value *, Value *> &DuplicatedInstructionMap, IRBuilder<> &B, BasicBlock &ErrBB);
int duplicateInstruction(Instruction &I, std::map<Value *, Value *> &DuplicatedInstructionMap, BasicBlock &ErrBB);
int duplicateInstruction (Instruction &I, std::map<Value *, Value *> &DuplicatedInstructionMap, BasicBlock &ErrBB);
bool isValueDuplicated(std::map<Value *, Value *> &DuplicatedInstructionMap, Instruction &V);
Function *duplicateFnArgs(Function &Fn, Module &Md, std::map<Value *, Value *> &DuplicatedInstructionMap);
void CreateErrBB(Module &Md, Function &Fn, BasicBlock *ErrBB);

void fixGlobalCtors(Module &M);
public:
explicit EDDI(bool duplicateAll, bool MultipleErrBBEnabled = false, std::string entryPoint = "main") : duplicateAll(duplicateAll), MultipleErrBBEnabled(MultipleErrBBEnabled), entryPoint(entryPoint) {}

PreservedAnalyses run(Module &M,
ModuleAnalysisManager &);

Expand Down Expand Up @@ -118,7 +135,7 @@ class CFCSS : public PassInfoMixin<CFCSS> {
const std::map<BasicBlock *, int> &BBSigs,
std::map<int, BasicBlock *> *NewBBs,
BasicBlock &ErrBB,
Value *G, Value *D);
Value *G, Value *D, int NeighborSig);

public:
PreservedAnalyses run(Module &M,
Expand Down
Loading