# Makefile - CVE-2017-5753 user-to-user sucess rate measurement # # Copyright (c) 2022 Samuel AUBERTIN # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .PHONY: clean build upload findfalses .SILENT: MAKEFLAGS:= -j4 ifeq ($(shell uname),OpenBSD) GCC:= DEPS:= clang ./uuid ifndef MKUUID MKUUID!= $(shell stat uuid > /dev/null 2>&1 || (make -C uuid_obsd && ln -s uuid_obsd/uuid uuid)) endif else GCC:= gcc DEPS:= $(GCC) clang uuid lld LDFLAGS+= -fuse-ld=lld endif ifdef MKUUID EXECUTABLES= $(DEPS) XXXX:= $(foreach exec,$(EXECUTABLES), $(if $(shell which $(exec) 2> /dev/null),X,$(error "No '$(exec)' in PATH, please install it and restart octopus !"))) endif ### Generic flags SRCS= spectre_v1 spectre_v2 CFLAGS+= -march=native CFLAGS+= -W CFLAGS+= -Wall CFLAGS+= -Werror -Wextra CFLAGS+= -Wno-unused-parameter CFLAGS+= -Wno-missing-field-initializers # Multiples optimization levels break when inlining victim_function for spectre v2 CFLAGS+= -fno-inline-functions # Debug symbols #CFLAGS+= -g ### Octopus flags CCS= clang $(GCC) OPTIMIZATIONS= 0 1 2 3 fast s UUID:= $(shell uuid 2> /dev/null || uuidgen 2> /dev/null || ./uuid) RESULTS_FILE:= results-$(UUID).json SSH_KEY= octoupload TIMES= 3 OCTOFLAGS= -j ifeq ($(shell uname),OpenBSD) COUNTER= $(shell jot $(TIMES) 1) else COUNTER= $(shell seq $(TIMES)) endif ### Octopus internals CPU:= $(shell LC_ALL=en_US.UTF-8 lscpu | grep "Model name" | cut -d":" -f 2 | sort | uniq | awk '{$$1=$$1;print}') UCODE:= $(shell (grep microcode /proc/cpuinfo 2> /dev/null || printf unknown) | sort | uniq | awk '{print $$NF}' || printf unknown) KERN:= $(shell uname -svm) CLANGV:= $(shell clang -v 2>&1 | head -n 1) GCCV:= $(shell (gcc -v 2>&1 | grep 'gcc version') || printf unknown) VULN1:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v1 2> /dev/null || printf unknown)) VULN2:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v2 2> /dev/null || printf unknown)) ifneq ($(shell uname),OpenBSD) ifndef PROGRESS HIT_TOTAL!= $(MAKE) $(MAKECMDGOALS) --dry-run PROGRESS="HIT_MARK" | grep -c "HIT_MARK" HIT_COUNT= $(eval HIT_N != expr $(HIT_N) + 1)$(HIT_N) PROGRESS= echo "[`expr $(HIT_COUNT) '*' 100 / $(HIT_TOTAL)`%]" endif endif SUB_ONE= $(word 1, $(subst -, ,$@)) SUB_TWO= $(word 2, $(subst -, ,$@)) SUB_THREE= $(word 3, $(subst -, ,$@)) SUB_FOUR= $(word 4, $(subst -, ,$@)) ### Compilers CPROGS= $(foreach C, $(CCS), $(addsuffix -$(C), $(SRCS))) ### Optimizations OPTIMIZED_PROGRAMS= $(foreach O, $(OPTIMIZATIONS), $(addsuffix -O$(O), $(CPROGS))) ### Static STATIC_PROGRAMS= $(addsuffix -static, $(foreach O, $(OPTIMIZATIONS), $(addsuffix -O$(O), $(CPROGS)))) ##### V1 ### Masking mitigation MASKING_PROGRAMS= $(addsuffix -mask, $(filter spectre_v1%, $(OPTIMIZED_PROGRAMS))) MASKING_STATIC_PROGRAMS= $(addsuffix -mask, $(filter spectre_v1%, $(STATIC_PROGRAMS))) ### Lfence mitigation LFENCE_PROGRAMS= $(addsuffix -fence, $(filter spectre_v1%, $(OPTIMIZED_PROGRAMS))) LFENCE_STATIC_PROGRAMS= $(addsuffix -fence, $(filter spectre_v1%, $(STATIC_PROGRAMS))) ###### V2 ### Retpoline ## clang # dynamic RETPOLINE_CLANG_PROGRAMS= $(addsuffix -retpoline, $(filter spectre_v2-clang%, $(OPTIMIZED_PROGRAMS))) # static RETPOLINE_STATIC_CLANG_PROGRAMS= $(addsuffix -retpoline, $(filter spectre_v2-clang%, $(STATIC_PROGRAMS))) ## gcc # dynamic RETPOLINE_GCC_PROGRAMS= $(addsuffix -retpoline, $(filter spectre_v2-gcc%, $(OPTIMIZED_PROGRAMS))) # static RETPOLINE_STATIC_GCC_PROGRAMS= $(addsuffix -retpoline, $(filter spectre_v2-gcc%, $(STATIC_PROGRAMS))) # Add GCC's specific flag V2_GCC_PROGRAMS= $(filter spectre_v2-gcc%, $(STATIC_PROGRAMS)) $(filter spectre_v2-gcc%, $(OPTIMIZED_PROGRAMS)) $(RETPOLINE_GCC_PROGRAMS) $(RETPOLINE_STATIC_GCC_PROGRAMS) $(V2_GCC_PROGRAMS): CFLAGS+=-fno-inline-small-functions PROGS= $(OPTIMIZED_PROGRAMS) PROGS+= $(STATIC_PROGRAMS) PROGS+= $(MASKING_PROGRAMS) PROGS+= $(MASKING_STATIC_PROGRAMS) PROGS+= $(LFENCE_PROGRAMS) PROGS+= $(LFENCE_STATIC_PROGRAMS) PROGS+= $(RETPOLINE_CLANG_PROGRAMS) PROGS+= $(RETPOLINE_STATIC_CLANG_PROGRAMS) PROGS+= $(V2_GCC_PROGRAMS) all: upload printf "\033[1mThank you for helping science today !\033[0m\n" upload: $(RESULTS_FILE) printf "\033[4mUploading $^ to www.sk4.nz\033[0m\n" chmod 600 $(SSH_KEY) printf 'put $^\n' | sftp -b - -i $(SSH_KEY) \ -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ octoupload@www.sk4.nz: findfalses: $(RESULTS_FILE) cat *.json | jq -c '.[].results[] | select(.[] == false)' | sort | uniq build: $(PROGS) $(RESULTS_FILE): build printf '\033[1m\033[94m________ __\n' printf '\\_____ \\ _____/ |_ ____ ______ __ __ ______\n' printf ' / | \\_/ ___\\ __\\/ _ \\\\____ \\| | \\/ ___/\n' printf '/ | \\ \\___| | ( <_> ) |_> > | /\\___ \\ \n' printf '\\_______ /\\___ >__| \\____/| __/|____//____ >\n' printf ' \\/ \\/ |__| \\/\033[0m\n' printf ' Samuel AUBERTIN - EURECOM\n' printf "\033[4mUUID\033[0m\t\t$(UUID)\n" printf "\033[4mCPU\033[0m\t\t$(CPU)\n" printf "\033[4mMicrocode\033[0m\t$(UCODE)\n" printf "\033[4mKernel\033[0m\t\t$(KERN)\n" printf "\033[4mClang\033[0m\t\t$(CLANGV)\n" printf "\033[4mGCC\033[0m\t\t$(GCCV)\n" printf "\033[4mSpectre v1\033[0m\t$(VULN1)\n" printf "\033[4mSpectre v2\033[0m\t$(VULN2)\n" printf "{ \"$(UUID)\": {\n" >> $@ printf "\"cpu\": \"$(CPU)\",\n" >> $@ printf "\"microcode\": \"$(UCODE)\",\n" >> $@ printf "\"kernel\": \"$(KERN)\",\n" >> $@ printf "\"clang\": \"$(CLANGV)\",\n" >> $@ printf "\"gcc\": \"$(GCCV)\",\n" >> $@ printf "\"spectre_v1\": \"$(VULN1)\",\n" >> $@ printf "\"spectre_v2\": \"$(VULN2)\",\n" >> $@ printf "\"results\": [\n" >> $@ for p in $(PROGS); do \ for t in $(COUNTER); do \ sleep 0.1; \ (./$$p $(OCTOFLAGS) || printf "{ \"$$p\": false }")>> $@; \ if ! [ "$$p" = "$(lastword $(PROGS))" ]; \ then printf ',\n' >> $@; \ else if ! [ $$t -eq $(TIMES) ]; \ then printf ',\n' >> $@; fi; \ fi; \ done \ done printf "\n]}}\n" >> $@ $(OPTIMIZED_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(CFLAGS) $(LDFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(CFLAGS) $(LDFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(STATIC_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(MASKING_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(CFLAGS) -DMASKING_MITIGATION $(LDFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(CFLAGS) -DMASKING_MITIGATION $(LDFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(MASKING_STATIC_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -DMASKING_MITIGATION -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -DMASKING_MITIGATION -$(SUB_THREE) -o $@ $(SUB_ONE).c $(LFENCE_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(CFLAGS) -DLFENCE_MITIGATION $(LDFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(CFLAGS) -DLFENCE_MITIGATION $(LDFLAGS) -$(SUB_THREE) -o $@ $(SUB_ONE).c $(LFENCE_STATIC_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -DLFENCE_MITIGATION -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -DLFENCE_MITIGATION -$(SUB_THREE) -o $@ $(SUB_ONE).c $(RETPOLINE_CLANG_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(CFLAGS) -mretpoline $(LDFLAGS) -z retpolineplt -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(CFLAGS) -mretpoline $(LDFLAGS) -z retpolineplt -$(SUB_THREE) -o $@ $(SUB_ONE).c $(RETPOLINE_STATIC_CLANG_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -mretpoline -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -mretpoline -$(SUB_THREE) -o $@ $(SUB_ONE).c $(RETPOLINE_GCC_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(CFLAGS) -mfunction-return=thunk -mindirect-branch=thunk -mindirect-branch-register $(LDFLAGS) -z retpolineplt -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(CFLAGS) -mfunction-return=thunk -mindirect-branch=thunk -mindirect-branch-register $(LDFLAGS) -z retpolineplt -$(SUB_THREE) -o $@ $(SUB_ONE).c $(RETPOLINE_STATIC_GCC_PROGRAMS): @$(PROGRESS) $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -mfunction-return=thunk -mindirect-branch=thunk -mindirect-branch-register -$(SUB_THREE) -o $@ $(SUB_ONE).c $(SUB_TWO) $(addprefix -, $(SUB_FOUR)) $(CFLAGS) -mfunction-return=thunk -mindirect-branch=thunk -mindirect-branch-register -$(SUB_THREE) -o $@ $(SUB_ONE).c clean: rm -rf $(PROGS) *.json ifeq ($(shell uname),OpenBSD) -make -C uuid_obsd clean endif