Skip to content

Commit fe7209a

Browse files
committed
Phase 1: Fix sysmodule buffer overflows, apply auth to GET routes, async threads
1 parent 27f8e44 commit fe7209a

File tree

1 file changed

+33
-36
lines changed

1 file changed

+33
-36
lines changed

switch_sysmodule/main.cpp

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
#include <switch/services/pm.h>
2020
#include <switch/services/hiddbg.h>
2121
#include <fcntl.h>
22-
22+
#include <thread>
23+
#include <string>
2324
extern "C" {
2425
u32 __check_mask_save;
2526

@@ -66,6 +67,22 @@ void handle_client(int client_sock) {
6667
return;
6768
}
6869

70+
const char* api_token = ConfigManager::getInstance().getApiToken();
71+
char token_header[128];
72+
snprintf(token_header, sizeof(token_header), "X-API-Token: %s", api_token);
73+
74+
if (!strstr(buffer, token_header)) {
75+
ConfigManager::getInstance().load();
76+
api_token = ConfigManager::getInstance().getApiToken();
77+
snprintf(token_header, sizeof(token_header), "X-API-Token: %s", api_token);
78+
if (!strstr(buffer, token_header)) {
79+
const char *resp = "HTTP/1.1 401 Unauthorized\r\nContent-Type: application/json\r\n\r\n{\"error\": \"Unauthorized\"}";
80+
write(client_sock, resp, strlen(resp));
81+
close(client_sock);
82+
return;
83+
}
84+
}
85+
6986
if (strstr(buffer, "GET /info")) {
7087
char response[2048];
7188
u32 hos_version = 0;
@@ -152,8 +169,7 @@ void handle_client(int client_sock) {
152169
}
153170

154171
if (strstr(buffer, "GET /titles")) {
155-
char* json_out = (char*)malloc(16384);
156-
strcpy(json_out, "[");
172+
std::string json_out = "[";
157173
s32 total_records = 0;
158174
nsListApplicationRecord(NULL, 0, 0, &total_records);
159175
if (total_records > 0) {
@@ -169,12 +185,12 @@ void handle_client(int client_sock) {
169185
char title_name[0x201] = {0};
170186
NacpLanguageEntry* langentry = NULL;
171187
if (R_SUCCEEDED(nacpGetLanguageEntry(&controlData->nacp, &langentry)) && langentry) {
172-
snprintf(title_name, sizeof(title_name), "%s", langentry->name);
173-
}
174-
if (!first) strcat(json_out, ",");
188+
snprintf(title_name, sizeof(title_name), "%s", langentry->name);
189+
}
190+
if (!first) json_out += ",";
175191
char entry[1024];
176192
snprintf(entry, sizeof(entry), "{\"title_id\": \"0x%016lX\", \"name\": \"%s\"}", (unsigned long)records[i].application_id, title_name);
177-
strcat(json_out, entry);
193+
json_out += entry;
178194
first = false;
179195
}
180196
free(controlData);
@@ -183,55 +199,36 @@ void handle_client(int client_sock) {
183199
}
184200
if (records) free(records);
185201
}
186-
strcat(json_out, "]");
202+
json_out += "]";
187203
char resp_head[256];
188-
snprintf(resp_head, sizeof(resp_head), "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n", strlen(json_out));
204+
snprintf(resp_head, sizeof(resp_head), "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n", json_out.length());
189205
write(client_sock, resp_head, strlen(resp_head));
190-
write(client_sock, json_out, strlen(json_out));
191-
free(json_out);
206+
write(client_sock, json_out.c_str(), json_out.length());
192207
close(client_sock);
193208
return;
194209
}
195210

196211
if (strstr(buffer, "GET /logs")) {
197212
u32 count = Logger::getInstance().getLogCount();
198-
char* json_out = (char*)malloc(16384);
199-
strcpy(json_out, "[");
213+
std::string json_out = "[";
200214
for (u32 i = 0; i < count; i++) {
201-
if (i > 0) strcat(json_out, ",");
215+
if (i > 0) json_out += ",";
202216
const LogEntry* log = Logger::getInstance().getLog(i);
203217
char entry[1024];
204218
const char* level_str = (log->level == LOG_LEVEL_INFO) ? "INFO" : (log->level == LOG_LEVEL_WARN) ? "WARN" : "ERROR";
205219
snprintf(entry, sizeof(entry), "{\"level\": \"%s\", \"message\": \"%s\", \"timestamp\": \"%s\"}",
206220
level_str, log->message, log->timestamp);
207-
strcat(json_out, entry);
221+
json_out += entry;
208222
}
209-
strcat(json_out, "]");
223+
json_out += "]";
210224
char resp_head[256];
211-
snprintf(resp_head, sizeof(resp_head), "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n", strlen(json_out));
225+
snprintf(resp_head, sizeof(resp_head), "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n", json_out.length());
212226
write(client_sock, resp_head, strlen(resp_head));
213-
write(client_sock, json_out, strlen(json_out));
214-
free(json_out);
227+
write(client_sock, json_out.c_str(), json_out.length());
215228
close(client_sock);
216229
return;
217230
}
218231

219-
const char* api_token = ConfigManager::getInstance().getApiToken();
220-
char token_header[128];
221-
snprintf(token_header, sizeof(token_header), "X-API-Token: %s", api_token);
222-
223-
if (!strstr(buffer, token_header)) {
224-
ConfigManager::getInstance().load();
225-
api_token = ConfigManager::getInstance().getApiToken();
226-
snprintf(token_header, sizeof(token_header), "X-API-Token: %s", api_token);
227-
if (!strstr(buffer, token_header)) {
228-
const char *resp = "HTTP/1.1 401 Unauthorized\r\nContent-Type: application/json\r\n\r\n{\"error\": \"Unauthorized\"}";
229-
write(client_sock, resp, strlen(resp));
230-
close(client_sock);
231-
return;
232-
}
233-
}
234-
235232
if (strstr(buffer, "POST /reboot")) {
236233
LOG_I("System reboot requested");
237234
const char *resp = "HTTP/1.1 200 OK\r\n\r\n{\"status\": \"ok\"}";
@@ -419,7 +416,7 @@ int main(int argc, char **argv) {
419416
}
420417

421418
if ((client_sock = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) >= 0) {
422-
handle_client(client_sock);
419+
std::thread(handle_client, client_sock).detach();
423420
}
424421
svcSleepThread(10000000ULL); // 10ms sleep
425422
}

0 commit comments

Comments
 (0)