diff options
author | Matt Wala <wala@google.com> | 2015-07-10 16:40:12 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-07-13 23:35:29 -0700 |
commit | 0c12ac25b03f8cb4fbc5080105d3c0e75e3a5194 (patch) | |
tree | f27907f5787968714982cfa45f44c05bec312700 | |
parent | db060579769662eeee0f73d3815edaa98abd0ab2 (diff) | |
download | rs-0c12ac25b03f8cb4fbc5080105d3c0e75e3a5194.tar.gz |
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)
-rw-r--r-- | cpu_ref/rsCpuCore.cpp | 42 | ||||
-rw-r--r-- | 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 <sys/resource.h> #include <sched.h> #include <sys/syscall.h> +#include <stdio.h> #include <string.h> #include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> - #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) #include <cutils/properties.h> #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); |