freebsd-ports/security/sandsifter/files/patch-injector.c
Rene Ladan 48192f57b0 The sandsifter audits x86 processors for hidden instructions and
hardware bugs, by systematically generating machine code to search
through a processor's instruction set, and monitoring execution for
anomalies. Sandsifter has uncovered secret processor instructions from
every major vendor; ubiquitous software bugs in disassemblers,
assemblers, and emulators; flaws in enterprise hypervisors; and both
benign and security-critical hardware bugs in x86 chips.

WWW: https://github.com/xoreaxeaxeax/sandsifter

PR:		221132
Submitted by:	rozhuk.im AT gmail.com
Reviewed by:	swills
2017-09-30 15:13:32 +00:00

107 lines
3.1 KiB
C

--- injector.c.orig 2017-07-27 19:17:30 UTC
+++ injector.c
@@ -77,10 +77,24 @@ cs_insn *capstone_insn;
/* 32 vs 64 */
-#if __x86_64__
- #define IP REG_RIP
+#ifdef __linux__
+# define PAGE_SIZE 4096
+# define EFL gregs[REG_EFL]
+# if __x86_64__
+# define IP gregs[REG_RIP]
+# else
+# define IP gregs[REG_EIP]
+# endif
#else
- #define IP REG_EIP
+# include <pthread_np.h>
+ typedef cpuset_t cpu_set_t;
+# if __x86_64__
+# define IP mc_rip
+# define EFL mc_rflags
+# else
+# define IP mc_eip
+# define EFL mc_eflags
+# endif
#endif
/* leave state as 0 */
@@ -155,7 +169,6 @@ state_t inject_state={
/* x86/64 */
#define UD2_SIZE 2
-#define PAGE_SIZE 4096
#define TF 0x100
/* injection */
@@ -293,6 +306,10 @@ ignore_op_t opcode_blacklist[MAX_BLACKLIST]={
{ "\xcd\x80", "int 0x80" },
/* as will syscall */
{ "\x0f\x05", "syscall" },
+ /* int 92 on FreeBSD triggers DTrace, which will trigger SIGSYS */
+ { "\xcd\x92", "int 0x92" },
+ /* int 93 on FreeBSD is used by Xen */
+ { "\xcd\x93", "int 0x93" },
/* ud2 is an undefined opcode, and messes up a length differential search
* b/c of the fault it throws */
{ "\x0f\xb9", "ud2" },
@@ -850,7 +867,7 @@ void inject(int insn_size)
void state_handler(int signum, siginfo_t* si, void* p)
{
fault_context=((ucontext_t*)p)->uc_mcontext;
- ((ucontext_t*)p)->uc_mcontext.gregs[IP]+=UD2_SIZE;
+ ((ucontext_t*)p)->uc_mcontext.IP+=UD2_SIZE;
}
void fault_handler(int signum, siginfo_t* si, void* p)
@@ -863,7 +880,7 @@ void fault_handler(int signum, siginfo_t* si, void* p)
/* make an initial estimate on the instruction length from the fault address */
insn_length=
- (uintptr_t)uc->uc_mcontext.gregs[IP]-(uintptr_t)packet-preamble_length;
+ (uintptr_t)uc->uc_mcontext.IP-(uintptr_t)packet-preamble_length;
if (insn_length<0) {
insn_length=JMP_LENGTH;
@@ -880,9 +897,13 @@ void fault_handler(int signum, siginfo_t* si, void* p)
(signum==SIGSEGV||signum==SIGBUS)?(uint32_t)(uintptr_t)si->si_addr:(uint32_t)-1
};
+#ifdef __linux__
memcpy(uc->uc_mcontext.gregs, fault_context.gregs, sizeof(fault_context.gregs));
- uc->uc_mcontext.gregs[IP]=(uintptr_t)&resume;
- uc->uc_mcontext.gregs[REG_EFL]&=~TF;
+#else
+ memcpy(&uc->uc_mcontext, &fault_context, sizeof(fault_context));
+#endif
+ uc->uc_mcontext.IP=(uintptr_t)&resume;
+ uc->uc_mcontext.EFL&=~TF;
}
void configure_sig_handler(void (*handler)(int, siginfo_t*, void*))
@@ -1341,7 +1362,13 @@ void pin_core(void)
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(config.core,&mask);
- if (sched_setaffinity(0, sizeof(mask), &mask)) {
+#ifdef __linux__
+ if (sched_setaffinity(0, sizeof(mask), &mask))
+#else
+ if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, sizeof(mask), &mask))
+#endif
+ {
printf("error: failed to set cpu\n");
exit(1);
}
@@ -1439,7 +1466,7 @@ int main(int argc, char** argv)
null_p=mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (null_p==MAP_FAILED) {
- printf("null access requires running as root\n");
+ printf("null access requires running as root, %i\n", errno);
exit(1);
}
}