Perf + armcap fixes
* Perf is setting 'exclude_callchain_kernel' flag which requires kernels >= 3.7.
Detect old kernels and abort archInit() if not compatible.
TODO: See if disabling that flag at runtime for non-compatible kernels affects perf operations
* For ARM kernels running Android API <= 21, if fuzzing target links to
libcrypto (OpenSSL), OPENSSL_cpuid_setup initialization is triggering a
SIGILL/ILLOPC at armv7_tick(). Setups using BoringSSL (API >= 22) are
not affected.
Signed-off-by: Anestis Bechtsoudis <anestis@census-labs.com>
diff --git a/android/Android.mk b/android/Android.mk
index ed14b08..249c6a5 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,13 @@
$(error Unsuported / Unknown APP_API '$(APP_ABI)')
endif
+ # Additional libcrypto OpenSSL flags required to mitigate bug (ARM systems with API <= 21)
+ ifeq ($(APP_ABI),$(filter $(APP_ABI),armeabi))
+ OPENSSL_ARMCAP_ABI := "5"
+ else
+ OPENSSL_ARMCAP_ABI := "7"
+ endif
+
# Upstream libunwind compiled from sources with Android NDK toolchain
LIBUNWIND_A := third_party/android/libunwind/$(ARCH_ABI)/libunwind-$(UNW_ARCH).a
ifeq ("$(wildcard $(LIBUNWIND_A))","")
@@ -113,6 +120,6 @@
endif
LOCAL_SRC_FILES += $(ARCH_SRCS)
-LOCAL_CFLAGS += -D_HF_ARCH_${ARCH}
+LOCAL_CFLAGS += -D_HF_ARCH_${ARCH} -DOPENSSL_ARMCAP_ABI='$(OPENSSL_ARMCAP_ABI)'
include $(BUILD_EXECUTABLE)
diff --git a/linux/arch.c b/linux/arch.c
index 2518dd0..ab204e4 100644
--- a/linux/arch.c
+++ b/linux/arch.c
@@ -44,6 +44,7 @@
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
+#include <sys/utsname.h>
#include "linux/perf.h"
#include "linux/ptrace_utils.h"
@@ -333,8 +334,49 @@
bool arch_archInit(honggfuzz_t * hfuzz)
{
- return true;
- if (hfuzz) {
- return true;
+ unsigned long major = 0, minor = 0;
+ char *p = NULL;
+
+ if (hfuzz->dynFileMethod != _HF_DYNFILE_NONE) {
+ /*
+ * Check that linux kernel is compatible
+ *
+ * Compatibility list:
+ * 1) Perf exclude_callchain_kernel requires kernel >= 3.7
+ * TODO: Runtime logic to disable it for unsupported kernels
+ * if it doesn't affect perf counters processing
+ */
+ struct utsname uts;
+ if (uname(&uts) == -1) {
+ LOGMSG_P(l_FATAL, "uname() failed");
+ return false;
+ }
+
+ p = uts.release;
+ major = strtoul(p, &p, 10);
+ if (*p++ != '.') {
+ LOGMSG(l_FATAL, "Unsupported kernel version (%s)", uts.release);
+ return false;
+ }
+
+ minor = strtoul(p, &p, 10);
+ if ((major < 3) || ((major == 3) && (minor < 7))) {
+ LOGMSG(l_ERROR, "Unsupported kernel version (%s)", uts.release);
+ return false;
+ }
}
+#if defined(__ANDROID__) && defined(__arm__)
+ /*
+ * For ARM kernels running Android API <= 21, if fuzzing target links to
+ * libcrypto (OpenSSL), OPENSSL_cpuid_setup initialization is triggering a
+ * SIGILL/ILLOPC at armv7_tick() due to "mrrc p15, #1, r0, r1, c14)" instruction.
+ * Setups using BoringSSL (API >= 22) are not affected.
+ */
+ if (setenv("OPENSSL_armcap", OPENSSL_ARMCAP_ABI, 1) == -1) {
+ LOGMSG_P(l_ERROR, "setenv(OPENSSL_armcap) failed");
+ return false;
+ }
+#endif
+
+ return true;
}