Fix a crash in ARM's CPUDetect on a malformed /proc/cpuinfo.

If a CPU string was incapable of being found we would return a null pointer, which would crash with strncpy.
Also if we couldn't get a CPU implementer we would call free() to a null pointer.
In addition, detect 64bit ARM running.
This commit is contained in:
Ryan Houdek 2014-06-01 23:49:23 -05:00
parent 31eedb2f79
commit 5d3382fb56
1 changed files with 15 additions and 8 deletions

View File

@ -11,7 +11,7 @@
#if !defined(BLACKBERRY) && !defined(IOS) && !defined(__SYMBIAN32__) #if !defined(BLACKBERRY) && !defined(IOS) && !defined(__SYMBIAN32__)
const char procfile[] = "/proc/cpuinfo"; const char procfile[] = "/proc/cpuinfo";
char *GetCPUString() std::string GetCPUString()
{ {
const char marker[] = "Hardware\t: "; const char marker[] = "Hardware\t: ";
char *cpu_string = nullptr; char *cpu_string = nullptr;
@ -31,8 +31,10 @@ char *GetCPUString()
cpu_string = strndup(cpu_string, strlen(cpu_string) - 1); // Strip the newline cpu_string = strndup(cpu_string, strlen(cpu_string) - 1); // Strip the newline
break; break;
} }
if (cpu_string)
return cpu_string; return std::string(cpu_string);
else
return "";
} }
unsigned char GetCPUImplementer() unsigned char GetCPUImplementer()
@ -54,11 +56,10 @@ unsigned char GetCPUImplementer()
implementer_string = buf + sizeof(marker) - 1; implementer_string = buf + sizeof(marker) - 1;
implementer_string = strndup(implementer_string, strlen(implementer_string) - 1); // Strip the newline implementer_string = strndup(implementer_string, strlen(implementer_string) - 1); // Strip the newline
sscanf(implementer_string, "0x%02hhx", &implementer); sscanf(implementer_string, "0x%02hhx", &implementer);
free(implementer_string);
break; break;
} }
free(implementer_string);
return implementer; return implementer;
} }
@ -81,11 +82,10 @@ unsigned short GetCPUPart()
part_string = buf + sizeof(marker) - 1; part_string = buf + sizeof(marker) - 1;
part_string = strndup(part_string, strlen(part_string) - 1); // Strip the newline part_string = strndup(part_string, strlen(part_string) - 1); // Strip the newline
sscanf(part_string, "0x%03hx", &part); sscanf(part_string, "0x%03hx", &part);
free(part_string);
break; break;
} }
free(part_string);
return part; return part;
} }
@ -156,9 +156,15 @@ void CPUInfo::Detect()
// Set some defaults here // Set some defaults here
// When ARMv8 cpus come out, these need to be updated. // When ARMv8 cpus come out, these need to be updated.
HTT = false; HTT = false;
#ifdef _M_ARM_64
OS64bit = true;
CPU64bit = true;
Mode64bit = true;
#else
OS64bit = false; OS64bit = false;
CPU64bit = false; CPU64bit = false;
Mode64bit = false; Mode64bit = false;
#endif
vendor = VENDOR_ARM; vendor = VENDOR_ARM;
// Get the information about the CPU // Get the information about the CPU
@ -209,7 +215,7 @@ void CPUInfo::Detect()
bFP = false; bFP = false;
bASIMD = false; bASIMD = false;
#else #else
strncpy(cpu_string, GetCPUString(), sizeof(cpu_string)); strncpy(cpu_string, GetCPUString().c_str(), sizeof(cpu_string));
bSwp = CheckCPUFeature("swp"); bSwp = CheckCPUFeature("swp");
bHalf = CheckCPUFeature("half"); bHalf = CheckCPUFeature("half");
bThumb = CheckCPUFeature("thumb"); bThumb = CheckCPUFeature("thumb");
@ -264,6 +270,7 @@ std::string CPUInfo::Summarize()
if (bVFPv4) sum += ", VFPv4"; if (bVFPv4) sum += ", VFPv4";
if (bIDIVa) sum += ", IDIVa"; if (bIDIVa) sum += ", IDIVa";
if (bIDIVt) sum += ", IDIVt"; if (bIDIVt) sum += ", IDIVt";
if (CPU64bit) sum += ", 64-bit";
return sum; return sum;
} }