From 0c12ac25b03f8cb4fbc5080105d3c0e75e3a5194 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Fri, 10 Jul 2015 16:40:12 -0700 Subject: CPU ref: Fix potential buffer over-read / uninitialized memory access. GetCpuInfo() was reading /proc/cpuinfo into a string without properly null terminating the result. The resulting unterminated string was being passed to strstr(). Change the code to read the file with fgets(), which ensures the result is null terminated. Also, document the GetCpuInfo() function and the global variable that it sets. Change-Id: I041331fdc25d79217ff7c1bf36a4aff2be8e0192 (cherry picked from commit 11fd9ec1ab8dfa7ae45c6edeea48dddc4633efea) --- cpu_ref/rsCpuCore.cpp | 42 +++++++++++++----------------------------- cpu_ref/rsCpuCore.h | 1 + 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/cpu_ref/rsCpuCore.cpp b/cpu_ref/rsCpuCore.cpp index 88893279..d5bd5fef 100644 --- a/cpu_ref/rsCpuCore.cpp +++ b/cpu_ref/rsCpuCore.cpp @@ -26,13 +26,10 @@ #include #include #include +#include #include #include -#include -#include -#include - #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) #include #include "utils/StopWatch.h" @@ -200,38 +197,25 @@ void RsdCpuReferenceImpl::unlockMutex() { pthread_mutex_unlock(&gInitMutex); } -static int -read_file(const char* pathname, char* buffer, size_t buffsize) -{ - int fd, len; - - fd = open(pathname, O_RDONLY); - if (fd < 0) - return -1; - - do { - len = read(fd, buffer, buffsize); - } while (len < 0 && errno == EINTR); - - close(fd); - - return len; -} - +// Determine if the CPU we're running on supports SIMD instructions. static void GetCpuInfo() { - char cpuinfo[4096]; - int cpuinfo_len; + // Read the CPU flags from /proc/cpuinfo. + FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); - cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo); - if (cpuinfo_len < 0) /* should not happen */ { + if (!cpuinfo) { return; } + char cpuinfostr[4096]; + if (!fgets(cpuinfostr, sizeof(cpuinfostr), cpuinfo)) { + cpuinfostr[0] = '\0'; + } + fclose(cpuinfo); + #if defined(ARCH_ARM_HAVE_VFP) || defined(ARCH_ARM_USE_INTRINSICS) - gArchUseSIMD = (!!strstr(cpuinfo, " neon")) || - (!!strstr(cpuinfo, " asimd")); + gArchUseSIMD = strstr(cpuinfostr, " neon") || strstr(cpuinfostr, " asimd"); #elif defined(ARCH_X86_HAVE_SSSE3) - gArchUseSIMD = !!strstr(cpuinfo, " ssse3"); + gArchUseSIMD = strstr(cpuinfostr, " ssse3"); #endif } diff --git a/cpu_ref/rsCpuCore.h b/cpu_ref/rsCpuCore.h index c350f509..bc3b5dd9 100644 --- a/cpu_ref/rsCpuCore.h +++ b/cpu_ref/rsCpuCore.h @@ -34,6 +34,7 @@ namespace bcc { namespace android { namespace renderscript { +// Whether the CPU we're running on supports SIMD instructions extern bool gArchUseSIMD; typedef void (* InvokeFunc_t)(void); -- cgit v1.2.3