From 6b0e25a11c7c1c3b12d4c52923712fc5b0114fe1 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdh8d@virginia.edu> Date: Sat, 16 Feb 2019 18:47:55 -0500 Subject: [PATCH] removed cfi Former-commit-id: 608b5a7fbd65a0b622b976db1fa0687b74bd85d8 --- .gitlab-ci.yml | 100 +- SConscript | 13 +- tools/selective_cfi/Makefile.in | 42 - tools/selective_cfi/SConscript | 39 - tools/selective_cfi/SConstruct | 7 - tools/selective_cfi/color_map.cpp | 107 -- tools/selective_cfi/color_map.hpp | 143 -- tools/selective_cfi/scfi_driver.cpp | 275 --- tools/selective_cfi/scfi_instr.cpp | 1597 ----------------- tools/selective_cfi/scfi_instr.hpp | 208 --- tools/selective_cfi/tests/cfi_all_configs.sh | 444 ----- .../tests/cfi_smokescreen_configs.sh | 64 - .../tests/cicd_tests/fib_src/fib.c | 53 - .../tests/cicd_tests/fib_src/libfib.c | 32 - .../tests/cicd_tests/fib_src/libfib2.c | 18 - .../tests/cicd_tests/foo_src/foo.c | 14 - .../tests/cicd_tests/foo_src/libfoo.c | 14 - tools/selective_cfi/tests/manual_tests/dude.c | 14 - tools/selective_cfi/tests/manual_tests/fib.c | 53 - tools/selective_cfi/tests/manual_tests/foo.c | 14 - .../tests/manual_tests/libc_driver.c | 6 - .../tests/manual_tests/libdude.c | 8 - .../selective_cfi/tests/manual_tests/libfib.c | 32 - .../tests/manual_tests/libfib2.c | 18 - .../selective_cfi/tests/manual_tests/libfoo.c | 14 - tools/selective_cfi/tests/manual_tests/pow.c | 19 - .../tests/manual_tests/test_coreutils.sh | 234 --- .../tests/manual_tests/test_dude.sh | 118 -- .../tests/manual_tests/test_fib.sh | 121 -- .../tests/manual_tests/test_foo.sh | 119 -- .../tests/manual_tests/test_libc.sh | 99 - .../tests/manual_tests/test_pow.sh | 108 -- .../tests/manual_tests/test_spec.sh | 190 -- .../selective_cfi/zest_cfi_runtime/SConscript | 5 - .../zest_cfi_runtime/SConscript32 | 35 - .../zest_cfi_runtime/SConscript64 | 35 - .../selective_cfi/zest_cfi_runtime/SConstruct | 7 - .../selective_cfi/zest_cfi_runtime/dispatch.c | 205 --- .../zest_cfi_runtime/dl_iterate.c | 166 -- .../selective_cfi/zest_cfi_runtime/ldsodefs.h | 1059 ----------- .../zest_cfi_runtime/zest_dispatch64.s | 102 -- 41 files changed, 56 insertions(+), 5895 deletions(-) delete mode 100644 tools/selective_cfi/Makefile.in delete mode 100644 tools/selective_cfi/SConscript delete mode 100644 tools/selective_cfi/SConstruct delete mode 100644 tools/selective_cfi/color_map.cpp delete mode 100644 tools/selective_cfi/color_map.hpp delete mode 100644 tools/selective_cfi/scfi_driver.cpp delete mode 100644 tools/selective_cfi/scfi_instr.cpp delete mode 100644 tools/selective_cfi/scfi_instr.hpp delete mode 100755 tools/selective_cfi/tests/cfi_all_configs.sh delete mode 100755 tools/selective_cfi/tests/cfi_smokescreen_configs.sh delete mode 100644 tools/selective_cfi/tests/cicd_tests/fib_src/fib.c delete mode 100644 tools/selective_cfi/tests/cicd_tests/fib_src/libfib.c delete mode 100644 tools/selective_cfi/tests/cicd_tests/fib_src/libfib2.c delete mode 100644 tools/selective_cfi/tests/cicd_tests/foo_src/foo.c delete mode 100644 tools/selective_cfi/tests/cicd_tests/foo_src/libfoo.c delete mode 100644 tools/selective_cfi/tests/manual_tests/dude.c delete mode 100644 tools/selective_cfi/tests/manual_tests/fib.c delete mode 100644 tools/selective_cfi/tests/manual_tests/foo.c delete mode 100644 tools/selective_cfi/tests/manual_tests/libc_driver.c delete mode 100644 tools/selective_cfi/tests/manual_tests/libdude.c delete mode 100644 tools/selective_cfi/tests/manual_tests/libfib.c delete mode 100644 tools/selective_cfi/tests/manual_tests/libfib2.c delete mode 100644 tools/selective_cfi/tests/manual_tests/libfoo.c delete mode 100644 tools/selective_cfi/tests/manual_tests/pow.c delete mode 100755 tools/selective_cfi/tests/manual_tests/test_coreutils.sh delete mode 100755 tools/selective_cfi/tests/manual_tests/test_dude.sh delete mode 100755 tools/selective_cfi/tests/manual_tests/test_fib.sh delete mode 100755 tools/selective_cfi/tests/manual_tests/test_foo.sh delete mode 100755 tools/selective_cfi/tests/manual_tests/test_libc.sh delete mode 100755 tools/selective_cfi/tests/manual_tests/test_pow.sh delete mode 100755 tools/selective_cfi/tests/manual_tests/test_spec.sh delete mode 100644 tools/selective_cfi/zest_cfi_runtime/SConscript delete mode 100644 tools/selective_cfi/zest_cfi_runtime/SConscript32 delete mode 100644 tools/selective_cfi/zest_cfi_runtime/SConscript64 delete mode 100644 tools/selective_cfi/zest_cfi_runtime/SConstruct delete mode 100644 tools/selective_cfi/zest_cfi_runtime/dispatch.c delete mode 100644 tools/selective_cfi/zest_cfi_runtime/dl_iterate.c delete mode 100644 tools/selective_cfi/zest_cfi_runtime/ldsodefs.h delete mode 100644 tools/selective_cfi/zest_cfi_runtime/zest_dispatch64.s diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1e3c65aaf..9ec0942b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -151,31 +151,31 @@ xform-cat-centos75: # # template -.test_foo: &test_foo - stage: test - script: - - ./cicd_tests/test_foo.sh - -test_foo-ubuntu18: - <<: *test_foo - tags: - - ubuntu18 - variables: - OS: 'ubuntu18' - -test_foo-ubuntu16: - <<: *test_foo - tags: - - ubuntu16 - variables: - OS: 'ubuntu16' - -test_foo-ubuntu16: - <<: *test_foo - tags: - - centos75 - variables: - OS: 'centos75' +#.test_foo: &test_foo +# stage: test +# script: +# - ./cicd_tests/test_foo.sh +# +#test_foo-ubuntu18: +# <<: *test_foo +# tags: +# - ubuntu18 +# variables: +# OS: 'ubuntu18' +# +#test_foo-ubuntu16: +# <<: *test_foo +# tags: +# - ubuntu16 +# variables: +# OS: 'ubuntu16' +# +#test_foo-ubuntu16: +# <<: *test_foo +# tags: +# - centos75 +# variables: +# OS: 'centos75' # @@ -183,31 +183,31 @@ test_foo-ubuntu16: # # template -.test_fib: &test_fib - stage: test - script: - - ./cicd_tests/test_fib.sh - -test_fib-ubuntu16: - <<: *test_fib - tags: - - ubuntu16 - variables: - OS: 'ubuntu16' - -test_fib-ubuntu18: - <<: *test_fib - tags: - - ubuntu18 - variables: - OS: 'ubuntu18' - -test_fib-centos75: - <<: *test_fib - tags: - - centos75 - variables: - OS: 'centos75' +#.test_fib: &test_fib +# stage: test +# script: +# - ./cicd_tests/test_fib.sh +# +#test_fib-ubuntu16: +# <<: *test_fib +# tags: +# - ubuntu16 +# variables: +# OS: 'ubuntu16' +# +#test_fib-ubuntu18: +# <<: *test_fib +# tags: +# - ubuntu18 +# variables: +# OS: 'ubuntu18' +# +#test_fib-centos75: +# <<: *test_fib +# tags: +# - centos75 +# variables: +# OS: 'centos75' # diff --git a/SConscript b/SConscript index 3163a4a81..22820a5b5 100644 --- a/SConscript +++ b/SConscript @@ -97,11 +97,12 @@ dump_insns=SConscript("dump_insns/SConscript", variant_dir='scons_build/dump_ins ir_builders=SConscript("ir_builders/SConscript", variant_dir='scons_build/ir_builders') -tools=None -if 'build_tools' not in env or env['build_tools'] is None or int(env['build_tools']) == 1: - tools=SConscript("tools/SConscript", variant_dir='scons_build/tools') - if "PEDI_HOME" in os.environ: - Depends(pedi,tools) +# no more tools in irdb-libs +#tools=None +#if 'build_tools' not in env or env['build_tools'] is None or int(env['build_tools']) == 1: +# tools=SConscript("tools/SConscript", variant_dir='scons_build/tools') +# if "PEDI_HOME" in os.environ: +# Depends(pedi,tools) libs=( libIRDBcore, libIRDBcfg, @@ -128,6 +129,4 @@ if "PEDI_HOME" in os.environ: else: Default(libIRDBcore, libIRDBcfg, libIRDButil, libIRDBdeep, libIRDBcore, libehp,libtransform,libEXEIO,libMEDSannotation,libStructDiv,libElfDep, libcapstone, thanos, rida, meds2pdb, dump_map, dump_insns, ir_builders) - if 'build_tools' not in env or env['build_tools'] is None or int(env['build_tools']) == 1: - Default(tools) diff --git a/tools/selective_cfi/Makefile.in b/tools/selective_cfi/Makefile.in deleted file mode 100644 index b91dfaa25..000000000 --- a/tools/selective_cfi/Makefile.in +++ /dev/null @@ -1,42 +0,0 @@ - - -PROGS=selective_cfi.exe - -CXX=@CXX@ -CXXFLAGS= -INCLUDE=-I. -I../include -I../xform -I../../beaengine/include -I../../libIRDB/include/ -I../../libMEDSannotation/include/ -I../libtransform/include/ -I../transforms -CXXFLAGS= @EXTRA_CXXFLAGS@ $(INCLUDE) -LIBS=-L../../lib -lxform -lIRDB-core -lIRDB-cfg -lBeaEngine_s_d -lpqxx -lMEDSannotation -ltransform ../transforms/Rewrite_Utility.o -lpq - - -OBJS=scfi_driver.o scfi_instr.o -programs=selective_cfi.exe - -.SUFFIXES: .o .c .exe .cpp .hpp - -all: $(programs) - @echo "---------------------------------------------" - @echo "- Selective CFI directory -- Build complete -" - @echo "---------------------------------------------" - - --include $(OBJS:.o=.d) - -%.o: %.cpp - $(CXX) -c $(CXXFLAGS) $*.cpp - @# - @# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html - @# - @cpp -MM $(CXXFLAGS) $*.cpp > $*.d 2> /dev/null || true # might fail on solaris with CXX=sun's CC. - @cp -f $*.d $*.d.tmp - @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d - @rm -f $*.d.tmp - -clean: - rm -f *.o core *.exe - -$(programs): ../../lib/*.a - -selective_cfi.exe: $(OBJS) - $(CXX) $(CXXFLAGS) $^ $(INCLUDE) $(LIBS) -o $@ - diff --git a/tools/selective_cfi/SConscript b/tools/selective_cfi/SConscript deleted file mode 100644 index e31c252db..000000000 --- a/tools/selective_cfi/SConscript +++ /dev/null @@ -1,39 +0,0 @@ -import os - - - -Import('env') -myenv=env.Clone() -myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) - -cpppath=''' - $IRDB_SDK/include - $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include - $SECURITY_TRANSFORMS_HOME/libtransform/include - $SECURITY_TRANSFORMS_HOME/libEXEIO/include - ''' - - -files=Glob( Dir('.').srcnode().abspath+"/*.cpp") - -myenv.Append(CXXFLAGS = " -std=c++11 -Wall ") - -pgm="selective_cfi.exe" - -LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-cfg irdb-util irdb-core irdb-transform MEDSannotation ") -myenv=myenv.Clone(CPPPATH=Split(cpppath)) -pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) -install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) -Default(install) - -ret=[]+install - - -#lib32=SConscript("zest_cfi_runtime/SConscript", variant_dir="build32") -if 'ZEST_RUNTIME' in os.environ: - zestcfi_lib=SConscript("zest_cfi_runtime/SConscript") # , variant_dir="build64") - ret=ret+zestcfi_lib -Return('ret') diff --git a/tools/selective_cfi/SConstruct b/tools/selective_cfi/SConstruct deleted file mode 100644 index 44d3bd9e8..000000000 --- a/tools/selective_cfi/SConstruct +++ /dev/null @@ -1,7 +0,0 @@ - - - -env=Environment() -Export('env') -ret=SConscript("SConscript") -Return('ret') diff --git a/tools/selective_cfi/color_map.cpp b/tools/selective_cfi/color_map.cpp deleted file mode 100644 index 587ea2035..000000000 --- a/tools/selective_cfi/color_map.cpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include "color_map.hpp" - -using namespace std; -using namespace IRDB_SDK; - - -bool ColoredInstructionNonces_t::create() -{ - UniqueICFSSet_t unique_icfs; - - assert(firp); - const ICFSSet_t& all_icfs=firp->getAllICFS(); - for(ICFSSet_t::iterator it=all_icfs.begin(); it!=all_icfs.end(); ++it) - { - ICFS_t* p=*it; - assert(p); - unique_icfs.insert( *p ); - } - - ColoredSlotValue_t v; - for(auto the_icfs : unique_icfs) - { - // const ICFS_t& the_icfs=*it; - // const auto the_icfs=*it; - - for(auto slot_no=0U; /* loop until break */ ; slot_no++) - { - // check if we need to allocate a new slot - if(slot_no<slots_used.size()) - { - // skip any slots that are full. - if(!slots_used[slot_no].CanReserve()) - goto next_slot; - } - else - { - // allocate slot - slots_used.push_back(ColoredSlotAllocator_t(slot_no,slot_values)); - } - - // check if any of the targets for this branch already have a slot filled. - for(auto target : the_icfs) - { - if(color_assignments[target][slot_no].IsValid()) - goto next_slot; - } - - // if we get here, the slot is valid for all targets, we can reserve it. - v=slots_used[slot_no].Reserve(); - - // and record the reservation for each target. - slot_assignments[the_icfs]=v; - for(ICFS_t::iterator it2=the_icfs.begin(); it2!=the_icfs.end(); ++it2) - { - Instruction_t* target=*it2; - color_assignments[target][slot_no]=v; - cout<<"Setting slot[-"<<hex<<v.GetPosition()<<"]=color["<<hex<<v.GetNonceValue()<<dec<<"]" - << " for "<<hex<<target->getBaseID()<<":"<<target->getDisassembly() - << endl; - } - - // and we're done with this ICFS - break; - - - // inc the slot no and try again. - next_slot: - // try next; - ; // neded statement for compiler to accept - } - - } - -#if 1 /* debug code */ - UniqueICFSSet_t used_icfs; - for(auto insn : firp->getInstructions()) - { - if(insn->getIBTargets()) - { - v=GetColorOfIB(insn); - cout<<"IB assigned " <<"slot[-"<<v.GetPosition()<<"]=color["<<hex<<v.GetNonceValue()<<dec<<"]" - << " for "<<insn->getBaseID()<<":"<<insn->getDisassembly() << endl; - - used_icfs.insert(*insn->getIBTargets()); - - } - } - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::Unique_Used_ICFS_size="<<dec<<used_icfs.size()<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::Unique_ICFS_size="<<dec<<unique_icfs.size()<<endl; -#endif - - // output stats - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::slots_used="<<slots_used.size()<<endl; - int total_slots = 0; - for(auto slot_no=0U; slot_no<slots_used.size(); slot_no++) - { - cout<<"# Selective_Control_Flow_Integrity::ATTRIBUTE used_slot"<<slot_no<<"="<<slots_used[slot_no].SlotsUsed()<<endl; - total_slots += slots_used[slot_no].SlotsUsed(); - } - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::total_slots="<<total_slots<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::pct_slots_used="<<std::fixed<<((float)slots_used.size()/(float)total_slots)*100.00<<"%"<<endl; - - return true; -} - diff --git a/tools/selective_cfi/color_map.hpp b/tools/selective_cfi/color_map.hpp deleted file mode 100644 index 2f78675d3..000000000 --- a/tools/selective_cfi/color_map.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#ifndef color_map_hpp -#define color_map_hpp - -#include <irdb-core> -#include <stdint.h> - - -typedef uint64_t NonceValueType_t; - -class ColoredSlotValue_t -{ - public: - ColoredSlotValue_t(int np, NonceValueType_t nv) : position(np), nonce_value(nv), valid(true) { }; - ColoredSlotValue_t() : valid(false) {} - - // void SetPosition(int pos) { slot_position=pos; } - int GetPosition() const { return position;} - - // void SetNonceValue(NonceValueType_t p_nv) { nonce_value=p_nv; } - NonceValueType_t const GetNonceValue() { return nonce_value; } - - bool IsValid() const { return valid; } - - private: - int position; - NonceValueType_t nonce_value; - bool valid; -}; - -class ColoredSlotAllocator_t -{ - public: - ColoredSlotAllocator_t(int sn, int mv) : slot_number(sn), used(1), max_value(mv) { } - - bool CanReserve() const { return used < max_value; } - ColoredSlotValue_t Reserve() - { - assert(CanReserve()); - return ColoredSlotValue_t(slot_number, used++); - } - int SlotsUsed() const { return used ; } - - - private: - int slot_number; - NonceValueType_t used; - NonceValueType_t max_value; -}; - -typedef std::map<int,ColoredSlotValue_t> ColoredSlotValues_t; - - -class ColoredInstructionNonces_t -{ - public: - ColoredInstructionNonces_t(IRDB_SDK::FileIR_t *the_firp) - : firp(the_firp), slot_size(1), slot_values(255) { } - ColoredInstructionNonces_t(IRDB_SDK::FileIR_t *the_firp, int the_slot_size) - : firp(the_firp), slot_size(the_slot_size), - slot_values(MaxNonceValForSlotSize(the_slot_size)) { } - ColoredSlotValues_t GetColorsOfIBT (IRDB_SDK::Instruction_t* i) - { return color_assignments[i]; } - - ColoredSlotValue_t GetColorOfIB (IRDB_SDK::Instruction_t* i) - { assert(i->getIBTargets()); return slot_assignments[*i->getIBTargets()]; } - - int NumberSlotsUsed() { return slots_used.size(); } - - bool build() { return create(); } - - private: - - // helper to assign colors to slots. - bool create(); - - // the IR we're working on. - IRDB_SDK::FileIR_t* firp; - - // used to describe how big a nonce slot is. for now, 1 byte. - const int slot_size; - const NonceValueType_t slot_values; - - // information for each slot we've used. - std::vector<ColoredSlotAllocator_t> slots_used; - - // information for each IBT. - // a map for each instruction, which contains a ColorSlotValue_t for each slot used. - // instruction -> ( int-> slot_value ) - std::map<IRDB_SDK::Instruction_t*, ColoredSlotValues_t> color_assignments; - - // information for each IB (as indexed by the IBs ICFS). - // the slot that each IB uses. ICFS_t -> slot_value - std::map<IRDB_SDK::InstructionSet_t, ColoredSlotValue_t> slot_assignments; - - NonceValueType_t MaxNonceValForSlotSize(int slot_size) - { - NonceValueType_t max_nonce_val = ~((NonceValueType_t) 0); - size_t max_nonce_size_bits = sizeof(NonceValueType_t)*8; - size_t slot_size_bits = slot_size*8; - - return max_nonce_val >> (max_nonce_size_bits - slot_size_bits); - } - - -}; - - -// a simple way to sort ICFS. - -class UniqueICFSSetSorter_t; -typedef std::set<IRDB_SDK::InstructionSet_t, UniqueICFSSetSorter_t> UniqueICFSSet_t; - -class UniqueICFSSetSorter_t -{ - public: - bool operator() (const IRDB_SDK::InstructionSet_t& a, const IRDB_SDK::InstructionSet_t& b) const - { - if(a.size() == b.size()) return a<b; - return a.size() < b.size() ; - } -}; - -#endif diff --git a/tools/selective_cfi/scfi_driver.cpp b/tools/selective_cfi/scfi_driver.cpp deleted file mode 100644 index 2e5d79607..000000000 --- a/tools/selective_cfi/scfi_driver.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#include <stdlib.h> -#include <fstream> -#include <irdb-core> -#include <libgen.h> - -#include "scfi_instr.hpp" - -using namespace std; -using namespace IRDB_SDK; - - -#define BINARY_NAME "a.ncexe" -#define SHARED_OBJECTS_DIR "shared_objects" - - -void usage(char* name) -{ - cerr<<" Usage: "<<name<<" <variant_id> \n" -" [--nonce-size [1|2|4|8]] \n" -" [--exe-nonce-size [1|2|4|8]] \n" -" [--color|--no-color] \n" -" [--color-exe-nonces|--no-color-exe-nonces] \n" -" [--protect-jumps|--no-protect-jumps] \n" -" [--protect-calls|--no-protect-calls] \n" -" [--protect-rets|--no-protect-rets] \n" -" [--protect-safefn|--no-protect-safefn] \n" -" [ --common-slow-path | --no-common-slow-path ] \n" -" [ --multimodule | --no-multimodule ] \n" -" [--exe-nonce-for-call|--no-exe-nonce-for-call] \n" -" \n" -"default: --no-color --no-color-exe-nonces --no-protect-jumps --protect-calls --protect-rets --protect-safefn --common-slow-path --no-multimodule --no-exe-nonce-for-call --nonce-size 1 --exe-nonce-size 4\n"; -} - -int main(int argc, char **argv) -{ - if(argc < 2) - { - usage(argv[0]); - exit(1); - } - -#if 0 -// CFI step is asserting with error message if a call is found. - if(!getenv("FIX_CALLS_FIX_ALL_CALLS")) - { - cerr<<"FIX_CALLS_FIX_ALL_CALLS should be set."<<endl; - exit(1); - } -#endif - - bool do_coloring=false; - bool do_color_exe_nonces=false; - bool do_common_slow_path=true; - bool do_jumps=false; // do_jumps=true will cause failures b/c registers stay live over ind jumps - bool do_calls=true; - bool do_rets=true; - bool do_safefn=true; - bool do_multimodule=false; - bool do_exe_nonce_for_call=false; - int nonce_size=1; - int exe_nonce_size=4; - for(int i=2;i<argc;i++) - { - if(string(argv[i])=="--nonce-size" && - string(argv[i+1]).length()==1 && isdigit(string(argv[i+1])[0])) - { - nonce_size = stoi(string(argv[i+1])); - if(!(nonce_size == 1 || nonce_size == 2 || nonce_size == 4 || nonce_size == 8)) - { - cerr<<"Unknown option: "<< argv[i] << endl; - usage(argv[0]); - exit(1); - } - ++i; // Skip over size argument - } - else if(string(argv[i])=="--exe-nonce-size" && - string(argv[i+1]).length()==1 && isdigit(string(argv[i+1])[0])) - { - exe_nonce_size = stoi(string(argv[i+1])); - if(!(exe_nonce_size == 1 || exe_nonce_size == 2 || exe_nonce_size == 4 || exe_nonce_size == 8)) - { - cerr<<"Unknown option: "<< argv[i] << endl; - usage(argv[0]); - exit(1); - } - ++i; // Skip over size argument - } - else if(string(argv[i])=="--color") - { - cout<<"Using coloring..."<<endl; - do_coloring=true; - } - else if(string(argv[i])=="--no-color") - { - cout<<"Not using coloring..."<<endl; - do_coloring=false; - } - else if(string(argv[i])=="--color-exe-nonces") - { - cout<<"Using coloring for exe nonces..."<<endl; - do_color_exe_nonces=true; - } - else if(string(argv[i])=="--no-color-exe-nonces") - { - cout<<"Not using coloring for exe nonces..."<<endl; - do_color_exe_nonces=false; - } - else if(string(argv[i])=="--protect-calls") - { - cout<<"protecting calls..."<<endl; - do_calls=true; - } - else if(string(argv[i])=="--no-protect-calls") - { - cout<<"Not protecting calls..."<<endl; - do_calls=false; - } - else if(string(argv[i])=="--protect-jumps") - { - cout<<"protecting jumps..."<<endl; - do_jumps=true; - } - else if(string(argv[i])=="--no-protect-jumps") - { - cout<<"Not protecting jumps..."<<endl; - do_jumps=false; - } - else if(string(argv[i])=="--protect-rets") - { - cout<<"protecting returns..."<<endl; - do_rets=true; - } - else if(string(argv[i])=="--no-protect-rets") - { - cout<<"Not protecting returns..."<<endl; - do_rets=false; - } - else if(string(argv[i])=="--protect-safefn") - { - cout<<"protecting safe functions..."<<endl; - do_safefn=true; - } - else if(string(argv[i])=="--no-protect-safefn") - { - cout<<"Not protecting safe functions..."<<endl; - do_safefn=false; - } - else if(string(argv[i])=="--no-multimodule") - { - cout<<"Not adding multimodule support..."<<endl; - do_multimodule=false; - } - else if(string(argv[i])=="--multimodule") - { - cout<<"Adding multimodule support ..."<<endl; - do_multimodule=true; - } - else if(string(argv[i])=="--no-exe-nonce-for-call") - { - cout<<"Not adding exe-nonce-for-call support..."<<endl; - do_exe_nonce_for_call=false; - } - else if(string(argv[i])=="--exe-nonce-for-call") - { - cout<<"Adding exe-nonce-for-call support ..."<<endl; - do_exe_nonce_for_call=true; - } - else if(string(argv[i])=="--common-slow-path") - { - cout<<"Using common slow path..."<<endl; - do_common_slow_path=true; - } - else if(string(argv[i])=="--no-common-slow-path") - { - cout<<"Not using common slow path..."<<endl; - do_common_slow_path=false; - } - else - { - cerr<<"Unknown option: "<< argv[i] << endl; - usage(argv[0]); - exit(1); - } - } - - string programName(argv[0]); - int variantID = atoi(argv[1]); - - /* setup the interface to the sql server */ - auto pqxx_interface=pqxxDB_t::factory(); - BaseObj_t::setInterface(pqxx_interface.get()); - - auto pidp=VariantID_t::factory(variantID); - assert(pidp->isRegistered()==true); - - cout<<"selective_cfi.exe started\n"; - - bool one_success = false; - bool seen_failures = false; - for(auto this_file : pidp->getFiles()) - { - auto firp = FileIR_t::factory(pidp.get(), this_file); - - cout<<"Transforming "<<this_file->getURL()<<endl; - - assert(firp && pidp); - - try - { - SCFI_Instrument scfii(firp.get(), nonce_size, exe_nonce_size, do_coloring, do_color_exe_nonces, do_common_slow_path, do_jumps, do_calls, do_rets, do_safefn, do_multimodule, do_exe_nonce_for_call); - - - int success=scfii.execute(); - - if (success) - { - cout<<"Writing changes for "<<this_file->getURL()<<endl; - one_success = true; - firp->writeToDB(); - } - else - { - seen_failures = true; - cout<<"Skipping (no changes) "<<this_file->getURL()<<endl; - } - } - catch (DatabaseError_t pnide) - { - seen_failures = true; - cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; - } - catch (...) - { - seen_failures = true; - cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; - } - } // end file iterator - - // if any integer transforms for any files succeeded, we commit - if (one_success) - { - cout<<"Commiting changes...\n"; - pqxx_interface->commit(); - } - - if(seen_failures) - { - return 1; - } - else - { - return 0; - } -} - diff --git a/tools/selective_cfi/scfi_instr.cpp b/tools/selective_cfi/scfi_instr.cpp deleted file mode 100644 index 10cec5511..000000000 --- a/tools/selective_cfi/scfi_instr.cpp +++ /dev/null @@ -1,1597 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - -#include <algorithm> -#include "scfi_instr.hpp" -#include "color_map.hpp" -#include <stdlib.h> -#include <memory> -#include <math.h> -#include <exeio.h> -#include <elf.h> - - -using namespace std; -using namespace IRDB_SDK; - -string getRetDataBits() -{ - string dataBits; - dataBits.resize(1); - dataBits[0] = 0xc3; - return dataBits; -} - - - -Relocation_t* SCFI_Instrument::FindRelocation(Instruction_t* insn, string type) -{ - RelocationSet_t::iterator rit; - for( rit=insn->getRelocations().begin(); rit!=insn->getRelocations().end(); ++rit) - { - Relocation_t& reloc=*(*rit); - if(reloc.getType()==type) - { - return &reloc; - } - } - return NULL; -} - -bool SCFI_Instrument::isSafeFunction(Instruction_t* insn) -{ - return (insn && insn->getFunction() && insn->getFunction()->isSafe()); -} - -bool SCFI_Instrument::isCallToSafeFunction(Instruction_t* insn) -{ - if (insn && insn->getTarget() && insn->getTarget()->getFunction()) - { - if(getenv("SCFI_VERBOSE")!=NULL) - { - if (insn->getTarget()->getFunction()->isSafe()) - { - cout << "Function " << insn->getTarget()->getFunction()->getName() << " is deemed safe" << endl; - } - } - - return insn->getTarget()->getFunction()->isSafe(); - } - - return false; -} - -Relocation_t* SCFI_Instrument::create_reloc(Instruction_t* insn) -{ - /* - * Relocation_t* reloc=new Relocation_t; - */ - auto reloc=firp->addNewRelocation(insn,0,"error-if-seen"); // will update offset and type in caller - - return reloc; -} - -bool SCFI_Instrument::add_scfi_instrumentation(Instruction_t* insn) -{ - bool success=true; - - if(getenv("SCFI_VERBOSE")!=NULL) - ; - - - return success; -} - -bool SCFI_Instrument::needs_scfi_instrumentation(Instruction_t* insn) -{ -assert(0); - return false; - -} - -unsigned int SCFI_Instrument::GetExeNonceOffset(Instruction_t* insn) -{ - if(exe_nonce_color_map) - { - assert(insn->getIBTargets()); - // We can't know the offset yet because this nonce may need to get - // shoved into multiple exe nonces, so just return the position. - cout << "EXE NONCE OFFSET IS: "<< exe_nonce_color_map->GetColorOfIB(insn).GetPosition() << endl; - return exe_nonce_color_map->GetColorOfIB(insn).GetPosition(); - } - // Otherwise, only one nonce per target and it's always in the first position - return 0; -} - -NonceValueType_t SCFI_Instrument::GetExeNonce(Instruction_t* insn) -{ - if(exe_nonce_color_map) - { - assert(insn->getIBTargets()); - return exe_nonce_color_map->GetColorOfIB(insn).GetNonceValue(); - } - // Otherwise, all nonces are the same - switch(exe_nonce_size) - { - case 1: - return 0xcc; - case 2: - return 0xbbcc; - case 4: - return 0xaabbccdd; - case 8: - return 0xaabbccdd00112233; - default: - exit(1); // wat? - } -} - -unsigned int SCFI_Instrument::GetExeNonceSize(Instruction_t* insn) -{ - return exe_nonce_size; -} - -unsigned int SCFI_Instrument::GetNonceOffset(Instruction_t* insn) -{ - if(color_map) - { - assert(insn->getIBTargets()); - return (color_map->GetColorOfIB(insn).GetPosition()+1) * GetNonceSize(insn); - } - return GetNonceSize(insn); -} - -NonceValueType_t SCFI_Instrument::GetNonce(Instruction_t* insn) -{ - /* in time we look up the nonce category for this insn */ - /* for now, it's just f4 as the nonce */ - if(color_map) - { - assert(insn->getIBTargets()); - return color_map->GetColorOfIB(insn).GetNonceValue(); - } - // Otherwise, all nonces are the same - switch(nonce_size) - { - case 1: - return 0xcc; - case 2: - return 0xbbcc; - case 4: - return 0xaabbccdd; - case 8: - return 0xaabbccdd00112233; - default: - exit(1); // wat? - } -} - -unsigned int SCFI_Instrument::GetNonceSize(Instruction_t* insn) -{ - return nonce_size; -} - -bool SCFI_Instrument::mark_targets() -{ - int targets=0, ind_targets=0, exe_nonce_targets=0; - // Make sure no unresolved instructions are in the insn set - firp->assembleRegistry(); - firp->setBaseIDS(); - // create new preds (we've added instructions) - auto newPredsp=InstructionPredecessors_t::factory(firp); - auto &newPreds=*newPredsp; - // Make sure the new insns added in this loop are not processed in this loop - // (ok since none of the them should receive nonces) - auto insn_set = firp->getInstructions(); - for(auto insn : insn_set) - { - targets++; - if(insn->getIndirectBranchTargetAddress()) - { - - // make sure there are no fallthroughs to nonces. - for(auto the_pred : newPreds[insn]) - { - if(the_pred->getFallthrough()==insn) - { - Instruction_t* jmp=addNewAssembly("jmp 0x0"); - the_pred->setFallthrough(jmp); - jmp->setTarget(insn); - } - } - - ind_targets++; - string type; - if(do_coloring) - { - ColoredSlotValues_t v=color_map->GetColorsOfIBT(insn); - int size=GetNonceSize(insn); - for(auto i=0U;i<v.size();i++) - { - if(!v[i].IsValid()) - continue; - int position=v[i].GetPosition(); - - // convert the colored "slot" into a position in the code. - position++; - position*=size; - position = - position; - - // cfi_nonce=(pos=-1,nv=0x33,sz=1) - NonceValueType_t noncevalue=v[i].GetNonceValue(); - type=string("cfi_nonce=(pos=") + to_string(position) + ",nv=" - + to_string(noncevalue) + ",sz="+ to_string(size)+ ")"; - Relocation_t* reloc=create_reloc(insn); - reloc->setOffset(-position*size); - reloc->setType(type); - cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; - } - } - else - { - type=string("cfi_nonce=(pos=") + to_string(-((int) GetNonceOffset(insn))) + ",nv=" - + to_string(GetNonce(insn)) + ",sz="+ to_string(GetNonceSize(insn))+ ")"; - Relocation_t* reloc=create_reloc(insn); - reloc->setOffset(-((int) GetNonceOffset(insn))); - reloc->setType(type); - cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; - } - } - - if(do_exe_nonce_for_call && DecodedInstruction_t::factory(insn)->isCall()) - { - ++exe_nonce_targets; - - if(do_color_exe_nonces) - { - // The colors we want are not on the call, but on its return target. - ColoredSlotValues_t v=exe_nonce_color_map->GetColorsOfIBT(insn->getFallthrough()); - - // The return target gets a regular nonce as well, so there may be an inserted jmp - // in the way of the original IBT that has our colors. - if(v.size() == 0) - { - v=exe_nonce_color_map->GetColorsOfIBT(insn->getFallthrough()->getTarget()); - } - - int nonceSz=GetExeNonceSize(insn); //Multiple sizes not yet supported - - for(auto i=0U;i<v.size();i++) - { - int noncePos; - NonceValueType_t nonceVal; - if(!v[i].IsValid()) - { - // This position is not valid, but need to fill it with something anyway - // because nonces are executable - noncePos = i; //FIXME: BAD COUPLING. Relies on the fact that i == position number - nonceVal = 0xc; - } - else - { - noncePos=v[i].GetPosition(); - nonceVal = v[i].GetNonceValue(); - } - PlaceExeNonceReloc(insn, nonceVal, nonceSz, noncePos); - } - // Place exe nonce reloc to fill extra space (if any) - int isExtraSpace = (v.size()*nonceSz) % EXE_NONCE_ARG_SIZE; - if(isExtraSpace) - { - int extraSpace = EXE_NONCE_ARG_SIZE - ((v.size()*nonceSz) % EXE_NONCE_ARG_SIZE); - int extraSpacePos = v.size(); - int extraSpaceBytePos = GetNonceBytePos(nonceSz, extraSpacePos-1)+nonceSz; - CreateExeNonceReloc(insn, 0, extraSpace, extraSpaceBytePos); - } - } - else - { - int nonceSz = GetExeNonceSize(insn); - PlaceExeNonceReloc(insn, GetExeNonce(insn), nonceSz, GetExeNonceOffset(insn)); - // Place exe nonce reloc to fill extra space (if any) - int isExtraSpace = nonceSz % EXE_NONCE_ARG_SIZE; - if(isExtraSpace) - { - int extraSpace = EXE_NONCE_ARG_SIZE - (nonceSz % EXE_NONCE_ARG_SIZE); - int extraSpacePos = 1; - int extraSpaceBytePos = GetNonceBytePos(nonceSz, extraSpacePos-1)+nonceSz; - CreateExeNonceReloc(insn, 0, extraSpace, extraSpaceBytePos); - } - } - } - } - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::ind_targets_found="<<std::dec<<ind_targets<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::targets_found="<<std::dec<<targets<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::exe_nonce_targets_found="<<std::dec<<exe_nonce_targets<<endl; - - assert(getenv("SELF_VALIDATE")==nullptr || ind_targets > 5 ); - assert(getenv("SELF_VALIDATE")==nullptr || targets > 5 ); - assert(getenv("SELF_VALIDATE")==nullptr || !do_exe_nonce_for_call || exe_nonce_targets > 5 ); - - return true; -} - - -void SCFI_Instrument::CreateExeNonceReloc(Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int bytePos) -{ - string type=string("cfi_exe_nonce=(pos=") + to_string(bytePos) + ",nv=" - + to_string(nonceVal) + ",sz="+ to_string(nonceSz)+ ")"; - Relocation_t* reloc=create_reloc(insn); - reloc->setOffset(bytePos); - reloc->setType(type); - cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; -} - - -int SCFI_Instrument::GetNonceBytePos(int nonceSz, int noncePos) -{ - // To get to the nonce, we must pass over noncePos other nonces, which may involve - // jumping over some exe nonce opcodes, depending on the exe nonce argument size. - int nonceBytePos = (((noncePos*nonceSz)/EXE_NONCE_ARG_SIZE)+1)*EXE_NONCE_OPCODE_SIZE - + noncePos*nonceSz; - return nonceBytePos; -} - - -/* Nonces are just bit strings. To fit them into exe - * nonces that have a limited argument size, they may need to - * be split over more than one exe nonce. To be stored as tightly - * as possible, more than one nonce may be fit into one exe nonce. - * - * To handle this, the GetExeNonceFit function returns a list - * of one or more NonceParts that together specify where in memory - * the complete nonce string is located. - * This function makes some CRITICAL ASSUMPTIONS. Look at the function definition in scfi_instr.hpp */ -std::vector<SCFI_Instrument::NoncePart_t> SCFI_Instrument::GetExeNonceFit(NonceValueType_t nonceVal, int nonceSz, int noncePos) -{ - // Checking an assumption - if(nonceSz > EXE_NONCE_ARG_SIZE) - assert(nonceSz % EXE_NONCE_ARG_SIZE == 0); - else - assert(EXE_NONCE_ARG_SIZE % nonceSz == 0); - - // If our nonce will fit into a single exe nonce - if(EXE_NONCE_ARG_SIZE >= nonceSz) - { - // To get to our nonce, we must pass over noncePos other nonces, which may involve - // jumping over some exe nonce opcodes, depending on the exe nonce argument size. - int nonceBytePos = GetNonceBytePos(nonceSz, noncePos); - std::vector<NoncePart_t> noncePartList; - NoncePart_t nonce = {nonceVal, nonceBytePos, nonceSz}; - noncePartList.push_back(nonce); - return noncePartList; - } - else //Otherwise, our nonce will have to be split over multiple exe nonces - { - // We will be dividing the nonce into nonceSz/EXE_NONCE_ARG_SIZE nonce parts, - // and each part corresponds to one entire exe nonce. - - std::vector<NoncePart_t> noncePartList; - for(int exeNonceIndex=0; exeNonceIndex < nonceSz/EXE_NONCE_ARG_SIZE; exeNonceIndex++) - { - // Calculate our nonce part info. The idea is to treat - // the nonce part as if it were a complete nonce in a scenario where - // nonce size = exe nonce arg size. This requires recalculation of the - // nonce position. - - int noncePartSz = EXE_NONCE_ARG_SIZE; - int noncePartPos = exeNonceIndex + noncePos*(nonceSz/EXE_NONCE_ARG_SIZE); - int noncePartBytePos = GetNonceBytePos(noncePartSz, noncePartPos); - - NonceValueType_t mask = 0; - mask = ~mask; - NonceValueType_t noncePartVal = (nonceVal >> exeNonceIndex*EXE_NONCE_ARG_SIZE*8) - & (mask >> (8-EXE_NONCE_ARG_SIZE)*8); - cout << "CALCD NONCE BYTE POS AS: " << noncePartBytePos << endl; - // Store the calculated nonce part info - NoncePart_t part = {noncePartVal, noncePartBytePos, noncePartSz}; - noncePartList.push_back(part); - } - return noncePartList; - } -} - - -// This function supports marking targets for colored 1, 2, 4, or 8 byte exe nonces. -// The exe nonce argument sizes can be 1, 2, 4, or 8 bytes. -void SCFI_Instrument::PlaceExeNonceReloc(Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int noncePos) -{ - // Get the nonce parts our nonce will be divided into to fit into the exe nonces - std::vector<NoncePart_t> nonceParts = GetExeNonceFit(nonceVal, nonceSz, noncePos); - // Create exe nonce relocs for each part. - for(std::vector<NoncePart_t>::iterator it = nonceParts.begin(); it != nonceParts.end(); ++it) - { - NoncePart_t theNoncePart = *it; - // If this nonce part is next to an exe nonce opcode, create a reloc for the opcode too - bool nextToExeNonceOpCode = !((noncePos*nonceSz) % EXE_NONCE_ARG_SIZE); - if(nextToExeNonceOpCode) - { - CreateExeNonceReloc(insn, EXE_NONCE_OPCODE_VAL, EXE_NONCE_OPCODE_SIZE, - theNoncePart.bytePos-EXE_NONCE_OPCODE_SIZE ); - } - // Create an exe nonce reloc for the nonce part. - CreateExeNonceReloc(insn, theNoncePart.val, theNoncePart.size, theNoncePart.bytePos); - } -} - - -/* - * targ_change_to_push - use the mode in the insnp to create a new instruction that is a push instruction. - */ -static string change_to_push(Instruction_t *insn) -{ - string newbits=insn->getDataBits(); - - const auto dp=DecodedInstruction_t::factory(insn); - const auto &d=*dp; - - int opcode_offset=0; - - opcode_offset=d.getPrefixCount(); - - unsigned char modregrm = (newbits[1+opcode_offset]); - modregrm &= 0xc7; - modregrm |= 0x30; - newbits[0+opcode_offset] = 0xFF; - newbits[1+opcode_offset] = modregrm; - - return newbits; -} - - -void SCFI_Instrument::mov_reloc(Instruction_t* from, Instruction_t* to, string type ) -{ - // need to copy because moveReloc will destroy the iterator used for copying - auto copy_of_relocs=from->getRelocations(); - for(auto reloc : copy_of_relocs) - { - - if(reloc->getType()==type) - { - firp->moveRelocation(reloc,from,to); - // odd standards-conforming way to delete object while iterating. - //to->getRelocations().insert(reloc); - //from->getRelocations().erase(it++); - } - } - -} - - -void SCFI_Instrument::move_relocs(Instruction_t* from, Instruction_t* to) -{ - auto copy_of_relocs=from->getRelocations(); - for(auto reloc : copy_of_relocs) - { - if(reloc->getType()!="fix_call_fallthrough") - { - firp->moveRelocation(reloc,from,to); - // to->getRelocations().insert(reloc); - // from->getRelocations().erase(current); - } - } -} - -void SCFI_Instrument::AddJumpCFI(Instruction_t* insn) -{ - assert(do_rets); - - string pushbits=change_to_push(insn); - cout<<"Converting ' "<<insn->getDisassembly()<<"' to '"; - Instruction_t* after=insertDataBitsBefore(insn,pushbits); - move_relocs(after,insn); - - after->setDataBits(getRetDataBits()); - cout <<insn->getDisassembly()<<" + ret' "<<endl ; - - // move any pc-rel relocation bits to the push, which will access memory now - mov_reloc(after,insn,"pcrel"); - - if(do_exe_nonce_for_call) - { - // This may be inefficient b/c jumps will not normally be targeting - // return targets. However, that does happen in multimodule returns - // so this is needed. - AddReturnCFIForExeNonce(after); - } - else - { - AddReturnCFI(after); - } - // cout<<"Warning, JUMPS not CFI's yet"<<endl; - return; -} - - -void SCFI_Instrument::AddCallCFIWithExeNonce(Instruction_t* insn) -{ - string reg="ecx"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - reg="r11"; // 64-bit reg. - - Instruction_t* call=NULL, *stub=NULL; - - - // convert a call indtarg to: - // push indtarg ;Calculate target if it has a memory operation - // pop reg ;Calculate it before changing stack ptr with call stub - // call stub ;Easy way to get correct return address on stack - // - //stub: cmp <nonce size> PTR [ecx-<nonce size>], Nonce - // jne slow - // jmp reg - - - // insert the pop/checking code. - string pushbits=change_to_push(insn); - call=insertDataBitsBefore(insn, pushbits); - insertAssemblyAfter(insn,string("pop ")+reg); - - // keep any relocs on the push instruction, as those may need updating. - insn->setRelocations(call->getRelocations()); - call->setRelocations({}); - - // Jump to non-exe nonce check code - stub = addNewAssembly(string("push ")+reg); - Instruction_t* ret = insertDataBitsAfter(stub, getRetDataBits()); - ret->setIBTargets(call->getIBTargets()); - - if(do_exe_nonce_for_call) - { - // This may be inefficient b/c jumps will not normally be targeting - // return targets. However, that does happen in multimodule returns - // so this is needed. - AddReturnCFIForExeNonce(ret); - } - else - { - AddReturnCFI(ret); - } - - // convert the indirct call to a direct call to the stub. - string call_bits=call->getDataBits(); - call_bits.resize(5); - call_bits[0]=0xe8; - call->setTarget(stub); - call->setDataBits(call_bits); - call->setComment("Direct call to cfi stub"); - call->setIBTargets(NULL); // lose info about branch targets. - - return; -} - -void SCFI_Instrument::AddExecutableNonce(Instruction_t* insn) -{ -// this is now done by the nonce plugin's PlopDollopEntry routine. -// insertDataBitsAfter(firp, insn, ExecutableNonceValue, NULL); -} - -// Returns the insn starting a non-exe nonce check for an insn, in case the exe nonce check fails -Instruction_t* SCFI_Instrument::GetExeNonceSlowPath(Instruction_t* insn) -{ - // Jump to non-exe nonce check code - Instruction_t* ret = addNewDataBits(getRetDataBits()); - ret->setIBTargets(insn->getIBTargets()); - AddReturnCFI(ret); - return ret; -} - - -// This function supports nonce checks for 1, 2, 4, or 8 byte nonces -// with 1, 2, 4, or 4 byte exe nonce argument sizes. -// TODO: Support 8 byte exe nonce arg sizes -void SCFI_Instrument::InsertExeNonceComparisons(Instruction_t* insn, - NonceValueType_t nonceVal, int nonceSz, int noncePos, - Instruction_t* exeNonceSlowPath) -{ - - int noncePartSz; - if(nonceSz > EXE_NONCE_ARG_SIZE) - noncePartSz = EXE_NONCE_ARG_SIZE; - else - noncePartSz = nonceSz; - - string reg="ecx"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - reg="r11"; // 64-bit reg. - - string decoration=""; - switch(noncePartSz) - { - case 8: - cerr<<"Cannot handle nonce part of size "<<std::dec<<nonceSz<<endl; - assert(0); - break; - case 4: - decoration="dword "; - break; - case 2: // handle later - decoration="word "; - break; - case 1: //handle later - decoration="byte "; - break; - default: - cerr<<"Cannot handle nonce of size "<<std::dec<<nonceSz<<endl; - assert(0); - } - - // Get the nonce parts our nonce will be divided into to fit into the exe nonces - std::vector<NoncePart_t> nonceParts = GetExeNonceFit(nonceVal, nonceSz, noncePos); - // Create exe nonce comparisons for each part. - Instruction_t* tmp = insn; - Instruction_t* jne=NULL; - for(std::vector<NoncePart_t>::iterator it = nonceParts.begin(); it != nonceParts.end(); ++it) - { - NoncePart_t theNoncePart = *it; - cout << "ADDING CMP FOR BYTE POS: " << theNoncePart.bytePos << "FOR NONCE WITH POSITION: " << noncePos << "AND SIZE: " << nonceSz << endl; - tmp=insertAssemblyAfter(tmp,string("cmp ")+decoration+ - " ["+reg+"+"+to_string(theNoncePart.bytePos)+"], "+to_string(theNoncePart.val)); - jne=tmp=insertAssemblyAfter(tmp,"jne 0"); - jne->setTarget(exeNonceSlowPath); - } -} - - -void SCFI_Instrument::AddReturnCFIForExeNonce(Instruction_t* insn, ColoredSlotValue_t *v) -{ - - if(!do_rets) - return; - - string reg="ecx"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - reg="r11"; // 64-bit reg. - - string rspreg="esp"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - rspreg="rsp"; // 64-bit reg. - - string worddec="dword"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - worddec="qword"; // 64-bit reg. - - - const auto dp=DecodedInstruction_t::factory(insn); - const auto &d=*dp; - - if(d.hasOperand(0)) - { - unsigned int sp_adjust=d.getImmediate() -firp->getArchitectureBitWidth()/8; - cout<<"Found relatively rare ret_with_pop insn: "<<d.getDisassembly() <<endl; - char buf[30]; - sprintf(buf, "pop %s [%s+%d]", worddec.c_str(), rspreg.c_str(), sp_adjust); - Instruction_t* newafter=insertAssemblyBefore(insn,buf); - - if(sp_adjust>0) - { - sprintf(buf, "lea %s, [%s+%d]", rspreg.c_str(), rspreg.c_str(), sp_adjust); - } - - // rewrite the "old" isntruction, as that's what insertAssemblyBefore returns - insn=newafter; - //Needed b/c AddReturnCFI may be called on this ret insn - //But also clean up and change ret_with_pop to ret (as it should be now) to be safe - setInstructionAssembly(insn, string("ret"), insn->getFallthrough(), insn->getTarget()); - } - //TODO: Handle uncommon slow path - - //TODO: Fix possible TOCTOU race condition? (see Abadi CFI paper) - // Ret address can be changed between nonce check and ret insn execution (in theory) - int nonce_size=GetExeNonceSize(insn); - int nonce_pos=GetExeNonceOffset(insn); - NonceValueType_t nonce=GetExeNonce(insn); - Instruction_t* exeNonceSlowPath = GetExeNonceSlowPath(insn); - - - // convert a return to: - // mov ecx, [esp] - // cmp <nonce size> PTR [ecx+<offset>], Nonce - // jne exit_node ; no need for slow path here - // ret ; ignore race condition for now - - // insert the mov/checking code. - insertAssemblyBefore(insn,string("mov ")+reg+string(", [")+rspreg+string("]")); - InsertExeNonceComparisons(insn, nonce, nonce_size, nonce_pos, exeNonceSlowPath); - // leave the ret instruction (risk of successful race condition exploit << performance benefit) - - return; - -} - -void SCFI_Instrument::AddReturnCFI(Instruction_t* insn, ColoredSlotValue_t *v) -{ - - if(!do_rets) - return; - ColoredSlotValue_t v2; - if(v==NULL && color_map) - { - v2=color_map->GetColorOfIB(insn); - v=&v2; - } - - - string reg="ecx"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - reg="r11"; // 64-bit reg. - - string rspreg="esp"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - rspreg="rsp"; // 64-bit reg. - - string worddec="dword"; // 32-bit reg - if(firp->getArchitectureBitWidth()==64) - worddec="qword"; // 64-bit reg. - - const auto dp=DecodedInstruction_t::factory(insn); - const auto &d=*dp; - if(d.hasOperand(0)) // d.Argument1.ArgType!=NO_ARGUMENT) - { - unsigned int sp_adjust=d.getImmediate() /* Instruction.Immediat*/-firp->getArchitectureBitWidth()/8; - cout<<"Found relatively rare ret_with_pop insn: "<<d.getDisassembly()<<endl; - char buf[30]; - sprintf(buf, "pop %s [%s+%d]", worddec.c_str(), rspreg.c_str(), sp_adjust); - Instruction_t* newafter=insertAssemblyBefore(insn,buf); - - if(sp_adjust>0) - { - sprintf(buf, "lea %s, [%s+%d]", rspreg.c_str(), rspreg.c_str(), sp_adjust); - } - - // rewrite the "old" isntruction, as that's what insertAssemblyBefore returns - insn=newafter; - //Clean up and change ret_with_pop to ret (as it should be now) to be safe - setInstructionAssembly(insn, string("ret"), insn->getFallthrough(), insn->getTarget()); - } - - int size=1; - //int position=0; - string slow_cfi_path_reloc_string; - if(do_coloring && !do_common_slow_path) - { - slow_cfi_path_reloc_string="slow_cfi_path=(pos=-1,nv=244,sz=1)"; - if( v && v->IsValid()) - { - slow_cfi_path_reloc_string="slow_cfi_path=(pos=-"+ to_string(v->GetPosition()+1) +",nv=" - + to_string(v->GetNonceValue())+",sz="+ to_string(size) +")"; - size=v->GetPosition(); - } - } - else - { - slow_cfi_path_reloc_string="slow_cfi_path"; - } - - - cout<<"Cal'd slow-path cfi reloc as: "<<slow_cfi_path_reloc_string<<endl; -// fixme: would like to mark a slow path per nonce type using the variables calc'd above. - - - - - string decoration=""; - int nonce_size=GetNonceSize(insn); - int nonce_offset=GetNonceOffset(insn); - NonceValueType_t nonce=GetNonce(insn); - Instruction_t* jne=NULL, *tmp=NULL; - - - // convert a return to: - // pop ecx - // cmp <nonce size> PTR [ecx-<nonce size>], Nonce - // jne slow ; reloc such that strata/zipr can convert slow to new code - // ; to handle places where nonce's can't be placed. - // jmp ecx - - switch(nonce_size) - { - case 1: - decoration="byte "; - break; - case 2: // handle later - decoration="word "; - break; - case 4: // handle later - decoration="dword "; - break; - case 8: - decoration="dword "; // 8 byte nonces will be split into 2 compares - break; - default: - cerr<<"Cannot handle nonce of size "<<std::dec<<nonce_size<<endl; - assert(0); - - } - - // insert the pop/checking code. - insertAssemblyBefore(insn,string("pop ")+reg); - if(nonce_size != 8) - { - tmp=insertAssemblyAfter(insn,string("cmp ")+decoration+ - " ["+reg+"-"+to_string(nonce_offset)+"], "+to_string(nonce)); - } - else - { - tmp=insertAssemblyAfter(insn,string("cmp ")+decoration+ - " ["+reg+"-"+to_string(nonce_offset)+"], "+to_string((uint32_t) nonce)); // upper 32 bits chopped off by cast - jne=tmp=insertAssemblyAfter(tmp,"jne 0"); - tmp=insertAssemblyAfter(tmp,string("cmp ")+decoration+ - " ["+reg+"-"+to_string(nonce_offset - 4)+"], "+to_string((uint32_t) (nonce >> 32))); - // set the jne's target to itself, and create a reloc that zipr/strata will have to resolve. - jne->setTarget(jne); // needed so spri/spasm/irdb don't freak out about missing target for new insn. - Relocation_t* reloc=create_reloc(jne); - reloc->setType(slow_cfi_path_reloc_string); - reloc->setOffset(0); - cout<<"Setting slow path for: "<<slow_cfi_path_reloc_string<<endl; - } - - jne=tmp=insertAssemblyAfter(tmp,"jne 0"); - // convert the ret instruction to a jmp ecx - cout<<"Converting "<<hex<<tmp->getFallthrough()->getBaseID()<<":"<<tmp->getFallthrough()->getDisassembly()<<"to jmp+reg"<<endl; - setInstructionAssembly(tmp->getFallthrough(), string("jmp ")+reg, NULL,NULL); - - // set the jne's target to itself, and create a reloc that zipr/strata will have to resolve. - jne->setTarget(jne); // needed so spri/spasm/irdb don't freak out about missing target for new insn. - Relocation_t* reloc=create_reloc(jne); - reloc->setType(slow_cfi_path_reloc_string); - reloc->setOffset(0); - cout<<"Setting slow path for: "<<slow_cfi_path_reloc_string<<endl; - - return; -} - -static void display_histogram(std::ostream& out, std::string attr_label, std::map<int,int> & p_map) -{ - if (p_map.size()) - { - out<<"# ATTRIBUTE Selective_Control_Flow_Integrity::" << attr_label << "="; - out<<"{ibt_size:count,"; - bool first_time=true; - for (map<int,int>::iterator it = p_map.begin(); - it != p_map.end(); ++it) - { - if (!first_time) - out << ","; - out << it->first << ":" << it->second; - first_time = false; - } - out<<"}"<<endl; - } -} - -bool SCFI_Instrument::is_plt_style_jmp(Instruction_t* insn) -{ - const auto d=DecodedInstruction_t::factory(insn); - if(d->getOperand(0)->isMemory()) - { - if(!d->getOperand(0)->hasBaseRegister() && !d->getOperand(0)->hasIndexRegister() ) - return true; - return false; - } - return false; -} - -bool SCFI_Instrument::is_jmp_a_fixed_call(Instruction_t* insn) -{ - if(preds[insn].size()!=1) - return false; - - Instruction_t* pred=*(preds[insn].begin()); - assert(pred); - - if(pred->getDataBits()[0]==0x68) - return true; - return false; -} - -bool SCFI_Instrument::instrument_jumps() -{ - int cfi_checks=0; - int cfi_branch_jmp_checks=0; - int cfi_branch_jmp_complete=0; - int cfi_branch_call_checks=0; - int cfi_branch_call_complete=0; - int cfi_branch_ret_checks=0; - int cfi_branch_ret_complete=0; - int cfi_safefn_jmp_skipped=0; - int cfi_safefn_ret_skipped=0; - int cfi_safefn_call_skipped=0; - int ibt_complete=0; - double cfi_branch_jmp_complete_ratio = NAN; - double cfi_branch_call_complete_ratio = NAN; - double cfi_branch_ret_complete_ratio = NAN; - - std::map<int, int> calls; - std::map<int, int> jmps; - std::map<int, int> rets; - - // build histogram of target sizes - - // for each instruction - // But make sure the new insns added in this loop are not processed in this loop - // (ok since none of the them should need to be protected) - auto insn_set = firp->getInstructions(); - for(auto insn : insn_set) - { - - // we always have to protect the zestcfi dispatcher, that we just added. - if(zestcfi_function_entry==insn) - { - cout<<"Protecting zestcfi function for external entrances"<<endl; - cfi_checks++; - AddJumpCFI(insn); - continue; - } - - if(insn->getBaseID()==BaseObj_t::NOT_IN_DATABASE) - continue; - - const auto dp=DecodedInstruction_t::factory(insn); - const auto &d=*dp; - - if (insn->getFunction()) - cerr<<"Looking at: "<<insn->getDisassembly()<< " from func: " << insn->getFunction()->getName() << endl; - else - cerr<<"Looking at: "<<insn->getDisassembly()<< " but no associated function" << endl; - - if(d.isCall() && (protect_safefn && !do_exe_nonce_for_call)) - { - cerr<<"Fatal Error: Found call instruction!"<<endl; - cerr<<"FIX_CALLS_FIX_ALL_CALLS=1 should be set in the environment, or"<<endl; - cerr<<"--step-option fix_calls:--fix-all should be passed to ps_analyze."<<endl; - exit(1); - } - - // if marked safe - if(FindRelocation(insn,"cf::safe")) - continue; - - bool safefn = isSafeFunction(insn); - - if (safefn) { - if (insn->getFunction()) - cerr << insn->getFunction()->getName() << " is safe" << endl; - } - - - - if(d.isUnconditionalBranch()) - { - if(!d.getOperand(0)->isConstant()) - { - bool is_fixed_call=is_jmp_a_fixed_call(insn); - bool is_plt_style=is_plt_style_jmp(insn); - bool is_any_call_style = (is_fixed_call || is_plt_style); - if(do_jumps && !is_any_call_style) - { - if (insn->getIBTargets() && insn->getIBTargets()->isComplete()) - { - cfi_branch_jmp_complete++; - jmps[insn->getIBTargets()->size()]++; - } - - cfi_checks++; - cfi_branch_jmp_checks++; - - AddJumpCFI(insn); - } - else if(do_calls && is_any_call_style) - { - if (insn->getIBTargets() && insn->getIBTargets()->isComplete()) - { - cfi_branch_call_complete++; - calls[insn->getIBTargets()->size()]++; - } - - cfi_checks++; - cfi_branch_call_checks++; - - AddJumpCFI(insn); - } - else - { - cout<<"Eliding protection for "<<insn->getDisassembly()<<std::boolalpha - <<" is_fixed_call="<<is_fixed_call - <<" is_plt_style="<<is_plt_style - <<" is_any_call_style="<<is_any_call_style - <<" do_jumps="<<do_jumps - <<" do_calls="<<do_calls<<endl; - } - } - } - else if(d.isCall()) - { - - // should only see calls if we are not CFI'ing safe functions - // be sure to use with: --no-fix-safefn in fixcalls - // (1) --no-fix-safefn in fixcalls leaves call as call (instead of push/jmp) - // (2) and here, we don't plop down a nonce - // see (3) below where we don't instrument returns for safe functions - bool isDirectCall = d.getOperand(0)->isConstant(); - if (!protect_safefn) - { - - if (safefn || (isDirectCall && isCallToSafeFunction(insn))) - { - cfi_safefn_call_skipped++; - continue; - } - } - - AddExecutableNonce(insn); // for all calls - if(!isDirectCall) - { - // for indirect calls. - AddCallCFIWithExeNonce(insn); - } - } - else if (d.isReturn()) - { - if (insn->getFunction()) - cerr << "found ret type protect_safefn: " << protect_safefn << " safefn: " << safefn << " function: " << insn->getFunction()->getName() << endl; - else - cerr << "found ret type protect_safefn: " << protect_safefn << " safefn: " << safefn << " no functions associated with instruction!! wtf???" << endl; - if (insn->getIBTargets() && insn->getIBTargets()->isComplete()) - { - cfi_branch_ret_complete++; - rets[insn->getIBTargets()->size()]++; - } - - // (3) and here, we don't instrument returns for safe function - if (!protect_safefn && safefn) - { - cfi_safefn_ret_skipped++; - continue; - } - - cfi_checks++; - cfi_branch_ret_checks++; - - if(do_exe_nonce_for_call) { - AddReturnCFIForExeNonce(insn); - } - else { - AddReturnCFI(insn); - } - } - else - { - } - } - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_jmp_checks="<<std::dec<<cfi_branch_jmp_checks<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_jmp_complete="<<cfi_branch_jmp_complete<<endl; - display_histogram(cout, "cfi_jmp_complete_histogram", jmps); - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_branch_call_checks="<<std::dec<<cfi_branch_call_checks<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_branch_call_complete="<<std::dec<<cfi_branch_call_complete<<endl; - display_histogram(cout, "cfi_call_complete_histogram", calls); - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_ret_checks="<<std::dec<<cfi_branch_ret_checks<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_ret_complete="<<std::dec<<cfi_branch_ret_complete<<endl; - display_histogram(cout, "cfi_ret_complete_histogram", rets); - - assert(getenv("SELF_VALIDATE")==nullptr || cfi_branch_call_checks> 2); - assert(getenv("SELF_VALIDATE")==nullptr || cfi_branch_call_checks> 2); - - // 0 or 1 checks. - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::multimodule_checks="<< (unsigned int)(zestcfi_function_entry!=NULL) <<endl; - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_checks="<<std::dec<<cfi_checks<<endl; - ibt_complete = cfi_branch_jmp_complete + cfi_branch_call_complete + cfi_branch_ret_complete; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::ibt_complete="<<std::dec<<ibt_complete<<endl; - - if (cfi_branch_jmp_checks > 0) - cfi_branch_jmp_complete_ratio = (double)cfi_branch_jmp_complete / cfi_branch_jmp_checks; - - if (cfi_branch_call_checks > 0) - cfi_branch_call_complete_ratio = (double)cfi_branch_call_complete / cfi_branch_call_checks; - - if (cfi_branch_ret_checks > 0) - cfi_branch_ret_complete_ratio = (double)cfi_branch_ret_complete / cfi_branch_ret_checks; - - //double cfi_branch_complete_ratio = NAN; - //if (ibt_complete > 0) - // cfi_branch_complete_ratio = (double) cfi_checks / ibt_complete; - - - - cout << "# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_jmp_complete_ratio=" << cfi_branch_jmp_complete_ratio*100.00<<"%" << endl; - cout << "# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_call_complete_ratio=" << cfi_branch_call_complete_ratio*100.00<<"%" << endl; - cout << "# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_ret_complete_ratio=" << cfi_branch_ret_complete_ratio*100.00<<"%" << endl; - cout << "# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_complete_ratio=" << cfi_branch_ret_complete_ratio*100.00<<"%" << endl; - - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_safefn_jmp_skipped="<<cfi_safefn_jmp_skipped<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_safefn_ret_skipped="<<cfi_safefn_ret_skipped<<endl; - cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_safefn_call_skipped="<<cfi_safefn_call_skipped<<endl; - - return true; -} - -// use this to determine whether a scoop has a given name. -static struct ScoopFinder : binary_function<const DataScoop_t*,const string,bool> -{ - // declare a simple scoop finder function that finds scoops by name - bool operator()(const DataScoop_t* scoop, const string& name) const - { - return (scoop->getName() == name); - }; -} finder; - -static DataScoop_t* find_scoop(FileIR_t *firp,const string &name) -{ - auto it=find_if(firp->getDataScoops().begin(), firp->getDataScoops().end(), bind2nd(finder, name)) ; - if( it != firp->getDataScoops().end() ) - return *it; - return NULL; -}; - -static unsigned int add_to_scoop(const string &str, DataScoop_t* scoop) -{ - // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--elftables-only - assert(scoop->getStart()->getVirtualOffset()==0); - int len=str.length(); - scoop->setContents(scoop->getContents()+str); - auto oldend=scoop->getEnd()->getVirtualOffset(); - auto newend=oldend+len; - scoop->getEnd()->setVirtualOffset(newend); - return oldend+1; -}; - -template<int ptrsize> -static void insert_into_scoop_at(const string &str, DataScoop_t* scoop, FileIR_t* firp, const unsigned int at) -{ - // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--cfi - assert(scoop->getStart()->getVirtualOffset()==0); - int len=str.length(); - string new_scoop_contents=scoop->getContents(); - new_scoop_contents.insert(at,str); - scoop->setContents(new_scoop_contents); - - auto oldend=scoop->getEnd()->getVirtualOffset(); - auto newend=oldend+len; - scoop->getEnd()->setVirtualOffset(newend); - - // update each reloc to point to the new location. - for(auto reloc : scoop->getRelocations()) - { - if((unsigned int)reloc->getOffset()>=at) - reloc->setOffset(reloc->getOffset()+str.size()); - - }; - - // check relocations for pointers to this object. - // we'll update dataptr_to_scoop relocs, but nothing else - // so assert if we find something else - for(auto reloc : firp->getRelocations()) - { - auto wrt=dynamic_cast<DataScoop_t*>(reloc->getWRT()); - assert(wrt != scoop || reloc->getType()=="dataptr_to_scoop"); - }; - - // for each scoop - for(auto scoop_to_update : firp->getDataScoops()) - { - // for each relocation for that scoop - for(auto reloc : scoop_to_update->getRelocations()) - { - // if it's a reloc that's wrt scoop - auto wrt=dynamic_cast<DataScoop_t*>(reloc->getWRT()); - if(wrt==scoop) - { - // then we need to update the scoop - if(reloc->getType()=="dataptr_to_scoop") - { - string contents=scoop_to_update->getContents(); - // subtract the stringsize from the (implicitly stored) addend - // taking pointer size into account. - switch(ptrsize) - { - case 4: - { - unsigned int val=*((unsigned int*)&contents.c_str()[reloc->getOffset()]); - if(val>=at) - val +=str.size(); - contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); - break; - - } - case 8: - { - unsigned long long val=*((long long*)&contents.c_str()[reloc->getOffset()]); - if(val>=at) - val +=str.size(); - contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); - break; - - } - default: - assert(0); - } - scoop_to_update->setContents(contents); - } - } - - }; - - }; -}; - -template<int ptrsize> -static void prefix_scoop(const string &str, DataScoop_t* scoop, FileIR_t* firp) -{ - insert_into_scoop_at<ptrsize>(str,scoop,firp,0); -}; - - -template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -bool SCFI_Instrument::add_dl_support() -{ - bool success=true; - success = success && add_libdl_as_needed_support<T_Elf_Sym,T_Elf_Rela, T_Elf_Dyn, rela_shift, reloc_type, ptrsize>(); - success = success && add_got_entries<T_Elf_Sym,T_Elf_Rela, T_Elf_Dyn, reloc_type, rela_shift, ptrsize>(); - - return success; -} - -template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -Instruction_t* SCFI_Instrument::find_runtime_resolve(DataScoop_t* gotplt_scoop) -{ - // find any data_to_insn_ptr reloc for the gotplt scoop - auto it=find_if(gotplt_scoop->getRelocations().begin(), gotplt_scoop->getRelocations().end(), [](Relocation_t* reloc) - { - return reloc->getType()=="data_to_insn_ptr"; - }); - // there _should_ be one. - assert(it!=gotplt_scoop->getRelocations().end()); - - Relocation_t* reloc=*it; - Instruction_t* wrt=dynamic_cast<Instruction_t*>(reloc->getWRT()); - assert(wrt); // should be a WRT - assert(wrt->getDisassembly().find("push ") != string::npos); // should be push K insn - return wrt->getFallthrough(); // jump to the jump, or not.. doesn't matter. zopt will fix -} - -template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -void SCFI_Instrument::add_got_entry(const std::string& name) -{ - // find relevant scoops - auto dynamic_scoop=find_scoop(firp,".dynamic"); - auto dynstr_scoop=find_scoop(firp,".dynstr"); - auto dynsym_scoop=find_scoop(firp,".dynsym"); - auto relaplt_scoop=find_scoop(firp,".rela.dyn coalesced w/.rela.plt"); - auto relplt_scoop=find_scoop(firp,".rel.dyn coalesced w/.rel.plt"); - auto relscoop=relaplt_scoop!=NULL ? relaplt_scoop : relplt_scoop; - auto gnu_version_scoop=find_scoop(firp,".gnu.version"); - - // if versioning info is avail in this binary, assert that we unpinned it. - if(gnu_version_scoop) - assert(gnu_version_scoop->getStart()->getVirtualOffset()==0); - - // add 0-init'd pointer to table - string new_got_entry_str(ptrsize,0); // zero-init a pointer-sized string - - - // create a new, unpinned, rw+relro scoop that's an empty pointer. - const auto start_addr=firp->addNewAddress(firp->getFile()->getBaseID(), 0); - const auto end_addr=firp->addNewAddress(firp->getFile()->getBaseID(), ptrsize-1); - auto external_func_addr_scoop=firp->addNewDataScoop(name, start_addr,end_addr, NULL, 6, true, new_got_entry_str); - - // add string to string table - const auto dl_str_pos=add_to_scoop(name+'\0', dynstr_scoop); - - // add symbol to dlsym - T_Elf_Sym dl_sym; - memset(&dl_sym,0,sizeof(T_Elf_Sym)); - dl_sym.st_name=dl_str_pos; - dl_sym.st_info=((STB_GLOBAL<<4)| (STT_OBJECT)); - string dl_sym_str((const char*)&dl_sym, sizeof(T_Elf_Sym)); - unsigned int dl_pos=add_to_scoop(dl_sym_str,dynsym_scoop); - - // if versioning info is avail in this binary, we are required to add a new entry for the new symbol - if(gnu_version_scoop) - { - // update the gnu.version section so that the new symbol has a version. - const auto new_version_str=string("\0\0", 2); // \0\0 means *local*, as in, don't index the gnu.verneeded array. - add_to_scoop(new_version_str,gnu_version_scoop); - } - - // find the rela count. can't insert before that. - int rela_count=0; - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) - { - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; - if(dyn_entry.d_tag==DT_RELACOUNT) // diff than rela size. - { - // add to the size - rela_count=dyn_entry.d_un.d_val; - break; - } - } - - // create the new reloc - T_Elf_Rela dl_rel; - memset(&dl_rel,0,sizeof(dl_rel)); - auto r_info_tmp=decltype(dl_rel.r_info)(dl_pos); - dl_rel.r_info= ((r_info_tmp/sizeof(T_Elf_Sym))<<rela_shift) | reloc_type; - string dl_rel_str((const char*)&dl_rel, sizeof(dl_rel)); - -// need to fixup relocs - unsigned int at=rela_count*sizeof(T_Elf_Rela); - insert_into_scoop_at<ptrsize>(dl_rel_str, relscoop, firp, at); - - /* - * Relocation_t* dl_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); - relscoop->getRelocations().insert(dl_reloc); - firp->getRelocations().insert(dl_reloc); - */ - auto dl_reloc=firp->addNewRelocation(relscoop,at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); - (void)dl_reloc; - - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) - { - // cast the index'd c_str to an Elf_Dyn pointer and deref it to assign to a - // reference structure. That way editing the structure directly edits the string. - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; - if(dyn_entry.d_tag==DT_RELASZ) - // add to the size - dyn_entry.d_un.d_val+=sizeof(T_Elf_Rela); - - // we insert the zest_cfi_dispatch symbol after the relative relocs. - // but we need to adjust the start if there are no relative relocs. - if(at == 0 && dyn_entry.d_tag==DT_RELA) - // subtract from the start. - dyn_entry.d_un.d_val-=sizeof(T_Elf_Rela); - - } -} - -template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -bool SCFI_Instrument::add_got_entries() -{ - - // find all the necessary scoops; - const auto dynamic_scoop=find_scoop(firp,".dynamic"); - //const auto gotplt_scoop=find_scoop(firp,".got.plt"); - //const auto got_scoop=find_scoop(firp,".got"); - const auto dynstr_scoop=find_scoop(firp,".dynstr"); - const auto dynsym_scoop=find_scoop(firp,".dynsym"); - //const auto relaplt_scoop=find_scoop(firp,".rela.dyn coalesced w/.rela.plt"); - //const auto relplt_scoop=find_scoop(firp,".rel.dyn coalesced w/.rel.plt"); - //const auto relscoop=relaplt_scoop!=NULL ? relaplt_scoop : relplt_scoop; - //const auto search_in = gotplt_scoop==NULL ? got_scoop : gotplt_scoop; - //const auto to_dl_runtime_resolve=find_runtime_resolve<T_Elf_Sym,T_Elf_Rela, T_Elf_Dyn, rela_shift, reloc_type, ptrsize>(search_in); - - - // add necessary GOT entries. - add_got_entry<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>("zest_cfi_dispatch"); - - - // also add a zest cfi "function" that's exported so dlsym can find it. - auto zestcfi_str_pos=add_to_scoop(string("zestcfi")+'\0', dynstr_scoop); - - // add zestcfi symbol to binary - T_Elf_Sym zestcfi_sym; - memset(&zestcfi_sym,0,sizeof(T_Elf_Sym)); - zestcfi_sym.st_name=zestcfi_str_pos; - zestcfi_sym.st_size=1234; - zestcfi_sym.st_info=((STB_GLOBAL<<4)| (STT_FUNC)); - string zestcfi_sym_str((const char*)&zestcfi_sym, sizeof(T_Elf_Sym)); - unsigned int zestcfi_pos=add_to_scoop(zestcfi_sym_str,dynsym_scoop); - - // add "function" for zestcfi" - // for now, return that the target is allowed. the nonce plugin will have to have a slow path for this later. - assert(firp->getArchitectureBitWidth()==64); // fixme for 32-bit, should jmp to ecx. - zestcfi_function_entry=addNewAssembly("jmp r11"); - - // this jump can target any IBT in the module. - // ICFS_t *newicfs=new ICFS_t; - // firp->GetAllICFS().insert(newicfs); - auto newicfs=firp->addNewICFS(); - for(auto insn : firp->getInstructions()) - { - if(insn->getIndirectBranchTargetAddress() != NULL ) - newicfs->insert(insn); - }; - zestcfi_function_entry->setIBTargets(newicfs); - firp->assembleRegistry(); - - - // add a relocation so that the zest_cfi "function" gets pointed to by the symbol - auto zestcfi_reloc=firp->addNewRelocation(dynsym_scoop,zestcfi_pos+((uintptr_t)&zestcfi_sym.st_value - (uintptr_t)&zestcfi_sym), "data_to_insn_ptr", zestcfi_function_entry); - (void)zestcfi_reloc; - - - // update strtabsz after got/etc entries are added. - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) - { - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; - if(dyn_entry.d_tag==DT_STRSZ) - { - dyn_entry.d_un.d_val=dynstr_scoop->getContents().size(); - } - } - - - return true; -} - -template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -bool SCFI_Instrument::add_libdl_as_needed_support() -{ - DataScoopSet_t::iterator it; - // use this to determine whether a scoop has a given name. - - auto dynamic_scoop=find_scoop(firp,".dynamic"); - auto dynstr_scoop=find_scoop(firp,".dynstr"); - auto dynsym_scoop=find_scoop(firp,".dynsym"); - auto relaplt_scoop=find_scoop(firp,".rela.dyn coalesced w/.rela.plt"); - auto relplt_scoop=find_scoop(firp,".rel.dyn coalesced w/.rel.plt"); - - - // they all have to be here, or none are. - assert( (dynamic_scoop==NULL && dynstr_scoop==NULL && dynsym_scoop==NULL ) || - (dynamic_scoop!=NULL && dynstr_scoop!=NULL && dynsym_scoop!=NULL ) - ); - - - // not dynamic executable w/o a .dynamic section. - if(!dynamic_scoop) - return true; - - // may need to enable --step move_globals --step-option move_globals:--cfi - if(relaplt_scoop == NULL && relplt_scoop==NULL) - { - cerr<<"Cannot find relocation-scoop pair: Did you enable '--step move_globals --step-option move_globals:--cfi' ? "<<endl; - exit(1); - } - - assert(relaplt_scoop == NULL || relplt_scoop==NULL); // can't have both - assert(relaplt_scoop != NULL || relplt_scoop!=NULL); // can't have neither - - - auto libld_str_pos=add_to_scoop(string("libzestcfi.so")+'\0', dynstr_scoop); - - - // a new dt_needed entry for libdl.so - T_Elf_Dyn new_dynamic_entry; - memset(&new_dynamic_entry,0,sizeof(new_dynamic_entry)); - new_dynamic_entry.d_tag=DT_NEEDED; - new_dynamic_entry.d_un.d_val=libld_str_pos; - string new_dynamic_entry_str((const char*)&new_dynamic_entry, sizeof(T_Elf_Dyn)); - // a null terminator - T_Elf_Dyn null_dynamic_entry; - memset(&null_dynamic_entry,0,sizeof(null_dynamic_entry)); - string null_dynamic_entry_str((const char*)&null_dynamic_entry, sizeof(T_Elf_Dyn)); - - // declare an entry for the .dynamic section and add it. - int index=0; - while(1) - { - // assert we don't run off the end. - assert((index+1)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()); - - T_Elf_Dyn* dyn_ptr=(T_Elf_Dyn*) & dynamic_scoop->getContents().c_str()[index*sizeof(T_Elf_Dyn)]; - - if(memcmp(dyn_ptr,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ) - { - cout<<"Inserting new DT_NEEDED at index "<<dec<<index<<endl; - // found a null terminator entry. - for(unsigned int i=0; i<sizeof(T_Elf_Dyn); i++) - { - // copy new_dynamic_entry ontop of null entry. - auto str=dynamic_scoop->getContents(); - str[index*sizeof(T_Elf_Dyn) + i ] = ((char*)&new_dynamic_entry)[i]; - dynamic_scoop->setContents(str); - } - - // check if there's room for the new null entry - if((index+2)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()) - { - /* yes */ - T_Elf_Dyn* next_entry=(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[(index+1)*sizeof(T_Elf_Dyn)]; - // assert it's actually null - assert(memcmp(next_entry,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ); - } - else - { - // add to the scoop - add_to_scoop(null_dynamic_entry_str,dynamic_scoop); - } - break; - } - - index++; - } - -#if 0 - cout<<".dynamic contents after scfi update:"<<hex<<endl; - const string &dynstr_contents=dynamic_scoop->getContents(); - for(unsigned int i=0;i<dynstr_contents.size(); i+=16) - { - cout<<*(long long*) &dynstr_contents.c_str()[i] <<" " - <<*(long long*) &dynstr_contents.c_str()[i+8] <<endl; - } -#endif - - return true; - -} - - - -bool SCFI_Instrument::execute() -{ - - bool success=true; - - // this adds an instruction that needs instrumenting by future phases. - // do not move later. - if(do_multimodule) - { - if(firp->getArchitectureBitWidth()==64) - success = success && add_dl_support<Elf64_Sym, Elf64_Rela, Elf64_Dyn, R_X86_64_GLOB_DAT, 32, 8>(); - else - success = success && add_dl_support<Elf32_Sym, Elf32_Rel, Elf32_Dyn, R_386_GLOB_DAT, 8, 4>(); - } - - - // this selects colors and is used in instrument jumps. - // do not move later. - if(do_coloring) - { - color_map.reset(new ColoredInstructionNonces_t(firp, nonce_size)); - assert(color_map); - success = success && color_map->build(); - - } - - if(do_color_exe_nonces) - { - // A separate color map is created for exe nonces so that exe and - // non-exe colored nonces can be different sizes. - // Note that these independent color slots will not conflict with - // the non-exe slots, but ONLY because exe nonces come after a target, - // while non-exe nonces come before. - exe_nonce_color_map.reset(new ColoredInstructionNonces_t(firp, exe_nonce_size)); - assert(exe_nonce_color_map); - success = success && exe_nonce_color_map->build(); - // Note that it is in theory possible (but I'm assuming unlikely) that - // unnecessary colored exe nonce slots will be added due to - // insn's sharing the same IBTs on func ret sites but having - // differing IBT's on non-func ret sites. (Because we reuse the non-exe - // nonce color map, which pays attention to all IBT's and - // not just the IBT's that target func ret sites, yet we are only putting - // exe nonces on func ret sites). - } - - success = success && instrument_jumps(); // to handle moving of relocs properly if - // an insn is both a IBT and a IB, - // we instrument first, then add relocs for targets - - success = success && mark_targets(); // put relocs on all targets so that the backend can put nonces in place. - - return success; -} - - diff --git a/tools/selective_cfi/scfi_instr.hpp b/tools/selective_cfi/scfi_instr.hpp deleted file mode 100644 index caf95929b..000000000 --- a/tools/selective_cfi/scfi_instr.hpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#ifndef scfi_instrument_hpp -#define scfi_instrument_hpp - -#include <irdb-core> -#include <irdb-util> -#include <irdb-transform> -#include "color_map.hpp" -#include <iostream> -#include <iomanip> -#include <memory> - - - -class SCFI_Instrument : public IRDB_SDK::Transform -{ - public: - SCFI_Instrument(IRDB_SDK::FileIR_t *the_firp, - int p_nonce_size=1, - int p_exe_nonce_size=4, - bool p_do_coloring=true, - bool p_do_color_exe_nonces=true, - bool p_do_common_slow_path=true, - bool p_do_jumps=false, - bool p_do_calls=true, - bool p_do_rets=true, - bool p_do_safefn=true, - bool p_do_multimodule=false, - bool p_do_exe_nonce_for_call=false - ) - : - Transform(the_firp), - firp(the_firp), - nonce_size(p_nonce_size), - exe_nonce_size(p_exe_nonce_size), - do_coloring(p_do_coloring), - do_color_exe_nonces(p_do_color_exe_nonces), - do_common_slow_path(p_do_common_slow_path), - do_jumps(p_do_jumps), - do_calls(p_do_calls), - do_rets(p_do_rets), - do_multimodule(p_do_multimodule), - protect_safefn(p_do_safefn), - do_exe_nonce_for_call(p_do_exe_nonce_for_call), - ret_shared(NULL), - zestcfi_function_entry(NULL), - ExecutableNonceValue("\x90", 1), - predsp(IRDB_SDK::InstructionPredecessors_t::factory(firp)), - preds(*predsp) - - { - std::cout<<std::boolalpha; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_coloring="<<p_do_coloring<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_color_exe_nonces="<<p_do_color_exe_nonces<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_common_slow_path="<<p_do_common_slow_path<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_jumps="<<p_do_jumps<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_calls="<<p_do_calls<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_rets="<<p_do_rets<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_safefn="<<p_do_safefn<<std::endl; - std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_multimodule="<<p_do_multimodule<<std::endl; - - } - bool execute(); - - private: // methods - - // helpers for adding GOT entries and symbols for multi-module cfi - template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int B> - bool add_dl_support(); - - template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int B> - bool add_libdl_as_needed_support(); - - template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> - bool add_got_entries(); - - template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> - IRDB_SDK::Instruction_t* find_runtime_resolve(IRDB_SDK::DataScoop_t* gotplt_scoop); - - template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> - void add_got_entry(const std::string& name); - - - - - // find instrumentation points. - bool mark_targets(); - bool instrument_jumps(); - - // helper - IRDB_SDK::Instruction_t* GetExeNonceSlowPath(IRDB_SDK::Instruction_t* insn); - IRDB_SDK::Relocation_t* create_reloc(IRDB_SDK::Instruction_t* insn); - IRDB_SDK::Relocation_t* FindRelocation(IRDB_SDK::Instruction_t* insn, std::string type); - bool isSafeFunction(IRDB_SDK::Instruction_t* insn); - bool isCallToSafeFunction(IRDB_SDK::Instruction_t* insn); - bool is_jmp_a_fixed_call(IRDB_SDK::Instruction_t* insn); - bool is_plt_style_jmp(IRDB_SDK::Instruction_t* insn); - - - - // add instrumentation - bool add_scfi_instrumentation(IRDB_SDK::Instruction_t* insn); - bool needs_scfi_instrumentation(IRDB_SDK::Instruction_t* insn); - - // return instrumentation - void AddReturnCFI(IRDB_SDK::Instruction_t* insn, ColoredSlotValue_t *v=NULL); - void AddReturnCFIForExeNonce(IRDB_SDK::Instruction_t* insn, ColoredSlotValue_t *v=NULL); - - // jump instrumentation - void AddJumpCFI(IRDB_SDK::Instruction_t* insn); - - // call instrumentation with executable nonce - void AddCallCFIWithExeNonce(IRDB_SDK::Instruction_t* insn); - - // for all calls - void AddExecutableNonce(IRDB_SDK::Instruction_t* insn); - - // Nonce Manipulation. - NonceValueType_t GetNonce(IRDB_SDK::Instruction_t* insn); - unsigned int GetNonceSize(IRDB_SDK::Instruction_t* insn); - unsigned int GetNonceOffset(IRDB_SDK::Instruction_t*); - - unsigned int GetExeNonceOffset(IRDB_SDK::Instruction_t* insn); - NonceValueType_t GetExeNonce(IRDB_SDK::Instruction_t* insn); - unsigned int GetExeNonceSize(IRDB_SDK::Instruction_t* insn); - - - private: // data - // predecessors of instructions. - IRDB_SDK::FileIR_t* firp; - const int nonce_size; - const int exe_nonce_size; - const bool do_coloring; - const bool do_color_exe_nonces; - const bool do_common_slow_path; - const bool do_jumps; - const bool do_calls; - const bool do_rets; - const bool do_multimodule; - const bool protect_safefn; - const bool do_exe_nonce_for_call; - std::unique_ptr<ColoredInstructionNonces_t> color_map; - std::unique_ptr<ColoredInstructionNonces_t> exe_nonce_color_map; - const IRDB_SDK::Instruction_t *ret_shared; - IRDB_SDK::Instruction_t *zestcfi_function_entry; - std::string ExecutableNonceValue; - - // Exe Nonce helpers - const int EXE_NONCE_OPCODE_SIZE = 3; - // Enter opcode val in reverse-byte order, as nonce_relocs reverses the bytes before placement - // (The nonce values themselves are placed little endian, but the opcode should be placed big-endian) - const int EXE_NONCE_OPCODE_VAL = 0x801F0F; // actual opcode = 0x0F1F80 - const int EXE_NONCE_ARG_SIZE = 4; - /* Nonces are just bit strings. To fit them into exe - * nonces that have a limited argument size, they may need to - * be split over more than one exe nonce. To be stored as tightly - * as possible, more than one nonce may be fit into one exe nonce. - * - * To handle this, the GetExeNonceFit function returns a list - * of one or more NonceParts that together specify where in memory - * the complete nonce string is located. */ - struct NoncePart_t { - NonceValueType_t val; - int bytePos; - int size; - }; - /* CRITICAL ASSUMPTIONS: - * 1.) The exe nonce being used is constant throughout the module. - * (It's opcode size, argument size, and opcode value should be constant). - * 2.) No nonce is split across exe nonces unless it completely fills all of them. - * (i.e. nonceSize % argSize == 0 OR argSize % nonceSize == 0). - */ - std::vector<NoncePart_t> GetExeNonceFit(NonceValueType_t nonceVal, int nonceSz, int noncePos); - int GetNonceBytePos(int nonceSz, int noncePos); - void CreateExeNonceReloc(IRDB_SDK::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int bytePos); - void PlaceExeNonceReloc(IRDB_SDK::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int noncePos); - void InsertExeNonceComparisons(IRDB_SDK::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, - int noncePos, IRDB_SDK::Instruction_t* exeNonceSlowPath ); - - - void mov_reloc(IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to, std::string type ); - void move_relocs(IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to); - - std::unique_ptr<IRDB_SDK::InstructionPredecessors_t> predsp; - IRDB_SDK::InstructionPredecessors_t &preds; - -}; - -#endif diff --git a/tools/selective_cfi/tests/cfi_all_configs.sh b/tools/selective_cfi/tests/cfi_all_configs.sh deleted file mode 100755 index 33767757c..000000000 --- a/tools/selective_cfi/tests/cfi_all_configs.sh +++ /dev/null @@ -1,444 +0,0 @@ -#!/bin/bash - -configs=(do_cfi - do_cfi_2_byte - do_cfi_4_byte - do_cfi_8_byte - do_coloring_cfi - do_coloring_cfi_2_byte - do_coloring_cfi_4_byte - do_coloring_cfi_8_byte - do_cfi_exe_nonces - do_cfi_exe_nonces_1_byte - do_cfi_exe_nonces_2_byte - do_cfi_exe_nonces_8_byte - do_cfi_exe_nonces_2_byte_non_exe - do_cfi_exe_nonces_4_byte_non_exe - do_cfi_exe_nonces_8_byte_non_exe - do_cfi_exe_nonces_1_byte_2_byte_non_exe - do_cfi_exe_nonces_1_byte_4_byte_non_exe - do_cfi_exe_nonces_1_byte_8_byte_non_exe - do_cfi_exe_nonces_2_byte_2_byte_non_exe - do_cfi_exe_nonces_2_byte_4_byte_non_exe - do_cfi_exe_nonces_2_byte_8_byte_non_exe - do_cfi_exe_nonces_8_byte_2_byte_non_exe - do_cfi_exe_nonces_8_byte_4_byte_non_exe - do_cfi_exe_nonces_8_byte_8_byte_non_exe - do_cfi_exe_nonces_color_non_exe - do_cfi_exe_nonces_1_byte_color_non_exe - do_cfi_exe_nonces_2_byte_color_non_exe - do_cfi_exe_nonces_8_byte_color_non_exe - do_cfi_exe_nonces_2_byte_non_exe_color_non_exe - do_cfi_exe_nonces_4_byte_non_exe_color_non_exe - do_cfi_exe_nonces_8_byte_non_exe_color_non_exe - do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_non_exe - do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_non_exe - do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_non_exe - do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_non_exe - do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_non_exe - do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_non_exe - do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_non_exe - do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_non_exe - do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_non_exe - do_cfi_exe_nonces_color_exe - do_cfi_exe_nonces_1_byte_color_exe - do_cfi_exe_nonces_2_byte_color_exe - do_cfi_exe_nonces_8_byte_color_exe - do_cfi_exe_nonces_2_byte_non_exe_color_exe - do_cfi_exe_nonces_4_byte_non_exe_color_exe - do_cfi_exe_nonces_8_byte_non_exe_color_exe - do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_exe - do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_exe - do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_exe - do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_exe - do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_exe - do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_exe - do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_exe - do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_exe - do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_exe - do_cfi_exe_nonces_color_both - do_cfi_exe_nonces_1_byte_color_both - do_cfi_exe_nonces_2_byte_color_both - do_cfi_exe_nonces_8_byte_color_both - do_cfi_exe_nonces_2_byte_non_exe_color_both - do_cfi_exe_nonces_4_byte_non_exe_color_both - do_cfi_exe_nonces_8_byte_non_exe_color_both - do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_both - do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_both - do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_both - do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_both - do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_both - do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_both - do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_both - do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_both - do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_both) - -do_cfi() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false") -} - -do_cfi_2_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2") -} - -do_cfi_4_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4") -} - -do_cfi_8_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8") -} - -############################################################################### - -do_coloring_cfi() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false") -} - -do_coloring_cfi_2_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2") -} - -do_coloring_cfi_4_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4") -} - -do_coloring_cfi_8_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8") -} - -############################################################################### - -do_cfi_exe_nonces() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false") -} - -do_cfi_exe_nonces_1_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1") -} - -do_cfi_exe_nonces_2_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2") -} - -do_cfi_exe_nonces_8_byte() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8") -} - -do_cfi_exe_nonces_2_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2") -} - -do_cfi_exe_nonces_4_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4") -} - -do_cfi_exe_nonces_8_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8") -} - -do_cfi_exe_nonces_1_byte_2_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2") -} - -do_cfi_exe_nonces_1_byte_4_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4") -} - -do_cfi_exe_nonces_1_byte_8_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8") -} - -do_cfi_exe_nonces_2_byte_2_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2") -} - -do_cfi_exe_nonces_2_byte_4_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4") -} - -do_cfi_exe_nonces_2_byte_8_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8") -} - -do_cfi_exe_nonces_8_byte_2_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2") -} - -do_cfi_exe_nonces_8_byte_4_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4") -} - -do_cfi_exe_nonces_8_byte_8_byte_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8") -} - -############################################################################### - -do_cfi_exe_nonces_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_4_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_non_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) -} - -############################################################################### - -do_cfi_exe_nonces_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_1_byte_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_2_byte_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_8_byte_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_2_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_4_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_8_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) -} - -do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_exe() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) -} - -############################################################################### - -do_cfi_exe_nonces_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_4_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} - -do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_both() -{ - (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) -} diff --git a/tools/selective_cfi/tests/cfi_smokescreen_configs.sh b/tools/selective_cfi/tests/cfi_smokescreen_configs.sh deleted file mode 100755 index 8b5d6d2e6..000000000 --- a/tools/selective_cfi/tests/cfi_smokescreen_configs.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - - -configs=(do_cfi_4_byte - do_coloring_cfi_4_byte - do_cfi_exe_nonces_1_byte - do_cfi_exe_nonces - do_cfi_exe_nonces_4_byte_non_exe_color_non_exe - do_cfi_exe_nonces_8_byte - do_cfi_exe_nonces_1_byte_color_exe - do_cfi_exe_nonces_color_exe - do_cfi_exe_nonces_8_byte_color_exe - do_cfi_exe_nonces_4_byte_non_exe_color_both) - - -do_cfi_4_byte() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" -} - -do_coloring_cfi_4_byte() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" -} - -do_cfi_exe_nonces_1_byte() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" -} - -do_cfi_exe_nonces() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" -} - -do_cfi_exe_nonces_4_byte_non_exe_color_non_exe() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color -} - -do_cfi_exe_nonces_8_byte() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" -} - -do_cfi_exe_nonces_1_byte_color_exe() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces -} - -do_cfi_exe_nonces_color_exe() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces -} - -do_cfi_exe_nonces_8_byte_color_exe() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces -} - -do_cfi_exe_nonces_4_byte_non_exe_color_both() -{ - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color -} diff --git a/tools/selective_cfi/tests/cicd_tests/fib_src/fib.c b/tools/selective_cfi/tests/cicd_tests/fib_src/fib.c deleted file mode 100644 index 15a198c03..000000000 --- a/tools/selective_cfi/tests/cicd_tests/fib_src/fib.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <stdio.h> - -extern int fib(); -extern int fib2(); -extern int fibp(int n, int (*)(int,int)); - -int add(int n1, int n2) -{ - if (n1 == 0) - return n2; - else if (n2 == 0) - return n1; - else if (n1 == 2) - return add(1, add(1, n2)); - else - return n1 + add(0, n2); -} - -main(int argc, char **argv) -{ - int x = 3; - int f = 0; - if (argc >= 2) - x = atoi(argv[1]); - - if (x <= 2) - f = fib_main(x); - if (x == 3) - f = fib2(x); - else if (x == 4) - f = fib_simple(x); - else if (x == 5) - f = fibp(x, &add); - else - f = fib(x); - printf("Fibonacci(%d) = %d\n", x, f); - - return f; -} - -fib_main(int f) { - if (f <= 2) - return 1; - else - return fib_simple(f-1) + fib_main(f-2); -} - -fib_simple(int f) { - if (f <= 2) - return 1; - else - return fib_simple(f-1) + fib_simple(f-2); -} diff --git a/tools/selective_cfi/tests/cicd_tests/fib_src/libfib.c b/tools/selective_cfi/tests/cicd_tests/fib_src/libfib.c deleted file mode 100644 index 75fbd864e..000000000 --- a/tools/selective_cfi/tests/cicd_tests/fib_src/libfib.c +++ /dev/null @@ -1,32 +0,0 @@ -extern int fib_main(); -extern int fib2(); -extern int fib2p(int n, int (*)(int,int)); - -int add2(int n1, int n2) -{ - if (n1 == 0) - return n2; - else if (n2 == 0) - return n1; - else if (n2 == 2) - return add2(add2(n1, 1),1); - else - return add2(0, n2) + add2(n1, 0); -} - -int fib(int n) -{ - if (n <= 2) - return 1; - else - return fib_main(n-1) + fib2(n-2); - -} - -int fibp(int n, int (*addp)(int,int)) -{ - if (n <= 2) - return 1; - else - return (*addp)(fib_main(n-1),fib2p(n-2,&add2)); -} diff --git a/tools/selective_cfi/tests/cicd_tests/fib_src/libfib2.c b/tools/selective_cfi/tests/cicd_tests/fib_src/libfib2.c deleted file mode 100644 index c64383522..000000000 --- a/tools/selective_cfi/tests/cicd_tests/fib_src/libfib2.c +++ /dev/null @@ -1,18 +0,0 @@ -extern int fib_main(); -extern int fib(); - -int fib2(int n) -{ - if (n <= 2) - return 1; - else - return fib2(n-1) + fib_main(n-2); -} - -int fib2p(int n, int (*addp)(int,int)) -{ - if (n <= 2) - return (*addp)(1,0); - else - return (*addp)(fib2(n-1),fib2p(n-2, addp)); -} diff --git a/tools/selective_cfi/tests/cicd_tests/foo_src/foo.c b/tools/selective_cfi/tests/cicd_tests/foo_src/foo.c deleted file mode 100644 index d0c95ea86..000000000 --- a/tools/selective_cfi/tests/cicd_tests/foo_src/foo.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - -extern int foo(); - -int main() -{ - foo(); -} - -int foo2() -{ - printf("In foo2\n"); -} diff --git a/tools/selective_cfi/tests/cicd_tests/foo_src/libfoo.c b/tools/selective_cfi/tests/cicd_tests/foo_src/libfoo.c deleted file mode 100644 index 2d83d2ef2..000000000 --- a/tools/selective_cfi/tests/cicd_tests/foo_src/libfoo.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <math.h> -#include <stdio.h> -#include <stdint.h> - -int bar() -{ - printf("in bar\n"); -} -int foo() -{ - printf("in foo\n"); - foo2(); -} - diff --git a/tools/selective_cfi/tests/manual_tests/dude.c b/tools/selective_cfi/tests/manual_tests/dude.c deleted file mode 100644 index 7251ce4ba..000000000 --- a/tools/selective_cfi/tests/manual_tests/dude.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - -extern int dude(); - -int main() -{ - dude(); -} - -void foo2() -{ - printf("In foo2()\n"); -} diff --git a/tools/selective_cfi/tests/manual_tests/fib.c b/tools/selective_cfi/tests/manual_tests/fib.c deleted file mode 100644 index 15a198c03..000000000 --- a/tools/selective_cfi/tests/manual_tests/fib.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <stdio.h> - -extern int fib(); -extern int fib2(); -extern int fibp(int n, int (*)(int,int)); - -int add(int n1, int n2) -{ - if (n1 == 0) - return n2; - else if (n2 == 0) - return n1; - else if (n1 == 2) - return add(1, add(1, n2)); - else - return n1 + add(0, n2); -} - -main(int argc, char **argv) -{ - int x = 3; - int f = 0; - if (argc >= 2) - x = atoi(argv[1]); - - if (x <= 2) - f = fib_main(x); - if (x == 3) - f = fib2(x); - else if (x == 4) - f = fib_simple(x); - else if (x == 5) - f = fibp(x, &add); - else - f = fib(x); - printf("Fibonacci(%d) = %d\n", x, f); - - return f; -} - -fib_main(int f) { - if (f <= 2) - return 1; - else - return fib_simple(f-1) + fib_main(f-2); -} - -fib_simple(int f) { - if (f <= 2) - return 1; - else - return fib_simple(f-1) + fib_simple(f-2); -} diff --git a/tools/selective_cfi/tests/manual_tests/foo.c b/tools/selective_cfi/tests/manual_tests/foo.c deleted file mode 100644 index d0c95ea86..000000000 --- a/tools/selective_cfi/tests/manual_tests/foo.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - -extern int foo(); - -int main() -{ - foo(); -} - -int foo2() -{ - printf("In foo2\n"); -} diff --git a/tools/selective_cfi/tests/manual_tests/libc_driver.c b/tools/selective_cfi/tests/manual_tests/libc_driver.c deleted file mode 100644 index 38ebfd514..000000000 --- a/tools/selective_cfi/tests/manual_tests/libc_driver.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <stdio.h> - -main() -{ - printf("hello world\n"); -} diff --git a/tools/selective_cfi/tests/manual_tests/libdude.c b/tools/selective_cfi/tests/manual_tests/libdude.c deleted file mode 100644 index 778cd09b7..000000000 --- a/tools/selective_cfi/tests/manual_tests/libdude.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <stdio.h> - -void dude() -{ - printf("in dude\n"); - foo(); -} - diff --git a/tools/selective_cfi/tests/manual_tests/libfib.c b/tools/selective_cfi/tests/manual_tests/libfib.c deleted file mode 100644 index 75fbd864e..000000000 --- a/tools/selective_cfi/tests/manual_tests/libfib.c +++ /dev/null @@ -1,32 +0,0 @@ -extern int fib_main(); -extern int fib2(); -extern int fib2p(int n, int (*)(int,int)); - -int add2(int n1, int n2) -{ - if (n1 == 0) - return n2; - else if (n2 == 0) - return n1; - else if (n2 == 2) - return add2(add2(n1, 1),1); - else - return add2(0, n2) + add2(n1, 0); -} - -int fib(int n) -{ - if (n <= 2) - return 1; - else - return fib_main(n-1) + fib2(n-2); - -} - -int fibp(int n, int (*addp)(int,int)) -{ - if (n <= 2) - return 1; - else - return (*addp)(fib_main(n-1),fib2p(n-2,&add2)); -} diff --git a/tools/selective_cfi/tests/manual_tests/libfib2.c b/tools/selective_cfi/tests/manual_tests/libfib2.c deleted file mode 100644 index c64383522..000000000 --- a/tools/selective_cfi/tests/manual_tests/libfib2.c +++ /dev/null @@ -1,18 +0,0 @@ -extern int fib_main(); -extern int fib(); - -int fib2(int n) -{ - if (n <= 2) - return 1; - else - return fib2(n-1) + fib_main(n-2); -} - -int fib2p(int n, int (*addp)(int,int)) -{ - if (n <= 2) - return (*addp)(1,0); - else - return (*addp)(fib2(n-1),fib2p(n-2, addp)); -} diff --git a/tools/selective_cfi/tests/manual_tests/libfoo.c b/tools/selective_cfi/tests/manual_tests/libfoo.c deleted file mode 100644 index 2d83d2ef2..000000000 --- a/tools/selective_cfi/tests/manual_tests/libfoo.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <math.h> -#include <stdio.h> -#include <stdint.h> - -int bar() -{ - printf("in bar\n"); -} -int foo() -{ - printf("in foo\n"); - foo2(); -} - diff --git a/tools/selective_cfi/tests/manual_tests/pow.c b/tools/selective_cfi/tests/manual_tests/pow.c deleted file mode 100644 index d2fe0c58b..000000000 --- a/tools/selective_cfi/tests/manual_tests/pow.c +++ /dev/null @@ -1,19 +0,0 @@ - -#include <stdio.h> -#include <math.h> - -main(int argc, char* argv[]) -{ - if(argc<3) - { - printf("Need two parameters...\n"); - return 1; - } - - int i=0; - for(i=0; i<3; i++) - { - printf("%s ^ %s = %f\n", argv[1], argv[2], pow(atoi(argv[1]), atoi(argv[2]))); - printf("%s ^ %s = %f\n", argv[1], argv[2], pow(atoi(argv[1]), atoi(argv[2]))); - } -} diff --git a/tools/selective_cfi/tests/manual_tests/test_coreutils.sh b/tools/selective_cfi/tests/manual_tests/test_coreutils.sh deleted file mode 100755 index 20eb3356b..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_coreutils.sh +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/bash - -check_fail() -{ - res=$3 - if [ $res != 0 ]; - then - echo - echo "Failed trying to protect $1" - cat $2.ps_output - failures="$1 $2 " $'\n' "$failures" - fi -} - -do_nocfi() -{ - if [ -e $2 ]; then - echo -n "$(basename $2) exists ... " - return - fi - echo -n "$(basename $2) ... " - $PS $1 $2 --backend zipr > $2.ps_output 2>&1 - check_fail $1 $2 $? -} - -do_cfi() -{ - if [ -e $2 ]; then - echo -n "$(basename $2) exists ... " - return - fi - echo -n "$(basename $2) ... " - $PS $1 $2 --backend zipr --step move_globals=on --step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" > $2.ps_output 2>&1 - check_fail $1 $2 $? -} - -do_coloring_cfi() -{ - if [ -e $2 ]; then - echo -n "$(basename $2) exists ... " - return - fi - echo -n "$(basename $2) ... " - $PS $1 $2 --backend zipr --step move_globals=on --step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false"> $2.ps_output 2>&1 - check_fail $1 $2 $? - -} - - -get_source() -{ - echo -n "Getting coreutils source ... " - utils_dir=$(ls -d coreutils-*.*/ 2> /dev/null) - if [ ! -d "$utils_dir" ]; then - apt-get source coreutils - fi - utils_dir=$(ls -d coreutils-*.*/) - - if [ ! -d "$utils_dir" ]; then - echo could/locate coreutils source - exit 1 - fi - echo "done!" -} - -build_source() -{ - echo -n "Building coreutils source ... " - cd $utils_dir - if [ ! -f Makefile ]; then - ./configure - fi - - make > coreutils.make.out - res=$? - - if [ $res != 0 ]; then - echo "Coreutils Build Failed!" - fi - - cd $start_dir - - echo "done!" - -} - -analyze() -{ - echo -n "Finding executables .... " - candidate_exes=$(find $utils_dir/src -executable ) - for candidate_exe in $candidate_exes - do - if [ -d "$candidate_exe" ]; then - #echo skipping dir $candidate_exe - continue; - fi - if [[ "$candidate_exe" == *.orig || "$candidate_exe" == *cfi ]]; then - #echo skipping orig exe $candidate_exe - continue; - fi - file $candidate_exe |grep ELF > /dev/null 2>&1 - res=${PIPESTATUS[1]} - - if [ $res != 0 ]; then - continue; - fi - - exes="$exes $candidate_exe" - - load_sec_no=$(readelf -l $candidate_exe|grep LOAD|wc -l) - - # save/verify .orig version already exists. - if [ $load_sec_no == 2 ]; then - # save .orig - cp $candidate_exe $candidate_exe.orig - else - # ensure .orig already exists. - if [ ! -x $candidate_exe.orig ]; then - echo "Missing $candidate_exe! Cannot continue ...." - exit 1 - fi - fi - done - echo "Done!" - echo "Found $(echo $exes |wc -w) coreutil executables" -} - -protect() -{ - for exe in $exes - do - echo -n "Protecting $(basename $exe) ... " - do_nocfi $exe.orig $exe.nocfi - do_cfi $exe.orig $exe.cfi - do_coloring_cfi $exe.orig $exe.colorcfi - echo "Done!" - done -} - -install_set() -{ - ext=$1 - for exe in $exes - do - if [ ! $exe.$ext ]; then echo "Cannot test $exe.ext -- Missing file!"; fi - cp $exe.$ext $exe - done -} - -test_coreutils() -{ - ext=$1 - outfile=results.$ext.txt - if [ ! -f $outfile ]; then - install_set $ext - cd $utils_dir - echo -n "Testing $ext ... " - SECONDS=0 - make check > ../$outfile 2>&1 - duration=$SECONDS - echo "Elapsed time: $(($duration / 60)) minutes and $(($duration % 60)) "\ - "seconds ($duration seconds total)." >> ../$outfile - - echo "Done!" - cd $start_dir - fi - - echo - echo Results for $ext - tail -100 $outfile | sed -n '/==================/,/=====================/p'| sed "s/^/ /" - tail -1 $outfile| sed "s/^/ /" - -} - -clean() -{ - if [ -d $utils_dir ]; then - rm -Rf $utils_dir - fi - -} - -get_size_results() -{ - echo "---------------------------------------------" - echo "Size of files are: " - echo "---------------------------------------------" - - for exe in $exes - do - cp $exe.orig $exe.stripped - strip $exe.stripped - done - - extensions="$*" - echo Executable $extensions - for exe in $exes - do - echo -n "$(basename $exe) " - - for ext in $extensions - do - if [ ! $exe.$ext ]; then - echo -n "N/A " - else - size=$(stat --printf="%s" $exe.$ext) - echo -n "$size " - fi - done - echo - done - echo -} - -main() -{ - start_dir=$(pwd) - get_source - build_source - analyze - install_set orig - protect - test_coreutils orig - test_coreutils nocfi - test_coreutils cfi - test_coreutils colorcfi - get_size_results orig stripped nocfi cfi colorcfi - - - echo "Protection failures: $failures" -} - -main "$@" - diff --git a/tools/selective_cfi/tests/manual_tests/test_dude.sh b/tools/selective_cfi/tests/manual_tests/test_dude.sh deleted file mode 100755 index d56ae5e7f..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_dude.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -source ../cfi_all_configs.sh - -get_correct() -{ - cp libfoo.so.orig libfoo.so - cp libdude.so.orig libdude.so - ./dude.exe > correct 2>&1 -} - -test() -{ - local fail=0 - cp $2 libfoo.so || fail=1 - cp $3 libdude.so || fail=1 - ./$1 > out 2>&1 - - cmp out correct - if [[ $? = 1 ]] || [[ $fail = 1 ]] ; then - fails=$(expr $fails + 1 ) - echo test failed $1 $2 $3 | tee -a dude_test_log.txt - echo "=== out ===" - cat out - echo "======" - else - passes=$(expr $passes + 1 ) - echo test passed. - fi -} - - -build() -{ - gcc -o libfoo.so libfoo.c -w -shared -fPIC - gcc -o libdude.so libdude.c -w -shared -fPIC - gcc -o dude.exe dude.c -w -L. -ldude -lfoo - gcc -o dude.exe.pie dude.c -fPIC -fpie -pie -w -L. -ldude -lfoo - mv libfoo.so libfoo.so.orig - mv libdude.so libdude.so.orig -} - - -protect() -{ - files=(dude.exe dude.exe.pie libfoo.so.orig libdude.so.orig) - - dude_exe_varients=(dude.exe) - dude_exe_pie_varients=(dude.exe.pie) - libfoo_so_orig_varients=(libfoo.so.orig) - libdude_so_orig_varients=(libdude.so.orig) - - for file in "${files[@]}"; do - for config in "${configs[@]}"; do - echo Protecting file "$file" with config "$config" | tee -a dude_protection_log.txt - "$config" ./"$file" ./"$file"".""$config" | tee -a dude_protection_log.txt - varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" - varient_file="$file"".""$config" - eval $varient_array_name+=\(\$varient_file\) - done - done -} - -clean() -{ - rm out - rm correct - rm -Rf dude.exe* peasoup_exe* lib*.so* - - for config in "${configs[@]}"; do - rm *."$config" - done -} - -report () -{ - total=$(expr $passes + $fails) - echo "Passes: $passes / $total" | tee -a dude_test_log.txt - echo "Fails : $fails / $total" | tee -a dude_test_log.txt - - if grep -q "Warning " ./dude_protection_log.txt - then - echo PROTECTION WARNINGS DETECTED! - else - echo ALL PROTECTIONS SUCCESSFUL - fi -} - -main() -{ - build - protect - get_correct - - dude_varients=("${dude_exe_varients[@]}" "${dude_exe_pie_varients[@]}") - - for dude_varient in "${dude_varients[@]}"; do - for libfoo_varient in "${libfoo_so_orig_varients[@]}"; do - for libdude_varient in "${libdude_so_orig_varients[@]}"; do - test "$dude_varient" "$libfoo_varient" "$libdude_varient" - done - done - done - - - report - if [[ $1 == "-k" ]] ; then - echo "Skipping cleanup" - else - clean - fi -} - -passes=0 -fails=0 - -main $* - diff --git a/tools/selective_cfi/tests/manual_tests/test_fib.sh b/tools/selective_cfi/tests/manual_tests/test_fib.sh deleted file mode 100755 index 71a7377fa..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_fib.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/bash - -source ../cfi_all_configs.sh - -get_correct() -{ - cp libfib.so.orig libfib.so - cp libfib2.so.orig libfib2.so - ./fib.exe $1 > correct - echo $? >> correct -} - -test() -{ - n=$2 - - get_correct $n - - cp $3 libfib.so - cp $4 libfib2.so - ./$1 $n > out - echo $? >> out - - cmp out correct - if [ $? = 1 ]; then - fails=$(expr $fails + 1 ) - echo test failed $1 $2 $3 $4 | tee -a fib_test_log.txt - echo "=== out ===" - cat out - echo "======" - echo "exiting" - #clean - exit 1 - else - passes=$(expr $passes + 1 ) - echo test passed. - fi -} - - -build() -{ - gcc -o libfib.so libfib.c -w -shared -fPIC - gcc -o libfib2.so libfib2.c -w -shared -fPIC - gcc -o fib.exe fib.c -w -L. -lfib -lfib2 - gcc -o fib.exe.pie fib.c -fPIC -fpie -pie -w -L. -lfib -lfib2 - mv libfib.so libfib.so.orig - mv libfib2.so libfib2.so.orig -} - - -protect() -{ - files=(libfib.so.orig libfib2.so.orig fib.exe fib.exe.pie) - - libfib_so_orig_varients=(libfib.so.orig) - libfib2_so_orig_varients=(libfib2.so.orig) - fib_exe_varients=(fib.exe) - fib_exe_pie_varients=(fib.exe.pie) - - for file in "${files[@]}"; do - for config in "${configs[@]}"; do - echo Protecting file "$file" with config "$config" | tee -a fib_protection_log.txt - "$config" ./"$file" ./"$file"".""$config" | tee -a fib_protection_log.txt - varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" - varient_file="$file"".""$config" - eval $varient_array_name+=\(\$varient_file\) - done - done -} - -clean() -{ - rm -f out - rm -f correct - rm -Rf fib.exe* peasoup_exe* lib*.so* - - for config in "${configs[@]}"; do - rm -f *."$config" - done -} - -report () -{ - total=$(expr $passes + $fails) - echo "Passes: $passes / $total" | tee -a fib_test_log.txt - echo "Fails : $fails / $total" | tee -a fib_test_log.txt - - if grep -q "Warning " ./fib_protection_log.txt - then - echo PROTECTION WARNINGS DETECTED! - else - echo ALL PROTECTIONS SUCCESSFUL - fi -} - -main() -{ - build - protect - - fib_varients=("${fib_exe_varients[@]}" "${fib_exe_pie_varients[@]}") - - for fib_varient in "${fib_varients[@]}"; do - for libfib_varient in "${libfib_so_orig_varients[@]}"; do - for libfib2_varient in "${libfib2_so_orig_varients[@]}"; do - for i in {2...6}; do - test "$fib_varient" $i "$libfib_varient" "$libfib2_varient" - done - done - done - done - - report - clean -} - -passes=0 -fails=0 - -main $* diff --git a/tools/selective_cfi/tests/manual_tests/test_foo.sh b/tools/selective_cfi/tests/manual_tests/test_foo.sh deleted file mode 100755 index 26cc9e2a9..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_foo.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -source ../cfi_all_configs.sh - -get_correct() -{ - cp libfoo.so.orig libfoo.so - ./foo.exe > correct -} - -test() -{ - - cp $2 libfoo.so - ./$1 > out - - cmp out correct - if [ $? = 1 ]; then - fails=$(expr $fails + 1 ) - echo test "$1" "$2" failed | tee -a foo_test_log.txt - else - passes=$(expr $passes + 1 ) - echo test passed. - fi -} - - -build() -{ - gcc -o libfoo.so libfoo.c -w -shared -fPIC - gcc -o foo.exe foo.c -w -L. -lfoo - mv libfoo.so libfoo.so.orig - - gcc -o libfoo.O.so libfoo.c -O -w -shared -fPIC - gcc -o libfoo.O2.so libfoo.c -O2 -w -shared -fPIC - gcc -o libfoo.O3.so libfoo.c -O3 -w -shared -fPIC - gcc -o libfoo.Os.so libfoo.c -Os -w -shared -fPIC - mv libfoo.O.so libfoo.O.so.orig - mv libfoo.O2.so libfoo.O2.so.orig - mv libfoo.O3.so libfoo.O3.so.orig - mv libfoo.Os.so libfoo.Os.so.orig -} - - -protect() -{ - files=(foo.exe libfoo.so.orig libfoo.O.so.orig libfoo.O2.so.orig libfoo.O3.so.orig libfoo.Os.so.orig) - - foo_exe_varients=(foo.exe) - libfoo_so_orig_varients=(libfoo.so.orig) - libfoo_O_so_orig_varients=(libfoo.O.so.orig) - libfoo_O2_so_orig_varients=(libfoo.O2.so.orig) - libfoo_O3_so_orig_varients=(libfoo.O3.so.orig) - libfoo_Os_so_orig_varients=(libfoo.Os.so.orig) - - for file in "${files[@]}"; do - for config in "${configs[@]}"; do - echo Protecting file "$file" with config "$config" | tee -a foo_protection_log.txt - "$config" ./"$file" ./"$file"".""$config" | tee -a foo_protection_log.txt - varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" - varient_file="$file"".""$config" - eval $varient_array_name+=\(\$varient_file\) - done - done - -} - -clean() -{ - rm out - rm correct - rm -rf peasoup_executable_directory.* - rm *.orig - rm *.exe - rm *.so - - for config in "${configs[@]}"; do - rm *."$config" - done -} - -report () -{ - total=$(expr $passes + $fails) - echo "Passes: $passes / $total" | tee -a foo_test_log.txt - echo "Fails : $fails / $total" | tee -a foo_test_log.txt - - if grep -q "Warning " ./foo_protection_log.txt - then - echo PROTECTION WARNINGS DETECTED! - else - echo ALL PROTECTIONS SUCCESSFUL - fi -} - -main() -{ - build - protect - get_correct - - libfoo_varients=("${libfoo_so_orig_varients[@]}" "${libfoo_O_so_orig_varients[@]}" "${libfoo_O2_so_orig_varients[@]}" - "${libfoo_O3_so_orig_varients[@]}" "${libfoo_Os_so_orig_varients[@]}") - - - for foo_varient in "${foo_exe_varients[@]}"; do - for libfoo_varient in "${libfoo_varients[@]}"; do - test "$foo_varient" "$libfoo_varient" - done - done - - report - clean -} - -passes=0 -fails=0 - -main $* diff --git a/tools/selective_cfi/tests/manual_tests/test_libc.sh b/tools/selective_cfi/tests/manual_tests/test_libc.sh deleted file mode 100755 index 7079c2ba7..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_libc.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash - -libcpath="" - - -source ../cfi_all_configs.sh - - -get_correct() -{ - echo "get_correct()" - ./libc_driver.exe $* > correct -} - -test() -{ - libc=$2 - pgm=$1 - shift 2 - - LD_PRELOAD=$2 ./$pgm $* > out - - cmp out correct - if [ $? = 1 ]; then - fails=$(expr $fails + 1 ) - echo test $pgm $libc failed | tee -a libc_test_log.txt - else - passes=$(expr $passes + 1 ) - echo test passed. - fi -} - - -build() -{ - gcc -o libc_driver.exe libc_driver.c -w - - libcpath=$(ldd libc_driver.exe|grep libc.so.6|sed "s/.*=>//"|sed "s/(.*//") - echo libc=$libcpath - cp $libcpath libc.so.6.orig -} - - -protect() -{ - files=(libc_driver.exe libc.so.6.orig) - - libc_driver_exe_varients=(libc_driver.exe) - libc_so_6_orig_varients=(libc.so.6.orig) - - for file in "${files[@]}"; do - for config in "${configs[@]}"; do - echo Protecting file "$file" with config "$config" | tee -a libc_protection_log.txt - "$config" ./"$file" ./"$file"".""$config" | tee -a libc_protection_log.txt - varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" - varient_file="$file"".""$config" - eval $varient_array_name+=\(\$varient_file\) - done - done -} - -clean() -{ - rm out - rm correct - rm -Rf *.orig *libc*.exe *libc.*cfi *peasoup_exec* - - for config in "${configs[@]}"; do - rm *."$config" - done -} - -report () -{ - total=$(expr $passes + $fails) - echo "Passes: $passes / $total" | tee -a libc_test_log.txt - echo "Fails : $fails / $total" | tee -a libc_test_log.txt -} - -main() -{ - build - protect - get_correct - - for libc_driver_varient in "${libc_driver_exe_varients[@]}"; do - for libc_varient in "${libc_so_6_orig_varients[@]}"; do - test "$libc_driver_varient" "$libc_varient" - done - done - - report - clean -} - -passes=0 -fails=0 - -main $* diff --git a/tools/selective_cfi/tests/manual_tests/test_pow.sh b/tools/selective_cfi/tests/manual_tests/test_pow.sh deleted file mode 100755 index af6ea58e0..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_pow.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - - -source ../cfi_all_configs.sh - - -get_correct() -{ - cp libm.so.6.orig libm.so.6 - ./pow.exe $* > correct -} - -test() -{ - exe=$1 - shift - lib=$1 - shift - - get_correct $1 $2 - - local fail=0 - cp $lib libm.so.6 || fail=1 - ./$exe $* > out - - cmp out correct - if [[ $? = 1 ]] || [[ $fail = 1 ]] ; then - fails=$(expr $fails + 1 ) - echo test $exe $lib $1 $2 failed | tee -a pow_test_log.txt - else - passes=$(expr $passes + 1 ) - echo test passed. - fi -} - - -build() -{ - gcc -o pow.exe pow.c -w -lm - - # get libm.so from system. - #libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe0fd24b000) - libmpath=$(ldd pow.exe|grep libm.so.6|sed "s/.*=>//"|sed "s/(.*//") - echo libm=$libmpath - cp $libmpath libm.so.6.orig - -} - - -protect() -{ - files=(pow.exe libm.so.6.orig) - - pow_exe_varients=(pow.exe) - libm_so_6_orig_varients=(libm.so.6.orig) - - for file in "${files[@]}"; do - for config in "${configs[@]}"; do - echo Protecting file "$file" with config "$config" | tee -a pow_protection_log.txt - "$config" ./"$file" ./"$file"".""$config" | tee -a pow_protection_log.txt - varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" - varient_file="$file"".""$config" - eval $varient_array_name+=\(\$varient_file\) - done - done -} - -clean() -{ - rm out - rm correct - rm -Rf pow.exe peasoup_exe* libm.so.6 libm.so.6.orig libm.so.6.cfi pow.cfi pow.exe.cfi - - for config in "${configs[@]}"; do - rm *."$config" - done -} - -report () -{ - total=$(expr $passes + $fails) - echo "Passes: $passes / $total" | tee -a pow_test_log.txt - echo "Fails : $fails / $total" | tee -a pow_test_log.txt -} - -main() -{ - build - protect - - - for pow_varient in "${pow_exe_varients[@]}"; do - for libm_varient in "${libm_so_6_orig_varients[@]}"; do - test "$pow_varient" "$libm_varient" 3 5 - test "$pow_varient" "$libm_varient" 5 8 - done - done - - report - if [[ ! $1 == -k ]]; then - clean - fi -} - -passes=0 -fails=0 - -main $* diff --git a/tools/selective_cfi/tests/manual_tests/test_spec.sh b/tools/selective_cfi/tests/manual_tests/test_spec.sh deleted file mode 100755 index 844ef86dd..000000000 --- a/tools/selective_cfi/tests/manual_tests/test_spec.sh +++ /dev/null @@ -1,190 +0,0 @@ -#!/bin/bash - -#benchmarks="401.bzip2" -# 447.dealII // broken build -benchmarks=" 400.perlbench 401.bzip2 403.gcc 410.bwaves 416.gamess 429.mcf 433.milc 434.zeusmp 435.gromacs 436.cactusADM 437.leslie3d 444.namd 445.gobmk 450.soplex 453.povray 454.calculix 456.hmmer 458.sjeng 459.GemsFDTD 462.libquantum 464.h264ref 465.tonto 470.lbm 471.omnetpp 473.astar 481.wrf 482.sphinx3 483.xalancbmk " - -#benchmarks="400.perlbench 403.gcc 445.gobmk 453.povray 458.sjeng 464.h264ref 464.tonto 471.omnetpp 481.wrf 482.sphinx3 483.xalancbmk" -number=1 - -setup() -{ - - if [ ! -d spec2006 ]; then - #svn co ^/spec2006/trunk spec2006 - git clone --depth 1 http://git.zephyr-software.com/allzp/spec2006.git spec2006 - fi - - - cd spec2006/ - if [ ! -L bin ]; then - ln -s bin.power/ bin - fi - source shrc - bin/relocate -} - - -run_test() -{ - local config_name=$1 - local config=$2 - - all_configs_that_were_run="$all_configs_that_were_run $config_name" - - cd $SPEC - if [ ! -d result.$config_name ]; then - echo "Re-doing runspec for test $config_name" - dropdb $PGDATABASE - createdb $PGDATABASE - $PEASOUP_HOME/tools/db/pdb_setup.sh - rm -Rf result/* - runspec --action scrub --config $config $benchmarks - runspec --action validate --config $config -n $number $benchmarks - cp benchspec/CPU2006/*/exe/* result - mv result result.$config_name - dropdb $PGDATABASE - createdb $PGDATABASE - $PEASOUP_HOME/tools/db/pdb_setup.sh - fi - -} - -get_size_result() -{ - bench=$1 - if [ -f $1 ]; then - size=$(stat --printf="%s" $bench) - echo -n $size - else - echo -n 0 - fi -} - -get_result() -{ - bench=$1 - config=$2 - - results=$(cat $SPEC/result.$config/CPU2006.002.log 2>/dev/null|grep Success|grep $bench|grep ratio=|sed 's/.*ratio=//'|sed 's/,.*//') - - sum=0 - count=0 - for res in $results - do - sum=$(echo $sum + $res | bc) - count=$(echo $count + 1 | bc) - done - #echo sum=$sum - #echo count=$count - res=$(echo "scale=2; $sum / $count" | bc 2> /dev/null ) - - count=$(echo $res|wc -w) - - if [ $count = 1 ]; then - echo -n $res - else - echo -n "N/A" - fi - -} - - -# global -all_configs_that_were_run="" - -get_raw_results() -{ - echo "--------------------------------------------------------------" - echo "Performance results are:" - echo "--------------------------------------------------------------" - local configs="$all_configs_that_were_run" - echo benchmark $configs - for bench in $benchmarks - do - echo -n "$bench " - for config in $configs - do - get_result $bench $config - echo -n " " - done - echo - done - - echo "--------------------------------------------------------------" - echo "Size results are:" - echo "--------------------------------------------------------------" - echo benchmark $configs - for bench in $SPEC/result.$config/*_base.amd64-m64-gcc42-nn - do - echo -n "$(basename $bench _base.amd64-m64-gcc42-nn) " - for config in $configs - do - file="$SPEC/result.$config/$(basename $bench)" - get_size_result $file - echo -n " " - done - echo - done - -} - - -main() -{ - start_dir=$(pwd) - setup - - - local zipr_flags="--backend zipr" - local mm_basic_cfi_flags="--critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all " - local mm_basic_cfi_exe_nonces_flags="--critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call " - #local mm_all_colored_8_byte_cfi_flags="--critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option selective_cfi:\"--nonce-size 8\" --step-option selective_cfi:--color --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:\"--exe-nonce-size 8\"" - local mm_color_cfi_flags="$mm_basic_cfi_flags --step-option selective_cfi:--color" - local cfi_4_byte_flags="$mm_basic_cfi_flags --step-option selective_cfi:\"--nonce-size 4\"" - local coloring_cfi_4_byte_flags="$mm_color_cfi_flags --step-option selective_cfi:\"--nonce-size 4\"" - local cfi_exe_nonces_1_byte_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:\"--exe-nonce-size 1\"" - local cfi_exe_nonces_4_byte_non_exe_color_non_exe_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:\"--nonce-size 4\" --step-option selective_cfi:--color" - local cfi_exe_nonces_8_byte_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:\"--exe-nonce-size 8\"" - local cfi_exe_nonces_1_byte_color_exe_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:\"--exe-nonce-size 1\" --step-option selective_cfi:--color-exe-nonces" - local cfi_exe_nonces_color_exe_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:--color-exe-nonces" - local cfi_exe_nonces_8_byte_color_exe_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:\"--exe-nonce-size 8\" --step-option selective_cfi:--color-exe-nonces" - local cfi_exe_nonces_4_byte_non_exe_color_both_flags="$mm_basic_cfi_exe_nonces_flags --step-option selective_cfi:\"--nonce-size 4\" --step-option selective_cfi:--color --step-option selective_cfi:--color-exe-nonces" - - local trace_flags="-o zipr:--traceplacement:on -o zipr:true" - - - # no $PS -- aka, baseline. - #run_test original $SPEC/config/ubuntu14.04lts-64bit.cfg - - # zipr, basic cfi, basic cfi with exe nonces for calls, color cfi - #PSOPTS="$zipr_flags" run_test zipr $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_basic_cfi_flags " run_test mm-basic-cfi $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_basic_cfi_exe_nonces_flags " run_test mm-basic-cfi-exe-nonces $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_color_cfi_flags" run_test mm-color-cfi $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $cfi_4_byte_flags " run_test cfi_4_byte $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $coloring_cfi_4_byte_flags " run_test coloring_cfi_4_byte $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_1_byte_flags " run_test cfi_exe_nonces_1_byte $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_4_byte_non_exe_color_non_exe_flags " run_test cfi_exe_nonces_4_byte_non_exe_color_non_exe $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_8_byte_flags " run_test cfi_exe_nonces_8_byte $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_1_byte_color_exe_flags " run_test cfi_exe_nonces_1_byte_color_exe $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_color_exe_flags " run_test cfi_exe_nonces_color_exe $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_8_byte_color_exe_flags " run_test cfi_exe_nonces_8_byte_color_exe $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - PSOPTS="$zipr_flags $cfi_exe_nonces_4_byte_non_exe_color_both_flags " run_test cfi_exe_nonces_4_byte_non_exe_color_both $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - - zipr, basic cfi, color cfi - # with trace placement - #PSOPTS="$zipr_flags $trace_flags " run_test zipr-trace $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_basic_cfi_flags $trace_flags " run_test mm-basic-cfi-trace $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_basic_cfi_exe_nonces_flags $trace_flags " run_test mm-basic-cfi-exe-nonces-trace $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_color_cfi_flags $trace_flags " run_test mm-color-cfi-trace $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - #PSOPTS="$zipr_flags $mm_all_colored_8_byte_cfi_flags " run_test mm-all-colored-8-byte-cfi $SPEC/config/ubuntu14.04lts-64bit-withps.cfg - - get_raw_results - -} - -main "$@" - - - diff --git a/tools/selective_cfi/zest_cfi_runtime/SConscript b/tools/selective_cfi/zest_cfi_runtime/SConscript deleted file mode 100644 index ca6e7f242..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/SConscript +++ /dev/null @@ -1,5 +0,0 @@ - -Import('env') -res=env.SConscript("SConscript64") - -Return('res') diff --git a/tools/selective_cfi/zest_cfi_runtime/SConscript32 b/tools/selective_cfi/zest_cfi_runtime/SConscript32 deleted file mode 100644 index b33ca0df1..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/SConscript32 +++ /dev/null @@ -1,35 +0,0 @@ -import os - - -Import('env') -myenv=env.Clone() -myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -myenv.Replace(ZEST_RUNTIME=os.environ['ZEST_RUNTIME']) - -cpppath=''' - ''' - - -cfiles=Glob( Dir('.').srcnode().abspath+"/*.cpp") -nasmfiles32=Glob( Dir('.').srcnode().abspath+"/*32.s") - -CXXFLAGS = " -nostdlib -nostdinc -fno-exceptions -Wall " -CFLAGS = " -nostdlib -nostdinc -fno-exceptions -Wall " -LDFLAGS = " -nostdlib -nostdinc -fno-exceptions -Wall " -AS = "nasm" - -myenv.Replace(AS = AS) -myenv.Append(CPPPATH=Split(cpppath)) - -myenv.Replace(ASFLAGS = " -felf32 " ) -myenv.Append(CXXFLAGS = CXXFLAGS+" -m32 ") -myenv.Append(CFLAGS = CFLAGS+" -m32 ") -myenv.Append(LINKFLAGS = LDFLAGS+" -m32 ") - - -so32=myenv.SharedLibrary("libzestcfi32.so", cfiles+nasmfiles32) -install32=myenv.Install("$ZEST_RUNTIME/lib32/", so32) -Default(install32) -Return('install32' - - diff --git a/tools/selective_cfi/zest_cfi_runtime/SConscript64 b/tools/selective_cfi/zest_cfi_runtime/SConscript64 deleted file mode 100644 index 650a83866..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/SConscript64 +++ /dev/null @@ -1,35 +0,0 @@ -import os - - -myenv=Environment() -myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -myenv.Replace(ZEST_RUNTIME=os.environ['ZEST_RUNTIME']) - -cpppath=''' - ''' - - -cfiles=Glob( Dir('.').srcnode().abspath+"/*.cpp")+Glob( Dir('.').srcnode().abspath+"/*.c") -nasmfiles64=Glob( Dir('.').srcnode().abspath+"/*64.s") - -CXXFLAGS = " -nostdlib -fno-exceptions -Wall -fPIC -O " -CFLAGS = " -nostdlib -fno-exceptions -Wall -fPIC -O " -LDFLAGS = " -nostdlib -fno-exceptions -Wall -fPIC -O " -AS = "nasm" - -myenv.Replace(AS = AS) -myenv.Append(CPPPATH=Split(cpppath)) - -myenv.Replace(ASFLAGS = " -felf64 ") -myenv.Append(CXXFLAGS = CXXFLAGS +" -m64 ") -myenv.Append(CFLAGS = CFLAGS +" -m64 ") -myenv.Append(LINKFLAGS = LDFLAGS +" -m64 ") - - -so64=myenv.SharedLibrary("libzestcfi.so", cfiles+nasmfiles64) -install64=myenv.Install("$ZEST_RUNTIME/lib64/", so64) -Default(install64) -Return('install64') - - - diff --git a/tools/selective_cfi/zest_cfi_runtime/SConstruct b/tools/selective_cfi/zest_cfi_runtime/SConstruct deleted file mode 100644 index e47f36c51..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/SConstruct +++ /dev/null @@ -1,7 +0,0 @@ - - - -env=Environment() -Export('env') -#env.SConscript('SConscript32', variant_dir='/tmp/build32') -env.SConscript('SConscript64', variant_dir='/tmp/build64') diff --git a/tools/selective_cfi/zest_cfi_runtime/dispatch.c b/tools/selective_cfi/zest_cfi_runtime/dispatch.c deleted file mode 100644 index e6dd745b8..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/dispatch.c +++ /dev/null @@ -1,205 +0,0 @@ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include <link.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -// typedef for a function pointer because the syntax is otherwise insane, unreadable and unwriteable. -typedef void (*zestcfi_func_ptr_t)(ElfW(Addr)) ; - -#define DEBUG 0 - - -static int Zest_strcmp(const char *s1, const char *s2) -{ - for ( ; *s1 == *s2; s1++, s2++) - if (*s1 == '\0') - return 0; - return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); -} - -#if DEBUG -static size_t Zest_strlen( const char *str ) -{ - register const char *s; - for (s = str; *s; ++s); - return(s - str); -} -#endif - -static void write_str(const char* out) -{ -#if DEBUG - write(2,out,Zest_strlen(out)); -#endif -} - -static void write_ptr(const void* out) -{ -#if DEBUG - char buf[20]; - sprintf(buf,"%p", out); - write_str(buf); -#endif -} - -static int ptload_for_target_exists(const struct dl_phdr_info *info, - const ElfW(Phdr) *phdr_start, const int phnum, const ElfW(Addr) target) -{ - const char* objname=info->dlpi_name; - int i; - for(i=0;i<phnum;i++) - { - // if it's a ptload header and it's - if(phdr_start[i].p_type==PT_LOAD && (info->dlpi_addr + phdr_start[i].p_vaddr)<=target && - target < (info->dlpi_addr + phdr_start[i].p_vaddr+phdr_start[i].p_memsz) ) - { - char str[]="Found target library: "; - write_str(str); - write_str(objname); - write_str(". "); - return 1; - } - } - return 0; -} - -static ElfW(Addr) find_dynamic_start(const struct dl_phdr_info *info,const ElfW(Phdr) *phdr_start, const int phnum) -{ - int i; - for(i=0;i<phnum;i++) - { - if(phdr_start[i].p_type==PT_DYNAMIC) - return info->dlpi_addr+phdr_start[i].p_vaddr; - } - - return (ElfW(Addr))NULL; -} - -static ElfW(Addr) find_dynamic_entry(const struct dl_phdr_info *info, const int type, const ElfW(Dyn) *dynamic_start) -{ - int i; - for(i=0; dynamic_start[i].d_tag!=DT_NULL; i++) - { - if(dynamic_start[i].d_tag==type) - return dynamic_start[i].d_un.d_val; - } - return 0; -} - -static ElfW(Addr) find_symtab_entry(const char* tofind, const ElfW(Sym) *symtab, const char* strtab, const int strtabsz) -{ - int i; - // unfortunately we can't know the symbol table size. - // (really?! i don't believe this, but I can't find it...) - // but we do know the string table size. - // if a symbol's name points outside the string table, abort lookup as - // we've probably exceeded the symbol table's size. - for(i=1; 1 ; i++) - { - // note: st_name is ElfW(Word) which maps to uint32_t or uint64_t depending on architecture. - // thus, no lower bound check is necessary bcause it has to be >=0. - if(symtab[i].st_name>=strtabsz) - return 0; - - const char* symstring=strtab+symtab[i].st_name; -#if DEBUG - write_str("Checking symbol: "); - write_str(symstring); - write_str("\n"); -#endif - if(Zest_strcmp(symstring, tofind)==0) - return (ElfW(Addr))&symtab[i]; - } - - // should not be reachable. do not put assert(0) here because that calls libc, which is disallowed. - return 0; -} - -int dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t size, void *data) -{ - ElfW(Addr) *zestcfi_addr=(ElfW(Addr)*)data; - ElfW(Addr) target=*zestcfi_addr; - - //const char* objname=info->dlpi_name; - const ElfW(Phdr) *phdr_start=info->dlpi_phdr; - const ElfW(Half) phnum=info->dlpi_phnum; - - // return now if this object doesn't have a ptload seg for the target. - if(!ptload_for_target_exists(info,phdr_start, phnum, target)) - return 0; - - const ElfW(Dyn) *dynamic_start=(ElfW(Dyn)*)find_dynamic_start(info, phdr_start, phnum); - if(!dynamic_start) - { - write_str("Couldn't find dynamic start. "); - return 0; - } - - const ElfW(Sym) *symtab=(ElfW(Sym)*)find_dynamic_entry(info,DT_SYMTAB, dynamic_start); - // apparently some modules don't have a reloc for their symtab pointer properly entry. - if(!ptload_for_target_exists(info, phdr_start, phnum, (ElfW(Addr))symtab)) - symtab=(ElfW(Sym)*)((ElfW(Addr))symtab+(ElfW(Addr))info->dlpi_addr); - - if(!symtab) - { - write_str("Couldn't find symtab start. "); - return 0; - } - - const char* strtab=(const char*)find_dynamic_entry(info,DT_STRTAB, dynamic_start); - // apparently some modules don't have a reloc for their symtab pointer properly entry. - if(!ptload_for_target_exists(info, phdr_start, phnum, (ElfW(Addr))strtab)) - strtab=(const char*)((ElfW(Addr))strtab+(ElfW(Addr))info->dlpi_addr); - if(!strtab) - { - write_str("Couldn't find strtab start. "); - return 0; - } - - const int strtabsz=(const int)find_dynamic_entry(info,DT_STRSZ, dynamic_start); - if(strtabsz==0) - { - write_str("Couldn't find strtab start. "); - return 0; - } - - const ElfW(Sym) *sym=(ElfW(Sym)*)find_symtab_entry("zestcfi", symtab, strtab, strtabsz); - if(!sym) - { - write_str("Couldn't find zestcfi symbol start. "); - return 0; - } - - write_str( "Found zestcfi string."); - - *zestcfi_addr=info->dlpi_addr+sym->st_value; - - return 1; -} - - -zestcfi_func_ptr_t* zest_cfi_dispatch_c(ElfW(Addr) target) -{ - extern int zestcfi__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data); - - write_ptr((void*)target); - write_str(" -- "); - - ElfW(Addr) zestcfi_addr=target; - int res=zestcfi__dl_iterate_phdr(dl_iterate_phdr_callback,(void*)&zestcfi_addr); - - if(res==0) - { - write_str("Could not find zestcfi for target library. Allowing control transfer.\n"); - return NULL; - } - else - { - write_str("Found zest-cfi_dispatcher. Control transfer will be checked.\n"); - zestcfi_func_ptr_t *zest_cfi_ptr = (zestcfi_func_ptr_t*) zestcfi_addr; - return zest_cfi_ptr; - } -} diff --git a/tools/selective_cfi/zest_cfi_runtime/dl_iterate.c b/tools/selective_cfi/zest_cfi_runtime/dl_iterate.c deleted file mode 100644 index 666032343..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/dl_iterate.c +++ /dev/null @@ -1,166 +0,0 @@ - - -#define _GNU_SOURCE -#include <link.h> -#include <stddef.h> -#include <dlfcn.h> -#include <stdio.h> -#include <pthread.h> - -struct auditstate { - uintptr_t cookie; - unsigned int bindflags; -}; - - -typedef struct { - pthread_mutex_t mutex; -} __rtld_lock_recursive_t; - - -struct unique_sym_table { - __rtld_lock_recursive_t lock; - struct unique_sym *entries; - size_t size; - size_t n_elements; - void (*free)(void *); -}; - -struct my_link_map { - ElfW(Addr) l_addr; - char *l_name; - ElfW(Dyn) *l_ld; - struct my_link_map *l_next; - struct my_link_map *l_prev; - struct my_link_map *l_real; - Lmid_t l_ns; - struct libname_list *l_libname; - ElfW(Dyn) *l_info[76]; - const ElfW(Phdr) *l_phdr; - ElfW(Addr) l_entry; - ElfW(Half) l_phnum; - ElfW(Half) l_ldnum; -}; - -struct link_namespaces { - struct my_link_map *_ns_loaded; - unsigned int _ns_nloaded; - struct r_scope_elem *_ns_main_searchlist; - size_t _ns_global_scope_alloc; - struct unique_sym_table _ns_unique_sym_table; - struct r_debug _ns_debug; -}; - -typedef unsigned long long hp_timing_t; - -struct my_rtld_global { - struct link_namespaces _dl_ns[16]; -#if 0 - size_t _dl_nns; - __rtld_lock_recursive_t _dl_load_lock; - __rtld_lock_recursive_t _dl_load_write_lock; - unsigned long long _dl_load_adds; - struct link_map *_dl_initfirst; - hp_timing_t _dl_cpuclock_offset; - struct link_map *_dl_profile_map; - unsigned long _dl_num_relocations; - unsigned long _dl_num_cache_relocations; - struct r_search_path_elem *_dl_all_dirs; - void **(*_dl_error_catch_tsd)(void); - struct link_map _dl_rtld_map; - struct auditstate audit_data[16]; - void (*_dl_rtld_lock_recursive)(void *); - void (*_dl_rtld_unlock_recursive)(void *); - int (*_dl_make_stack_executable_hook)(void **); - Elf64_Word _dl_stack_flags; - _Bool _dl_tls_dtv_gaps; - size_t _dl_tls_max_dtv_idx; - struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; - size_t _dl_tls_static_nelem; - size_t _dl_tls_static_size; - size_t _dl_tls_static_used; - size_t _dl_tls_static_align; - void *_dl_initial_dtv; - size_t _dl_tls_generation; - void (*_dl_init_static_tls)(struct link_map *); - void (*_dl_wait_lookup_done)(void); - struct dl_scope_free_list *_dl_scope_free_list; -#endif -}; - -extern struct my_rtld_global _rtld_global; - - -#define GL(a) _rtld_global._##a -int -zestcfi__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, - size_t size, void *data), void *data) -{ - struct my_link_map *l=NULL; - struct dl_phdr_info info; - int ret = 0; - - /* Make sure nobody modifies the list of loaded objects. */ -// __rtld_lock_lock_recursive (GL(dl_load_write_lock)); -// __libc_cleanup_push (cancel_handler, NULL); - - /* We have to determine the namespace of the caller since this determines - which namespace is reported. */ - //size_t nloaded = GL(dl_ns)[0]._ns_nloaded; - Lmid_t ns = 0; -#ifdef SHARED - const void *caller = RETURN_ADDRESS (0); - for (Lmid_t cnt = GL(dl_nns) - 1; cnt > 0; --cnt) - for (struct my_link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next) - { - /* We have to count the total number of loaded objects. */ - nloaded += GL(dl_ns)[cnt]._ns_nloaded; - - if (caller >= (const void *) l->l_map_start - && caller < (const void *) l->l_map_end - && (l->l_contiguous - || _dl_addr_inside_object (l, (ElfW(Addr)) caller))) - ns = cnt; - } -#endif - - for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) - { - info.dlpi_addr = l->l_real->l_addr; - info.dlpi_name = l->l_real->l_name; - info.dlpi_phdr = l->l_real->l_phdr; - info.dlpi_phnum = l->l_real->l_phnum; -// info.dlpi_adds = GL(dl_load_adds); -// info.dlpi_subs = GL(dl_load_adds) - nloaded; -// info.dlpi_tls_data = NULL; -// info.dlpi_tls_modid = l->l_real->l_tls_modid; -// if (info.dlpi_tls_modid != 0) -// info.dlpi_tls_data = GLRO(dl_tls_get_addr_soft) (l->l_real); - ret = callback (&info, sizeof (struct dl_phdr_info), data); - if (ret) - break; - } - - /* Release the lock. */ -// __libc_cleanup_pop (0); -// __rtld_lock_unlock_recursive (GL(dl_load_write_lock)); - - return ret; -} - -#ifdef TEST - -int test_callback (struct dl_phdr_info *info, size_t size, void *data) -{ - printf("In test_callback with info=%p, module=%s\n", info, info->dlpi_name); - return 0; -} - -main() -{ - printf("My impl:\t"); - zestcfi__dl_iterate_phdr (test_callback, NULL); - printf("real impl:\t"); - dl_iterate_phdr (test_callback, NULL); -} -#endif diff --git a/tools/selective_cfi/zest_cfi_runtime/ldsodefs.h b/tools/selective_cfi/zest_cfi_runtime/ldsodefs.h deleted file mode 100644 index 68b3171db..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/ldsodefs.h +++ /dev/null @@ -1,1059 +0,0 @@ -/* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _LDSODEFS_H -#define _LDSODEFS_H 1 - -#include <features.h> - -#include <stdbool.h> -#define __need_size_t -#define __need_NULL -#include <stddef.h> -#include <string.h> -#include <stdint.h> - -#include <elf.h> -#include <bits/auxv.h> -#include <dlfcn.h> -#include <fpu_control.h> -#include <sys/mman.h> -#include <link.h> -#include <dl-lookupcfg.h> -#include <dl-sysdep.h> -#include <bits/libc-lock.h> -#include <hp-timing.h> -#include <tls.h> -#include <kernel-features.h> -#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_RTLD_DEBUG. */ - -__BEGIN_DECLS - -#define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALTAGIDX (tag)) -#define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag)) - -/* We use this macro to refer to ELF types independent of the native wordsize. - `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ -#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) - -/* All references to the value of l_info[DT_PLTGOT], - l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA], - l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)] - have to be accessed via the D_PTR macro. The macro is needed since for - most architectures the entry is already relocated - but for some not - and we need to relocate at access time. */ -#ifdef DL_RO_DYN_SECTION -# define D_PTR(map, i) ((map)->i->d_un.d_ptr + (map)->l_addr) -#else -# define D_PTR(map, i) (map)->i->d_un.d_ptr -#endif - -/* Result of the lookup functions and how to retrieve the base address. */ -typedef struct link_map *lookup_t; -#define LOOKUP_VALUE(map) map -#define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0) - -/* On some architectures a pointer to a function is not just a pointer - to the actual code of the function but rather an architecture - specific descriptor. */ -#ifndef ELF_FUNCTION_PTR_IS_SPECIAL -# define DL_SYMBOL_ADDRESS(map, ref) \ - (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value) -# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr)) -# define DL_CALL_DT_INIT(map, start, argc, argv, env) \ - ((init_t) (start)) (argc, argv, env) -# define DL_CALL_DT_FINI(map, start) ((fini_t) (start)) () -#endif - -/* On some architectures dladdr can't use st_size of all symbols this way. */ -#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \ - ((ADDR) >= (L)->l_addr + (SYM)->st_value \ - && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0) \ - && (ADDR) == (L)->l_addr + (SYM)->st_value) \ - || (ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size) \ - && ((MATCHSYM) == NULL || (MATCHSYM)->st_value < (SYM)->st_value)) - -/* Unmap a loaded object, called by _dl_close (). */ -#ifndef DL_UNMAP_IS_SPECIAL -# define DL_UNMAP(map) \ - __munmap ((void *) (map)->l_map_start, \ - (map)->l_map_end - (map)->l_map_start) -#endif - -/* By default we do not need special support to initialize DSOs loaded - by statically linked binaries. */ -#ifndef DL_STATIC_INIT -# define DL_STATIC_INIT(map) -#endif - -/* Reloc type classes as returned by elf_machine_type_class(). - ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by - some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be - satisfied by any symbol in the executable. Some architectures do - not support copy relocations. In this case we define the macro to - zero so that the code for handling them gets automatically optimized - out. */ -#define ELF_RTYPE_CLASS_PLT 1 -#ifndef DL_NO_COPY_RELOCS -# define ELF_RTYPE_CLASS_COPY 2 -#else -# define ELF_RTYPE_CLASS_COPY 0 -#endif - -/* ELF uses the PF_x macros to specify the segment permissions, mmap - uses PROT_xxx. In most cases the three macros have the values 1, 2, - and 3 but not in a matching order. The following macros allows - converting from the PF_x values to PROT_xxx values. */ -#define PF_TO_PROT \ - ((PROT_READ << (PF_R * 4)) \ - | (PROT_WRITE << (PF_W * 4)) \ - | (PROT_EXEC << (PF_X * 4)) \ - | ((PROT_READ | PROT_WRITE) << ((PF_R | PF_W) * 4)) \ - | ((PROT_READ | PROT_EXEC) << ((PF_R | PF_X) * 4)) \ - | ((PROT_WRITE | PROT_EXEC) << (PF_W | PF_X) * 4) \ - | ((PROT_READ | PROT_WRITE | PROT_EXEC) << ((PF_R | PF_W | PF_X) * 4))) - -/* The filename itself, or the main program name, if available. */ -#define DSO_FILENAME(name) ((name)[0] ? (name) \ - : (rtld_progname ?: "<main program>")) - -#define RTLD_PROGNAME (rtld_progname ?: "<program name unknown>") - -/* For the version handling we need an array with only names and their - hash values. */ -struct r_found_version - { - const char *name; - ElfW(Word) hash; - - int hidden; - const char *filename; - }; - -/* We want to cache information about the searches for shared objects. */ - -enum r_dir_status { unknown, nonexisting, existing }; - -struct r_search_path_elem - { - /* This link is only used in the `all_dirs' member of `r_search_path'. */ - struct r_search_path_elem *next; - - /* Strings saying where the definition came from. */ - const char *what; - const char *where; - - /* Basename for this search path element. The string must end with - a slash character. */ - const char *dirname; - size_t dirnamelen; - - enum r_dir_status status[0]; - }; - -struct r_strlenpair - { - const char *str; - size_t len; - }; - - -/* A data structure for a simple single linked list of strings. */ -struct libname_list - { - const char *name; /* Name requested (before search). */ - struct libname_list *next; /* Link to next name for this object. */ - int dont_free; /* Flag whether this element should be freed - if the object is not entirely unloaded. */ - }; - - -/* Bit masks for the objects which valid callers can come from to - functions with restricted interface. */ -enum allowmask - { - allow_libc = 1, - allow_libdl = 2, - allow_libpthread = 4, - allow_ldso = 8 - }; - - -struct audit_ifaces -{ - void (*activity) (uintptr_t *, unsigned int); - char *(*objsearch) (const char *, uintptr_t *, unsigned int); - unsigned int (*objopen) (struct link_map *, Lmid_t, uintptr_t *); - void (*preinit) (uintptr_t *); - union - { - uintptr_t (*symbind32) (Elf32_Sym *, unsigned int, uintptr_t *, - uintptr_t *, unsigned int *, const char *); - uintptr_t (*symbind64) (Elf64_Sym *, unsigned int, uintptr_t *, - uintptr_t *, unsigned int *, const char *); - }; - union - { -#ifdef ARCH_PLTENTER_MEMBERS - ARCH_PLTENTER_MEMBERS; -#endif - }; - union - { -#ifdef ARCH_PLTEXIT_MEMBERS - ARCH_PLTEXIT_MEMBERS; -#endif - }; - unsigned int (*objclose) (uintptr_t *); - - struct audit_ifaces *next; -}; - - -/* Test whether given NAME matches any of the names of the given object. */ -extern int _dl_name_match_p (const char *__name, const struct link_map *__map) - internal_function; - -/* Compute next higher prime number. */ -extern unsigned long int _dl_higher_prime_number (unsigned long int n) - internal_function; - -/* Function used as argument for `_dl_receive_error' function. The - arguments are the error code, error string, and the objname the - error occurred in. */ -typedef void (*receiver_fct) (int, const char *, const char *); - -/* Internal functions of the run-time dynamic linker. - These can be accessed if you link again the dynamic linker - as a shared library, as in `-lld' or `/lib/ld.so' explicitly; - but are not normally of interest to user programs. - - The `-ldl' library functions in <dlfcn.h> provide a simple - user interface to run-time dynamic linking. */ - - -#ifndef SHARED -# define EXTERN extern -# define GL(name) _##name -#else -# define EXTERN -# ifdef IS_IN_rtld -# define GL(name) _rtld_local._##name -# else -# define GL(name) _rtld_global._##name -# endif -struct rtld_global -{ -#endif - /* Don't change the order of the following elements. 'dl_loaded' - must remain the first element. Forever. */ - -/* Non-shared code has no support for multiple namespaces. */ -#ifdef SHARED -# define DL_NNS 16 -#else -# define DL_NNS 1 -#endif - EXTERN struct link_namespaces - { - /* A pointer to the map for the main map. */ - struct link_map *_ns_loaded; - /* Number of object in the _dl_loaded list. */ - unsigned int _ns_nloaded; - /* Direct pointer to the searchlist of the main object. */ - struct r_scope_elem *_ns_main_searchlist; - /* This is zero at program start to signal that the global scope map is - allocated by rtld. Later it keeps the size of the map. It might be - reset if in _dl_close if the last global object is removed. */ - size_t _ns_global_scope_alloc; - /* Search table for unique objects. */ - struct unique_sym_table - { - __rtld_lock_define_recursive (, lock) - struct unique_sym - { - uint32_t hashval; - const char *name; - const ElfW(Sym) *sym; - const struct link_map *map; - } *entries; - size_t size; - size_t n_elements; - void (*free) (void *); - } _ns_unique_sym_table; - /* Keep track of changes to each namespace' list. */ - struct r_debug _ns_debug; - } _dl_ns[DL_NNS]; - /* One higher than index of last used namespace. */ - EXTERN size_t _dl_nns; - - /* During the program run we must not modify the global data of - loaded shared object simultanously in two threads. Therefore we - protect `_dl_open' and `_dl_close' in dl-close.c. - - This must be a recursive lock since the initializer function of - the loaded object might as well require a call to this function. - At this time it is not anymore a problem to modify the tables. */ - __rtld_lock_define_recursive (EXTERN, _dl_load_lock) - /* This lock is used to keep __dl_iterate_phdr from inspecting the - list of loaded objects while an object is added to or removed - from that list. */ - __rtld_lock_define_recursive (EXTERN, _dl_load_write_lock) - - /* Incremented whenever something may have been added to dl_loaded. */ - EXTERN unsigned long long _dl_load_adds; - - /* The object to be initialized first. */ - EXTERN struct link_map *_dl_initfirst; - -#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL || HP_TIMING_PAD - /* Start time on CPU clock. */ - EXTERN hp_timing_t _dl_cpuclock_offset; -#endif - - /* Map of shared object to be profiled. */ - EXTERN struct link_map *_dl_profile_map; - - /* Counters for the number of relocations performed. */ - EXTERN unsigned long int _dl_num_relocations; - EXTERN unsigned long int _dl_num_cache_relocations; - - /* List of search directories. */ - EXTERN struct r_search_path_elem *_dl_all_dirs; - -#ifdef _LIBC_REENTRANT - EXTERN void **(*_dl_error_catch_tsd) (void) __attribute__ ((const)); -#endif - - /* Structure describing the dynamic linker itself. We need to - reserve memory for the data the audit libraries need. */ - EXTERN struct link_map _dl_rtld_map; -#ifdef SHARED - struct auditstate audit_data[DL_NNS]; -#endif - -#if defined SHARED && defined _LIBC_REENTRANT \ - && defined __rtld_lock_default_lock_recursive - EXTERN void (*_dl_rtld_lock_recursive) (void *); - EXTERN void (*_dl_rtld_unlock_recursive) (void *); -#endif - - /* If loading a shared object requires that we make the stack executable - when it was not, we do it by calling this function. - It returns an errno code or zero on success. */ - EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function; - - /* Prevailing state of the stack, PF_X indicating it's executable. */ - EXTERN ElfW(Word) _dl_stack_flags; - - /* Flag signalling whether there are gaps in the module ID allocation. */ - EXTERN bool _dl_tls_dtv_gaps; - /* Highest dtv index currently needed. */ - EXTERN size_t _dl_tls_max_dtv_idx; - /* Information about the dtv slots. */ - EXTERN struct dtv_slotinfo_list - { - size_t len; - struct dtv_slotinfo_list *next; - struct dtv_slotinfo - { - size_t gen; - struct link_map *map; - } slotinfo[0]; - } *_dl_tls_dtv_slotinfo_list; - /* Number of modules in the static TLS block. */ - EXTERN size_t _dl_tls_static_nelem; - /* Size of the static TLS block. */ - EXTERN size_t _dl_tls_static_size; - /* Size actually allocated in the static TLS block. */ - EXTERN size_t _dl_tls_static_used; - /* Alignment requirement of the static TLS block. */ - EXTERN size_t _dl_tls_static_align; - -/* Number of additional entries in the slotinfo array of each slotinfo - list element. A large number makes it almost certain take we never - have to iterate beyond the first element in the slotinfo list. */ -#define TLS_SLOTINFO_SURPLUS (62) - -/* Number of additional slots in the dtv allocated. */ -#define DTV_SURPLUS (14) - - /* Initial dtv of the main thread, not allocated with normal malloc. */ - EXTERN void *_dl_initial_dtv; - /* Generation counter for the dtv. */ - EXTERN size_t _dl_tls_generation; - - EXTERN void (*_dl_init_static_tls) (struct link_map *); - - EXTERN void (*_dl_wait_lookup_done) (void); - - /* Scopes to free after next THREAD_GSCOPE_WAIT (). */ - EXTERN struct dl_scope_free_list - { - size_t count; - void *list[50]; - } *_dl_scope_free_list; -#ifdef SHARED -}; -# define __rtld_global_attribute__ -# ifdef IS_IN_rtld -# ifdef HAVE_SDATA_SECTION -# define __rtld_local_attribute__ \ - __attribute__ ((visibility ("hidden"), section (".sdata"))) -# undef __rtld_global_attribute__ -# define __rtld_global_attribute__ __attribute__ ((section (".sdata"))) -# else -# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) -# endif -extern struct rtld_global _rtld_local __rtld_local_attribute__; -# undef __rtld_local_attribute__ -# endif -extern struct rtld_global _rtld_global __rtld_global_attribute__; -# undef __rtld_global_attribute__ -#endif - -#if __OPTION_EGLIBC_RTLD_DEBUG -# define GLRO_dl_debug_mask GLRO(dl_debug_mask) -#else -# define GLRO_dl_debug_mask 0 -#endif - -#ifndef SHARED -# define GLRO(name) _##name -#else -# ifdef IS_IN_rtld -# define GLRO(name) _rtld_local_ro._##name -# else -# define GLRO(name) _rtld_global_ro._##name -# endif -struct rtld_global_ro -{ -#endif - -#if __OPTION_EGLIBC_RTLD_DEBUG - /* If nonzero the appropriate debug information is printed. */ - EXTERN int _dl_debug_mask; -#endif -#define DL_DEBUG_LIBS (1 << 0) -#define DL_DEBUG_IMPCALLS (1 << 1) -#define DL_DEBUG_BINDINGS (1 << 2) -#define DL_DEBUG_SYMBOLS (1 << 3) -#define DL_DEBUG_VERSIONS (1 << 4) -#define DL_DEBUG_RELOC (1 << 5) -#define DL_DEBUG_FILES (1 << 6) -#define DL_DEBUG_STATISTICS (1 << 7) -#define DL_DEBUG_UNUSED (1 << 8) -#define DL_DEBUG_SCOPES (1 << 9) -/* These two are used only internally. */ -#define DL_DEBUG_HELP (1 << 10) -#define DL_DEBUG_PRELINK (1 << 11) - - /* OS version. */ - EXTERN unsigned int _dl_osversion; - /* Platform name. */ - EXTERN const char *_dl_platform; - EXTERN size_t _dl_platformlen; - - /* Cached value of `getpagesize ()'. */ - EXTERN size_t _dl_pagesize; - - /* Do we read from ld.so.cache? */ - EXTERN int _dl_inhibit_cache; - - /* Copy of the content of `_dl_main_searchlist' at startup time. */ - EXTERN struct r_scope_elem _dl_initial_searchlist; - - /* CLK_TCK as reported by the kernel. */ - EXTERN int _dl_clktck; - - /* If nonzero print warnings messages. */ - EXTERN int _dl_verbose; - - /* File descriptor to write debug messages to. */ - EXTERN int _dl_debug_fd; - - /* Do we do lazy relocations? */ - EXTERN int _dl_lazy; - - /* Nonzero if runtime lookups should not update the .got/.plt. */ - EXTERN int _dl_bind_not; - - /* Nonzero if references should be treated as weak during runtime - linking. */ - EXTERN int _dl_dynamic_weak; - - /* Default floating-point control word. */ - EXTERN fpu_control_t _dl_fpu_control; - - /* Expected cache ID. */ - EXTERN int _dl_correct_cache_id; - - /* Mask for hardware capabilities that are available. */ - EXTERN uint64_t _dl_hwcap; - - /* Mask for important hardware capabilities we honour. */ - EXTERN uint64_t _dl_hwcap_mask; - - /* Pointer to the auxv list supplied to the program at startup. */ - EXTERN ElfW(auxv_t) *_dl_auxv; - - /* Get architecture specific definitions. */ -#define PROCINFO_DECL -#ifndef PROCINFO_CLASS -# define PROCINFO_CLASS EXTERN -#endif -#include <dl-procinfo.c> - - /* Names of shared object for which the RPATH should be ignored. */ - EXTERN const char *_dl_inhibit_rpath; - - /* Location of the binary. */ - EXTERN const char *_dl_origin_path; - - /* -1 if the dynamic linker should honor library load bias, - 0 if not, -2 use the default (honor biases for normal - binaries, don't honor for PIEs). */ - EXTERN ElfW(Addr) _dl_use_load_bias; - - /* Name of the shared object to be profiled (if any). */ - EXTERN const char *_dl_profile; - /* Filename of the output file. */ - EXTERN const char *_dl_profile_output; - /* Name of the object we want to trace the prelinking. */ - EXTERN const char *_dl_trace_prelink; - /* Map of shared object to be prelink traced. */ - EXTERN struct link_map *_dl_trace_prelink_map; - - /* All search directories defined at startup. */ - EXTERN struct r_search_path_elem *_dl_init_all_dirs; - -#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL || HP_TIMING_PAD - /* Overhead of a high-precision timing measurement. */ - EXTERN hp_timing_t _dl_hp_timing_overhead; -#endif - -#ifdef NEED_DL_SYSINFO - /* Syscall handling improvements. This is very specific to x86. */ - EXTERN uintptr_t _dl_sysinfo; -#endif - -#ifdef NEED_DL_SYSINFO_DSO - /* The vsyscall page is a virtual DSO pre-mapped by the kernel. - This points to its ELF header. */ - EXTERN const ElfW(Ehdr) *_dl_sysinfo_dso; - - /* At startup time we set up the normal DSO data structure for it, - and this points to it. */ - EXTERN struct link_map *_dl_sysinfo_map; -#endif - - /* Mask for more hardware capabilities that are available on some - platforms. */ - EXTERN uint64_t _dl_hwcap2; - -#ifdef SHARED - /* We add a function table to _rtld_global which is then used to - call the function instead of going through the PLT. The result - is that we can avoid exporting the functions and we do not jump - PLT relocations in libc.so. */ - void (*_dl_debug_printf) (const char *, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); - int (internal_function *_dl_catch_error) (const char **, const char **, - bool *, void (*) (void *), void *); - void (internal_function *_dl_signal_error) (int, const char *, const char *, - const char *); - void (*_dl_mcount) (ElfW(Addr) frompc, ElfW(Addr) selfpc); - lookup_t (internal_function *_dl_lookup_symbol_x) (const char *, - struct link_map *, - const ElfW(Sym) **, - struct r_scope_elem *[], - const struct r_found_version *, - int, int, - struct link_map *); - int (*_dl_check_caller) (const void *, enum allowmask); - void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen, - Lmid_t nsid, int argc, char *argv[], char *env[]); - void (*_dl_close) (void *map); - void *(*_dl_tls_get_addr_soft) (struct link_map *); -#ifdef HAVE_DL_DISCOVER_OSVERSION - int (*_dl_discover_osversion) (void); -#endif - - /* List of auditing interfaces. */ - struct audit_ifaces *_dl_audit; - unsigned int _dl_naudit; - - /* 0 if internal pointer values should not be guarded, 1 if they should. */ - EXTERN int _dl_pointer_guard; -}; -# define __rtld_global_attribute__ -# ifdef IS_IN_rtld -# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) -extern struct rtld_global_ro _rtld_local_ro - attribute_relro __rtld_local_attribute__; -extern struct rtld_global_ro _rtld_global_ro - attribute_relro __rtld_global_attribute__; -# undef __rtld_local_attribute__ -# else -/* We cheat a bit here. We declare the variable as as const even - though it is at startup. */ -extern const struct rtld_global_ro _rtld_global_ro - attribute_relro __rtld_global_attribute__; -# endif -# undef __rtld_global_attribute__ -#endif -#undef EXTERN - -#ifndef SHARED -/* dl-support.c defines these and initializes them early on. */ -extern const ElfW(Phdr) *_dl_phdr; -extern size_t _dl_phnum; -#endif - -#ifdef IS_IN_rtld -/* This is the initial value of GL(dl_error_catch_tsd). - A non-TLS libpthread will change it. */ -extern void **_dl_initial_error_catch_tsd (void) __attribute__ ((const)) - attribute_hidden; -#endif - -/* This is the initial value of GL(dl_make_stack_executable_hook). - A threads library can change it. */ -extern int _dl_make_stack_executable (void **stack_endp) internal_function; -rtld_hidden_proto (_dl_make_stack_executable) - -/* Variable pointing to the end of the stack (or close to it). This value - must be constant over the runtime of the application. Some programs - might use the variable which results in copy relocations on some - platforms. But this does not matter, ld.so can always use the local - copy. */ -extern void *__libc_stack_end -#ifndef LIBC_STACK_END_NOT_RELRO - attribute_relro -#endif - ; -rtld_hidden_proto (__libc_stack_end) - -/* Parameters passed to the dynamic linker. */ -extern int _dl_argc attribute_hidden attribute_relro; -extern char **_dl_argv -#ifndef DL_ARGV_NOT_RELRO - attribute_relro -#endif - ; -#ifdef IS_IN_rtld -extern unsigned int _dl_skip_args attribute_hidden -# ifndef DL_ARGV_NOT_RELRO - attribute_relro -# endif - ; -extern unsigned int _dl_skip_args_internal attribute_hidden -# ifndef DL_ARGV_NOT_RELRO - attribute_relro -# endif - ; -extern char **_dl_argv_internal attribute_hidden -# ifndef DL_ARGV_NOT_RELRO - attribute_relro -# endif - ; -# define rtld_progname (INTUSE(_dl_argv)[0]) -#else -# define rtld_progname _dl_argv[0] -#endif - -/* Flag set at startup and cleared when the last initializer has run. */ -extern int _dl_starting_up; -weak_extern (_dl_starting_up) -#ifdef IS_IN_rtld -extern int _dl_starting_up_internal attribute_hidden; -#endif - -/* Random data provided by the kernel. */ -extern void *_dl_random attribute_hidden attribute_relro; - -/* OS-dependent function to open the zero-fill device. */ -extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ - - -/* Write message on the debug file descriptor. The parameters are - interpreted as for a `printf' call. All the lines start with a - tag showing the PID. */ -extern void _dl_debug_printf (const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 1, 2))) attribute_hidden; - -/* Write message on the debug file descriptor. The parameters are - interpreted as for a `printf' call. All the lines buf the first - start with a tag showing the PID. */ -extern void _dl_debug_printf_c (const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); - - -/* Write a message on the specified descriptor FD. The parameters are - interpreted as for a `printf' call. */ -extern void _dl_dprintf (int fd, const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))) - attribute_hidden; - -/* Write a message on the specified descriptor standard output. The - parameters are interpreted as for a `printf' call. */ -#define _dl_printf(fmt, args...) \ - _dl_dprintf (STDOUT_FILENO, fmt, ##args) - -/* Write a message on the specified descriptor standard error. The - parameters are interpreted as for a `printf' call. */ -#define _dl_error_printf(fmt, args...) \ - _dl_dprintf (STDERR_FILENO, fmt, ##args) - -/* Write a message on the specified descriptor standard error and exit - the program. The parameters are interpreted as for a `printf' call. */ -#define _dl_fatal_printf(fmt, args...) \ - do \ - { \ - _dl_dprintf (STDERR_FILENO, fmt, ##args); \ - _exit (127); \ - } \ - while (1) - - -/* This function is called by all the internal dynamic linker functions - when they encounter an error. ERRCODE is either an `errno' code or - zero; OBJECT is the name of the problematical shared object, or null if - it is a general problem; ERRSTRING is a string describing the specific - problem. */ -extern void _dl_signal_error (int errcode, const char *object, - const char *occurred, const char *errstring) - internal_function __attribute__ ((__noreturn__)) attribute_hidden; - -/* Like _dl_signal_error, but may return when called in the context of - _dl_receive_error. */ -extern void _dl_signal_cerror (int errcode, const char *object, - const char *occation, const char *errstring) - internal_function; - -/* Call OPERATE, receiving errors from `dl_signal_cerror'. Unlike - `_dl_catch_error' the operation is resumed after the OPERATE - function returns. - ARGS is passed as argument to OPERATE. */ -extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), - void *args) - internal_function; - - -/* Open the shared object NAME and map in its segments. - LOADER's DT_RPATH is used in searching for NAME. - If the object is already opened, returns its existing map. */ -extern struct link_map *_dl_map_object (struct link_map *loader, - const char *name, - int type, int trace_mode, int mode, - Lmid_t nsid) - internal_function attribute_hidden; - -/* Call _dl_map_object on the dependencies of MAP, and set up - MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously - loaded objects that will be inserted into MAP->l_searchlist after MAP - but before its dependencies. */ -extern void _dl_map_object_deps (struct link_map *map, - struct link_map **preloads, - unsigned int npreloads, int trace_mode, - int open_mode) - internal_function attribute_hidden; - -/* Cache the locations of MAP's hash table. */ -extern void _dl_setup_hash (struct link_map *map) - internal_function attribute_hidden; - - -/* Collect the directories in the search path for LOADER's dependencies. - The data structure is defined in <dlfcn.h>. If COUNTING is true, - SI->dls_cnt and SI->dls_size are set; if false, those must be as set - by a previous call with COUNTING set, and SI must point to SI->dls_size - bytes to be used in filling in the result. */ -extern void _dl_rtld_di_serinfo (struct link_map *loader, - Dl_serinfo *si, bool counting) - internal_function; - - -/* Search loaded objects' symbol tables for a definition of the symbol - referred to by UNDEF. *SYM is the symbol table entry containing the - reference; it is replaced with the defining symbol, and the base load - address of the defining object is returned. SYMBOL_SCOPE is a - null-terminated list of object scopes to search; each object's - l_searchlist (i.e. the segment of the dependency tree starting at that - object) is searched in turn. REFERENCE_NAME should name the object - containing the reference; it is used in error messages. - TYPE_CLASS describes the type of symbol we are looking for. */ -enum - { - /* If necessary add dependency between user and provider object. */ - DL_LOOKUP_ADD_DEPENDENCY = 1, - /* Return most recent version instead of default version for - unversioned lookup. */ - DL_LOOKUP_RETURN_NEWEST = 2, - /* Set if dl_lookup* called with GSCOPE lock held. */ - DL_LOOKUP_GSCOPE_LOCK = 4, - }; - -/* Lookup versioned symbol. */ -extern lookup_t _dl_lookup_symbol_x (const char *undef, - struct link_map *undef_map, - const ElfW(Sym) **sym, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int flags, - struct link_map *skip_map) - internal_function attribute_hidden; - - -/* Look up symbol NAME in MAP's scope and return its run-time address. */ -extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name) - internal_function; - -/* Add the new link_map NEW to the end of the namespace list. */ -extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) - internal_function attribute_hidden; - -/* Allocate a `struct link_map' for a new object being loaded. */ -extern struct link_map *_dl_new_object (char *realname, const char *libname, - int type, struct link_map *loader, - int mode, Lmid_t nsid) - internal_function attribute_hidden; - -/* Relocate the given object (if it hasn't already been). - SCOPE is passed to _dl_lookup_symbol in symbol lookups. - If RTLD_LAZY is set in RELOC-MODE, don't relocate its PLT. */ -extern void _dl_relocate_object (struct link_map *map, - struct r_scope_elem *scope[], - int reloc_mode, int consider_profiling) - attribute_hidden; - -/* Protect PT_GNU_RELRO area. */ -extern void _dl_protect_relro (struct link_map *map) - internal_function attribute_hidden; - -/* Call _dl_signal_error with a message about an unhandled reloc type. - TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value. - PLT is nonzero if this was a PLT reloc; it just affects the message. */ -extern void _dl_reloc_bad_type (struct link_map *map, - unsigned int type, int plt) - internal_function __attribute__ ((__noreturn__)); - -/* Resolve conflicts if prelinking. */ -extern void _dl_resolve_conflicts (struct link_map *l, - ElfW(Rela) *conflict, - ElfW(Rela) *conflictend); - -/* Check the version dependencies of all objects available through - MAP. If VERBOSE print some more diagnostics. */ -extern int _dl_check_all_versions (struct link_map *map, int verbose, - int trace_mode) - internal_function; - -/* Check the version dependencies for MAP. If VERBOSE print some more - diagnostics. */ -extern int _dl_check_map_versions (struct link_map *map, int verbose, - int trace_mode) - internal_function; - -/* Initialize the object in SCOPE by calling the constructors with - ARGC, ARGV, and ENV as the parameters. */ -extern void _dl_init (struct link_map *main_map, int argc, char **argv, - char **env) internal_function attribute_hidden; - -/* Call the finalizer functions of all shared objects whose - initializer functions have completed. */ -extern void _dl_fini (void) internal_function; - -/* Sort array MAPS according to dependencies of the contained objects. */ -extern void _dl_sort_fini (struct link_map **maps, size_t nmaps, char *used, - Lmid_t ns) - internal_function; - -/* The dynamic linker calls this function before and having changing - any shared object mappings. The `r_state' member of `struct r_debug' - says what change is taking place. This function's address is - the value of the `r_brk' member. */ -extern void _dl_debug_state (void); -rtld_hidden_proto (_dl_debug_state) - -/* Initialize `struct r_debug' if it has not already been done. The - argument is the run-time load address of the dynamic linker, to be put - in the `r_ldbase' member. Returns the address of the structure. */ -extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) - internal_function; - -/* Initialize the basic data structure for the search paths. */ -extern void _dl_init_paths (const char *library_path) internal_function; - -/* Gather the information needed to install the profiling tables and start - the timers. */ -extern void _dl_start_profile (void) internal_function attribute_hidden; - -/* The actual functions used to keep book on the calls. */ -extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc); -extern void _dl_mcount_internal (ElfW(Addr) frompc, ElfW(Addr) selfpc) - attribute_hidden; - -/* This function is simply a wrapper around the _dl_mcount function - which does not require a FROMPC parameter since this is the - calling function. */ -extern void _dl_mcount_wrapper (void *selfpc); - -/* Show the members of the auxiliary array passed up from the kernel. */ -extern void _dl_show_auxv (void) internal_function; - -/* Return all environment variables starting with `LD_', one after the - other. */ -extern char *_dl_next_ld_env_entry (char ***position) internal_function; - -/* Return an array with the names of the important hardware capabilities. */ -extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform, - size_t paltform_len, - size_t *sz, - size_t *max_capstrlen) - internal_function; - -/* Look up NAME in ld.so.cache and return the file name stored there, - or null if none is found. */ -extern const char *_dl_load_cache_lookup (const char *name) - internal_function; - -/* If the system does not support MAP_COPY we cannot leave the file open - all the time since this would create problems when the file is replaced. - Therefore we provide this function to close the file and open it again - once needed. */ -extern void _dl_unload_cache (void) attribute_hidden; - -/* System-dependent function to read a file's whole contents in the - most convenient manner available. *SIZEP gets the size of the - file. On error MAP_FAILED is returned. */ -extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep, - int prot) - internal_function attribute_hidden; - -/* System-specific function to do initial startup for the dynamic linker. - After this, file access calls and getenv must work. This is responsible - for setting __libc_enable_secure if we need to be secure (e.g. setuid), - and for setting _dl_argc and _dl_argv, and then calling _dl_main. */ -extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, - void (*dl_main) (const ElfW(Phdr) *phdr, - ElfW(Word) phnum, - ElfW(Addr) *user_entry, - ElfW(auxv_t) *auxv)) - attribute_hidden; - -extern void _dl_sysdep_start_cleanup (void) - internal_function attribute_hidden; - - -/* Determine next available module ID. */ -extern size_t _dl_next_tls_modid (void) internal_function attribute_hidden; - -/* Calculate offset of the TLS blocks in the static TLS block. */ -extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden; - -/* Set up the data structures for TLS, when they were not set up at startup. - Returns nonzero on malloc failure. - This is called from _dl_map_object_from_fd or by libpthread. */ -extern int _dl_tls_setup (void) internal_function; -rtld_hidden_proto (_dl_tls_setup) - -/* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */ -extern void *_dl_allocate_tls (void *mem) internal_function; -rtld_hidden_proto (_dl_allocate_tls) - -/* Get size and alignment requirements of the static TLS block. */ -extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp) - internal_function; - -extern void _dl_allocate_static_tls (struct link_map *map) - internal_function attribute_hidden; - -/* These are internal entry points to the two halves of _dl_allocate_tls, - only used within rtld.c itself at startup time. */ -extern void *_dl_allocate_tls_storage (void) - internal_function attribute_hidden; -extern void *_dl_allocate_tls_init (void *) internal_function; -rtld_hidden_proto (_dl_allocate_tls_init) - -/* Deallocate memory allocated with _dl_allocate_tls. */ -extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function; -rtld_hidden_proto (_dl_deallocate_tls) - -extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden; - -/* Find origin of the executable. */ -extern const char *_dl_get_origin (void) attribute_hidden; - -/* Count DSTs. */ -extern size_t _dl_dst_count (const char *name, int is_path) attribute_hidden; - -/* Substitute DST values. */ -extern char *_dl_dst_substitute (struct link_map *l, const char *name, - char *result, int is_path) attribute_hidden; - -/* Check validity of the caller. */ -extern int _dl_check_caller (const void *caller, enum allowmask mask) - attribute_hidden; - -/* Open the shared object NAME, relocate it, and run its initializer if it - hasn't already been run. MODE is as for `dlopen' (see <dlfcn.h>). If - the object is already opened, returns its existing map. */ -extern void *_dl_open (const char *name, int mode, const void *caller, - Lmid_t nsid, int argc, char *argv[], char *env[]) - attribute_hidden; - -/* Free or queue for freeing scope OLD. If other threads might be - in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the - old scope, OLD can't be freed until no thread is using it. */ -extern int _dl_scope_free (void *) attribute_hidden; - -/* Add module to slot information data. */ -extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden; - -/* Update slot information data for at least the generation of the - module with the given index. */ -extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid); - -/* Look up the module's TLS block as for __tls_get_addr, - but never touch anything. Return null if it's not allocated yet. */ -extern void *_dl_tls_get_addr_soft (struct link_map *l) attribute_hidden; - -extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - internal_function attribute_hidden; - -/* Show show of an object. */ -extern void _dl_show_scope (struct link_map *new, int from); - -extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr) - internal_function; -rtld_hidden_proto (_dl_find_dso_for_object) - -/* Initialization which is normally done by the dynamic linker. */ -extern void _dl_non_dynamic_init (void) internal_function; - -/* Used by static binaries to check the auxiliary vector. */ -extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function; - - -__END_DECLS - -#endif /* ldsodefs.h */ diff --git a/tools/selective_cfi/zest_cfi_runtime/zest_dispatch64.s b/tools/selective_cfi/zest_cfi_runtime/zest_dispatch64.s deleted file mode 100644 index 394e86eea..000000000 --- a/tools/selective_cfi/zest_cfi_runtime/zest_dispatch64.s +++ /dev/null @@ -1,102 +0,0 @@ -BITS 64 - -default rel - -extern zest_cfi_dispatch_c - -%define cfi_dispatch_translation_cache_entries 16*1024 - -section .tls alloc write align=8 tls - -global translation_cache_src -translation_cache_src: times cfi_dispatch_translation_cache_entries dq 0 -translation_cache_targ: times cfi_dispatch_translation_cache_entries dq 0 - - -section .text -global zest_cfi_dispatch:function -zest_cfi_dispatch: - - ; not saving rbx, rsp, rbp, r12-r15 as C code should save them. - lea rsp, [rsp-128] - pushf - push rax - push rcx - - ; check translation cache. - mov rax,[rel translation_cache_src wrt ..gottpoff] - - ; rax contains tls address of translation_cache_src - - ; hash target - mov rcx, r11 - and rcx, ((cfi_dispatch_translation_cache_entries) -1) - - cmp r11, [fs:rax+rcx*8] - jne enter_c_code - -allow_xfer_fast: - mov rax, [fs:rax+rcx*8+cfi_dispatch_translation_cache_entries*8] - - -decide_to_check: - ; decide if we need to check the transfer, or if it's allowed. - ; checking the xfer is done if the target module has a zest_cfi symbol. - ; rax contains the address, if the symbol exists. - ; rax is 0 if the symbol does not exist. - cmp rax, 0 - je allow_xfer - -check_xfer: - mov rcx, rax ; save zest_cfi address into rcx. - mov rax, [rsp+8] ; restore rax. - mov [rsp+8], rcx ; write zest_cfi over rax location. - pop rcx ; restore rcx. - lea rsp, [rsp+8] ; skip over stack space for saved rax, which is now used for zest_zfi address. - popf ; restore rest of state. - lea rsp, [rsp+128] ; undo read zone - jmp [rsp-128-8-8] ; jump to zest_cfi address stored on stack. -128 for red zone, -8 for flags, -8 for rax. - - -allow_xfer: - pop rcx - pop rax - popf - lea rsp, [rsp+128] - jmp r11 - - - - -enter_c_code: - push rdx - push rsi - push rdi - push r8 - push r9 - push r10 - push r11 - mov rdi, r11 ; r11 is the cfi reg for x86-64, copy it to rdi for C-calling convention. - call zest_cfi_dispatch_c wrt ..plt - ; rax has the address of zest_cfi in the target module. - pop r11 - pop r10 - pop r9 - pop r8 - pop rdi - pop rsi - pop rdx - - - ; rax contains tls address of translation_cache_src - - ; hash target - mov rcx, r11 - and rcx, ((cfi_dispatch_translation_cache_entries) -1) - lea rcx, [rcx*8] - add rcx, [rel translation_cache_src wrt ..gottpoff] - mov [fs:rcx], r11 - mov [fs:rcx+cfi_dispatch_translation_cache_entries*8], rax - - ; resume computation - jmp decide_to_check -- GitLab