From e9260740ac70ce654d36cf4a8e4b6175efb4626e Mon Sep 17 00:00:00 2001 From: Matt Mower Date: Sun, 22 Feb 2015 20:20:18 -0600 Subject: Cleanup device_id retrieval * If TW_USE_MODEL_HARDWARE_ID_FOR_DEVICE_ID is defined: - provide the header that defines property functions/constants - actually look for hardware_id before attempting to append it * Perform string length checks rigorously. * Only perform newline removal if string is used before sanitization. * Copy changes to htcdumlock, but rely on cmdline only. ps3: fix merge conflict in data.cpp includes Change-Id: I720d3bc8416758f5f83782e8bc298b32eda1a573 --- data.cpp | 154 ++++++++++++++++++++++++++---------------------- htcdumlock/htcdumlock.c | 118 ++++++++++++------------------------- 2 files changed, 122 insertions(+), 150 deletions(-) diff --git a/data.cpp b/data.cpp index a032d40cd..6e39bc3f9 100644 --- a/data.cpp +++ b/data.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -47,8 +48,10 @@ #endif #include "find_file.hpp" #include "set_metadata.h" +#include -#include "cutils/properties.h" +#define DEVID_MAX 64 +#define HWID_MAX 32 #ifndef TW_MAX_BRIGHTNESS #define TW_MAX_BRIGHTNESS 255 @@ -77,14 +80,14 @@ pthread_mutex_t DataManager::m_valuesLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; // Device ID functions void DataManager::sanitize_device_id(char* device_id) { - const char* whitelist ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-._"; - char str[50]; + const char* whitelist ="-._"; + char str[DEVID_MAX]; char* c = str; - strcpy(str, device_id); - memset(device_id, 0, sizeof(device_id)); + snprintf(str, DEVID_MAX, "%s", device_id); + memset(device_id, 0, strlen(device_id)); while (*c) { - if (strchr(whitelist, *c)) + if (isalnum(*c) || strchr(whitelist, *c)) strncat(device_id, c, 1); c++; } @@ -100,30 +103,55 @@ void DataManager::sanitize_device_id(char* device_id) { void DataManager::get_device_id(void) { FILE *fp; + size_t i; char line[2048]; - char hardware_id[32], device_id[64]; + char hardware_id[HWID_MAX] = { 0 }; + char device_id[DEVID_MAX] = { 0 }; char* token; - // Assign a blank device_id to start with - device_id[0] = 0; - #ifdef TW_USE_MODEL_HARDWARE_ID_FOR_DEVICE_ID - // Now we'll use product_model_hardwareid as device id + // Use (product_model)_(hardware_id) as device id char model_id[PROPERTY_VALUE_MAX]; property_get("ro.product.model", model_id, "error"); - if (strcmp(model_id,"error") != 0) { + if (strcmp(model_id, "error") != 0) { LOGINFO("=> product model: '%s'\n", model_id); // Replace spaces with underscores - for(int i = 0; i < strlen(model_id); i++) { - if(model_id[i] == ' ') - model_id[i] = '_'; + for (i = 0; i < strlen(model_id); i++) { + if (model_id[i] == ' ') + model_id[i] = '_'; } - strcpy(device_id, model_id); - if (hardware_id[0] != 0) { - strcat(device_id, "_"); - strcat(device_id, hardware_id); + snprintf(device_id, DEVID_MAX, "%s", model_id); + + if (strlen(device_id) < DEVID_MAX) { + fp = fopen("proc_cpuinfo.txt", "rt"); + if (fp != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { + if (memcmp(line, CPUINFO_HARDWARE, + CPUINFO_HARDWARE_LEN) == 0) { + // skip past "Hardware", spaces, and colon + token = line + CPUINFO_HARDWARE_LEN; + while (*token && (!isgraph(*token) || *token == ':')) + token++; + + if (*token && *token != '\n' + && strcmp("UNKNOWN\n", token)) { + snprintf(hardware_id, HWID_MAX, "%s", token); + if (hardware_id[strlen(hardware_id)-1] == '\n') + hardware_id[strlen(hardware_id)-1] = 0; + LOGINFO("=> hardware id from cpuinfo: '%s'\n", + hardware_id); + } + break; + } + } + fclose(fp); + } } - sanitize_device_id((char *)device_id); + + if (hardware_id[0] != 0) + snprintf(device_id, DEVID_MAX, "%s_%s", model_id, hardware_id); + + sanitize_device_id(device_id); mConstValues.insert(make_pair("device_id", device_id)); LOGINFO("=> using device id: '%s'\n", device_id); return; @@ -131,26 +159,18 @@ void DataManager::get_device_id(void) { #endif #ifndef TW_FORCE_CPUINFO_FOR_DEVICE_ID - // First, try the cmdline to see if the serial number was supplied + // Check the cmdline to see if the serial number was supplied fp = fopen("/proc/cmdline", "rt"); - if (fp != NULL) - { - // First step, read the line. For cmdline, it's one long line + if (fp != NULL) { fgets(line, sizeof(line), fp); - fclose(fp); + fclose(fp); // cmdline is only one line long - // Now, let's tokenize the string token = strtok(line, " "); - - // Let's walk through the line, looking for the CMDLINE_SERIALNO token - while (token) - { - // We don't need to verify the length of token, because if it's too short, it will mismatch CMDLINE_SERIALNO at the NULL - if (memcmp(token, CMDLINE_SERIALNO, CMDLINE_SERIALNO_LEN) == 0) - { - // We found the serial number! - strcpy(device_id, token + CMDLINE_SERIALNO_LEN); - sanitize_device_id((char *)device_id); + while (token) { + if (memcmp(token, CMDLINE_SERIALNO, CMDLINE_SERIALNO_LEN) == 0) { + token += CMDLINE_SERIALNO_LEN; + snprintf(device_id, DEVID_MAX, "%s", token); + sanitize_device_id(device_id); // also removes newlines mConstValues.insert(make_pair("device_id", device_id)); return; } @@ -158,42 +178,36 @@ void DataManager::get_device_id(void) { } } #endif - // Now we'll try cpuinfo for a serial number + // Check cpuinfo for serial number; if found, use as device_id + // If serial number is not found, fallback to hardware_id for the device_id fp = fopen("/proc/cpuinfo", "rt"); - if (fp != NULL) - { - while (fgets(line, sizeof(line), fp) != NULL) { // First step, read the line. - if (memcmp(line, CPUINFO_SERIALNO, CPUINFO_SERIALNO_LEN) == 0) // check the beginning of the line for "Serial" - { - // We found the serial number! - token = line + CPUINFO_SERIALNO_LEN; // skip past "Serial" - while ((*token > 0 && *token <= 32 ) || *token == ':') token++; // skip over all spaces and the colon - if (*token != 0) { - token[30] = 0; - if (token[strlen(token)-1] == 10) { // checking for endline chars and dropping them from the end of the string if needed - memset(device_id, 0, sizeof(device_id)); - strncpy(device_id, token, strlen(token) - 1); - } else { - strcpy(device_id, token); - } + if (fp != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { + if (memcmp(line, CPUINFO_SERIALNO, CPUINFO_SERIALNO_LEN) == 0) { + // skip past "Serial", spaces, and colon + token = line + CPUINFO_SERIALNO_LEN; + while (*token && (!isgraph(*token) || *token == ':')) + token++; + + if (*token && *token != '\n') { + snprintf(device_id, DEVID_MAX, "%s", token); + sanitize_device_id(device_id); // also removes newlines LOGINFO("=> serial from cpuinfo: '%s'\n", device_id); - fclose(fp); - sanitize_device_id((char *)device_id); mConstValues.insert(make_pair("device_id", device_id)); + fclose(fp); return; } - } else if (memcmp(line, CPUINFO_HARDWARE, CPUINFO_HARDWARE_LEN) == 0) {// We're also going to look for the hardware line in cpuinfo and save it for later in case we don't find the device ID - // We found the hardware ID - token = line + CPUINFO_HARDWARE_LEN; // skip past "Hardware" - while ((*token > 0 && *token <= 32 ) || *token == ':') token++; // skip over all spaces and the colon - if (*token != 0) { - token[30] = 0; - if (token[strlen(token)-1] == 10) { // checking for endline chars and dropping them from the end of the string if needed - memset(hardware_id, 0, sizeof(hardware_id)); - strncpy(hardware_id, token, strlen(token) - 1); - } else { - strcpy(hardware_id, token); - } + } else if (memcmp(line, CPUINFO_HARDWARE, + CPUINFO_HARDWARE_LEN) == 0) { + // skip past "Hardware", spaces, and colon + token = line + CPUINFO_HARDWARE_LEN; + while (*token && (!isgraph(*token) || *token == ':')) + token++; + + if (*token && *token != '\n') { + snprintf(hardware_id, HWID_MAX, "%s", token); + if (hardware_id[strlen(hardware_id)-1] == '\n') + hardware_id[strlen(hardware_id)-1] = 0; LOGINFO("=> hardware id from cpuinfo: '%s'\n", hardware_id); } } @@ -203,14 +217,14 @@ void DataManager::get_device_id(void) { if (hardware_id[0] != 0) { LOGINFO("\nusing hardware id for device id: '%s'\n", hardware_id); - strcpy(device_id, hardware_id); - sanitize_device_id((char *)device_id); + snprintf(device_id, DEVID_MAX, "%s", hardware_id); + sanitize_device_id(device_id); mConstValues.insert(make_pair("device_id", device_id)); return; } strcpy(device_id, "serialno"); - LOGERR("=> device id not found, using '%s'.", device_id); + LOGERR("=> device id not found, using '%s'\n", device_id); mConstValues.insert(make_pair("device_id", device_id)); return; } diff --git a/htcdumlock/htcdumlock.c b/htcdumlock/htcdumlock.c index ec9469f8a..911961292 100644 --- a/htcdumlock/htcdumlock.c +++ b/htcdumlock/htcdumlock.c @@ -36,6 +36,8 @@ // Number of bytes in the ramdisks to compare #define SCAN_SIZE 60 +#define DEVID_MAX 64 + #define CMDLINE_SERIALNO "androidboot.serialno=" #define CMDLINE_SERIALNO_LEN (strlen(CMDLINE_SERIALNO)) #define CPUINFO_SERIALNO "Serial" @@ -43,98 +45,54 @@ #define CPUINFO_HARDWARE "Hardware" #define CPUINFO_HARDWARE_LEN (strlen(CPUINFO_HARDWARE)) -char device_id[255]; +char device_id[DEVID_MAX] = { 0 }; int verbose = 0, java = 0; +void sanitize_device_id(void) { + const char* whitelist ="-._"; + char str[DEVID_MAX]; + char* c = str; + + snprintf(str, DEVID_MAX, "%s", device_id); + memset(device_id, 0, strlen(device_id)); + while (*c) { + if (isalnum(*c) || strchr(whitelist, *c)) + strncat(device_id, c, 1); + c++; + } + return; +} + +/* Recent HTC devices that still take advantage of dumlock + can safely rely on cmdline device_id retrieval */ void get_device_id(void) { FILE *fp; - char line[2048]; - char hardware_id[32]; + char line[2048]; char* token; - // Assign a blank device_id to start with - device_id[0] = 0; - - // First, try the cmdline to see if the serial number was supplied + // Check the cmdline to see if the serial number was supplied fp = fopen("/proc/cmdline", "rt"); - if (fp != NULL) - { - // First step, read the line. For cmdline, it's one long line - fgets(line, sizeof(line), fp); - fclose(fp); - - // Now, let's tokenize the string - token = strtok(line, " "); - - // Let's walk through the line, looking for the CMDLINE_SERIALNO token - while (token) - { - // We don't need to verify the length of token, because if it's too short, it will mismatch CMDLINE_SERIALNO at the NULL - if (memcmp(token, CMDLINE_SERIALNO, CMDLINE_SERIALNO_LEN) == 0) - { - // We found the serial number! - strcpy(device_id, token + CMDLINE_SERIALNO_LEN); - return; - } - token = strtok(NULL, " "); - } - } - - // Now we'll try cpuinfo for a serial number - fp = fopen("/proc/cpuinfo", "rt"); - if (fp != NULL) - { - while (fgets(line, sizeof(line), fp) != NULL) { // First step, read the line. - if (memcmp(line, CPUINFO_SERIALNO, CPUINFO_SERIALNO_LEN) == 0) // check the beginning of the line for "Serial" - { - // We found the serial number! - token = line + CPUINFO_SERIALNO_LEN; // skip past "Serial" - while (((int)*token > 0 && (int)*token <= 32 ) || (int)*token == ':') token++; // skip over all spaces and the colon - if (*token != NULL) { - token[30] = 0; - if (token[strlen(token)-1] == 10) { // checking for endline chars and dropping them from the end of the string if needed - memset(device_id, 0, sizeof(device_id)); - strncpy(device_id, token, strlen(token) - 1); - } else { - strcpy(device_id, token); - } - if (verbose) - printf("serial from cpuinfo: '%s'\n", device_id); - fclose(fp); - return; - } - } else if (memcmp(line, CPUINFO_HARDWARE, CPUINFO_HARDWARE_LEN) == 0) {// We're also going to look for the hardware line in cpuinfo and save it for later in case we don't find the device ID - // We found the hardware ID - token = line + CPUINFO_HARDWARE_LEN; // skip past "Hardware" - while (((int)*token > 0 && (int)*token <= 32 ) || (int)*token == ':') token++; // skip over all spaces and the colon - if (*token != NULL) { - token[30] = 0; - if (token[strlen(token)-1] == 10) { // checking for endline chars and dropping them from the end of the string if needed - memset(hardware_id, 0, sizeof(hardware_id)); - strncpy(hardware_id, token, strlen(token) - 1); - } else { - strcpy(hardware_id, token); - } - if (verbose) - printf("hardware id from cpuinfo: '%s'\n", hardware_id); - } + if (fp != NULL) { + fgets(line, sizeof(line), fp); + fclose(fp); // cmdline is only one line long + + token = strtok(line, " "); + while (token) { + if (memcmp(token, CMDLINE_SERIALNO, CMDLINE_SERIALNO_LEN) == 0) { + token += CMDLINE_SERIALNO_LEN; + snprintf(device_id, DEVID_MAX, "%s", token); + sanitize_device_id(); // also removes newlines + return; } + token = strtok(NULL, " "); } - fclose(fp); - } - - if (hardware_id[0] != 0) { - if (verbose) - printf("using hardware id for device id: '%s'\n", hardware_id); - strcpy(device_id, hardware_id); - return; } - strcpy(device_id, "serialno"); + strcpy(device_id, "serialno"); if (verbose) printf("device id not found, using '%s'.", device_id); - return; + return; } void reboot_device() { @@ -386,8 +344,8 @@ int main(int argc, char** argv) get_device_id(); if (verbose) printf("Device ID is: '%s'\n", device_id); - if (strcmp(device_id, "0000000000000000") == 0) { - printf("Error, device ID is all zeros!\n"); + if (strcmp(device_id, "serialno") == 0) { + printf("Error, dummy device ID detected!\n"); printf("Did you 'su' first? HTC Dumlock requires root access.\nFailed\n"); return 0; } -- cgit v1.2.3