From a4b6de139abf93e8cf7bbbadcaac9c80da7417b4 Mon Sep 17 00:00:00 2001 From: Iwan Timmer Date: Tue, 19 Dec 2017 19:37:59 +0100 Subject: [PATCH] Use PATH_MAX and memory safe string operations in libgamestream --- libgamestream/client.c | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/libgamestream/client.c b/libgamestream/client.c index e19936a..6fe0c0b 100644 --- a/libgamestream/client.c +++ b/libgamestream/client.c @@ -22,6 +22,7 @@ #include "mkcert.h" #include "client.h" #include "errors.h" +#include "limits.h" #include @@ -58,12 +59,13 @@ static EVP_PKEY *privateKey; const char* gs_error; static int mkdirtree(const char* directory) { - char buffer[1024]; + char buffer[PATH_MAX]; char* p = buffer; // The passed in string could be a string literal // so we must copy it first - strcpy(p, directory); + strncpy(p, directory, PATH_MAX - 1); + buffer[PATH_MAX - 1] = '\0'; while (*p != 0) { // Find the end of the path element @@ -86,8 +88,8 @@ static int mkdirtree(const char* directory) { } static int load_unique_id(const char* keyDirectory) { - char uniqueFilePath[4096]; - sprintf(uniqueFilePath, "%s/%s", keyDirectory, UNIQUE_FILE_NAME); + char uniqueFilePath[PATH_MAX]; + snprintf(uniqueFilePath, PATH_MAX, "%s/%s", keyDirectory, UNIQUE_FILE_NAME); FILE *fd = fopen(uniqueFilePath, "r"); if (fd == NULL) { @@ -111,11 +113,11 @@ static int load_unique_id(const char* keyDirectory) { } static int load_cert(const char* keyDirectory) { - char certificateFilePath[4096]; - sprintf(certificateFilePath, "%s/%s", keyDirectory, CERTIFICATE_FILE_NAME); + char certificateFilePath[PATH_MAX]; + snprintf(certificateFilePath, PATH_MAX, "%s/%s", keyDirectory, CERTIFICATE_FILE_NAME); - char keyFilePath[4096]; - sprintf(&keyFilePath[0], "%s/%s", keyDirectory, KEY_FILE_NAME); + char keyFilePath[PATH_MAX]; + snprintf(&keyFilePath[0], PATH_MAX, "%s/%s", keyDirectory, KEY_FILE_NAME); FILE *fd = fopen(certificateFilePath, "r"); if (fd == NULL) { @@ -123,8 +125,8 @@ static int load_cert(const char* keyDirectory) { CERT_KEY_PAIR cert = mkcert_generate(); printf("done\n"); - char p12FilePath[4096]; - sprintf(p12FilePath, "%s/%s", keyDirectory, P12_FILE_NAME); + char p12FilePath[PATH_MAX]; + snprintf(p12FilePath, PATH_MAX, "%s/%s", keyDirectory, P12_FILE_NAME); mkcert_save(certificateFilePath, p12FilePath, keyFilePath, cert); mkcert_free(cert); @@ -190,7 +192,7 @@ static int load_server_status(PSERVER_DATA server) { // is not already paired. Since we can't pair without knowing the server version, we // make another request over HTTP if the HTTPS request fails. We can't just use HTTP // for everything because it doesn't accurately tell us if we're paired. - sprintf(url, "%s://%s:%d/serverinfo?uniqueid=%s&uuid=%s", + snprintf(url, sizeof(url), "%s://%s:%d/serverinfo?uniqueid=%s&uuid=%s", i == 0 ? "https" : "http", server->serverInfo.address, i == 0 ? 47984 : 47989, unique_id, uuid_str); PHTTP_DATA data = http_create_data(); @@ -375,7 +377,7 @@ int gs_unpair(PSERVER_DATA server) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "http://%s:47989/unpair?uniqueid=%s&uuid=%s", server->serverInfo.address, unique_id, uuid_str); + snprintf(url, sizeof(url), "http://%s:47989/unpair?uniqueid=%s&uuid=%s", server->serverInfo.address, unique_id, uuid_str); ret = http_request(url, data); http_free_data(data); @@ -406,7 +408,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->serverInfo.address, unique_id, uuid_str, salt_hex, cert_hex); + snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->serverInfo.address, unique_id, uuid_str, salt_hex, cert_hex); PHTTP_DATA data = http_create_data(); if (data == NULL) return GS_OUT_OF_MEMORY; @@ -465,7 +467,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientchallenge=%s", server->serverInfo.address, unique_id, uuid_str, challenge_hex); + snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientchallenge=%s", server->serverInfo.address, unique_id, uuid_str, challenge_hex); if ((ret = http_request(url, data)) != GS_OK) goto cleanup; @@ -524,7 +526,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", server->serverInfo.address, unique_id, uuid_str, challenge_response_hex); + snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", server->serverInfo.address, unique_id, uuid_str, challenge_response_hex); if ((ret = http_request(url, data)) != GS_OK) goto cleanup; @@ -575,7 +577,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", server->serverInfo.address, unique_id, uuid_str, client_pairing_secret_hex); + snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", server->serverInfo.address, unique_id, uuid_str, client_pairing_secret_hex); if ((ret = http_request(url, data)) != GS_OK) goto cleanup; @@ -594,7 +596,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "https://%s:47984/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=pairchallenge", server->serverInfo.address, unique_id, uuid_str); + snprintf(url, sizeof(url), "https://%s:47984/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=pairchallenge", server->serverInfo.address, unique_id, uuid_str); if ((ret = http_request(url, data)) != GS_OK) goto cleanup; @@ -636,7 +638,7 @@ int gs_applist(PSERVER_DATA server, PAPP_LIST *list) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "https://%s:47984/applist?uniqueid=%s&uuid=%s", server->serverInfo.address, unique_id, uuid_str); + snprintf(url, sizeof(url), "https://%s:47984/applist?uniqueid=%s&uuid=%s", server->serverInfo.address, unique_id, uuid_str); if (http_request(url, data) != GS_OK) ret = GS_IO_ERROR; else if (xml_status(data->memory, data->size) == GS_ERROR) @@ -687,9 +689,9 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b if (server->currentGame == 0) { int channelCounnt = config->audioConfiguration == AUDIO_CONFIGURATION_STEREO ? CHANNEL_COUNT_STEREO : CHANNEL_COUNT_51_SURROUND; int mask = config->audioConfiguration == AUDIO_CONFIGURATION_STEREO ? CHANNEL_MASK_STEREO : CHANNEL_MASK_51_SURROUND; - sprintf(url, "https://%s:47984/launch?uniqueid=%s&uuid=%s&appid=%d&mode=%dx%dx%d&additionalStates=1&sops=%d&rikey=%s&rikeyid=%d&localAudioPlayMode=%d&surroundAudioInfo=%d", server->serverInfo.address, unique_id, uuid_str, appId, config->width, config->height, config->fps, sops, rikey_hex, rikeyid, localaudio, (mask << 16) + channelCounnt); + snprintf(url, sizeof(url), "https://%s:47984/launch?uniqueid=%s&uuid=%s&appid=%d&mode=%dx%dx%d&additionalStates=1&sops=%d&rikey=%s&rikeyid=%d&localAudioPlayMode=%d&surroundAudioInfo=%d", server->serverInfo.address, unique_id, uuid_str, appId, config->width, config->height, config->fps, sops, rikey_hex, rikeyid, localaudio, (mask << 16) + channelCounnt); } else - sprintf(url, "https://%s:47984/resume?uniqueid=%s&uuid=%s&rikey=%s&rikeyid=%d", server->serverInfo.address, unique_id, uuid_str, rikey_hex, rikeyid); + snprintf(url, sizeof(url), "https://%s:47984/resume?uniqueid=%s&uuid=%s&rikey=%s&rikeyid=%d", server->serverInfo.address, unique_id, uuid_str, rikey_hex, rikeyid); if ((ret = http_request(url, data)) == GS_OK) server->currentGame = appId; @@ -726,7 +728,7 @@ int gs_quit_app(PSERVER_DATA server) { uuid_generate_random(uuid); uuid_unparse(uuid, uuid_str); - sprintf(url, "https://%s:47984/cancel?uniqueid=%s&uuid=%s", server->serverInfo.address, unique_id, uuid_str); + snprintf(url, sizeof(url), "https://%s:47984/cancel?uniqueid=%s&uuid=%s", server->serverInfo.address, unique_id, uuid_str); if ((ret = http_request(url, data)) != GS_OK) goto cleanup;