-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Many string command updates to help prevent buffer overflows. #72
Changes from all commits
24437a1
f2a1077
5c83e0b
e0beb80
d6656ad
787235a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -312,7 +312,7 @@ deal_with_a2s_packet(struct qserver *server, char *rawpkt, int pktlen) | |
server->max_players = (unsigned char)pkt[1]; | ||
|
||
// version | ||
sprintf(buf, "%hhu", pkt[2]); | ||
snprintf(buf, sizeof(buf), "%hhu", pkt[2]); | ||
add_rule(server, "version", buf, 0); | ||
|
||
// dedicated | ||
|
@@ -373,13 +373,13 @@ deal_with_a2s_packet(struct qserver *server, char *rawpkt, int pktlen) | |
} | ||
|
||
// mod version | ||
sprintf(buf, "%u", swap_long_from_little(pkt)); | ||
snprintf(buf, sizeof(buf), "%u", swap_long_from_little(pkt)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
add_rule(server, "mod_ver", buf, 0); | ||
pkt += 4; | ||
pktlen -= 4; | ||
|
||
// mod size | ||
sprintf(buf, "%u", swap_long_from_little(pkt)); | ||
snprintf(buf, sizeof(buf), "%u", swap_long_from_little(pkt)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
add_rule(server, "mod_size", buf, 0); | ||
pkt += 4; | ||
pktlen -= 4; | ||
|
@@ -405,7 +405,7 @@ deal_with_a2s_packet(struct qserver *server, char *rawpkt, int pktlen) | |
pktlen--; | ||
|
||
// Bots | ||
sprintf(buf, "%hhu", *pkt); | ||
snprintf(buf, sizeof(buf), "%hhu", *pkt); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
add_rule(server, "bots", buf, 0); | ||
pkt++; | ||
pktlen--; | ||
|
@@ -474,7 +474,7 @@ deal_with_a2s_packet(struct qserver *server, char *rawpkt, int pktlen) | |
server->num_players = (unsigned char)pkt[2]; | ||
server->max_players = (unsigned char)pkt[3]; | ||
// pkt[4] number of bots | ||
sprintf(buf, "%hhu", pkt[4]); | ||
snprintf(buf, sizeof(buf), "%hhu", pkt[4]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
add_rule(server, "bots", buf, 0); | ||
|
||
add_rule(server, "dedicated", pkt[5] ? "1" : "0", 0); | ||
|
@@ -524,7 +524,7 @@ deal_with_a2s_packet(struct qserver *server, char *rawpkt, int pktlen) | |
goto out_too_short; | ||
} | ||
gameport = swap_short_from_little(pkt); | ||
sprintf(buf, "%hu", gameport); | ||
snprintf(buf, sizeof(buf), "%hu", gameport); | ||
add_rule(server, "game_port", buf, 0); | ||
change_server_port(server, gameport, 0); | ||
pkt += 2; | ||
|
@@ -547,7 +547,7 @@ deal_with_a2s_packet(struct qserver *server, char *rawpkt, int pktlen) | |
goto out_too_short; | ||
} | ||
spectator_port = swap_short_from_little(pkt); | ||
sprintf(buf, "%hu", spectator_port); | ||
snprintf(buf, sizeof(buf), "%hu", spectator_port); | ||
add_rule(server, "spectator_port", buf, 0); | ||
pkt += 2; | ||
pktlen -= 2; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,7 +117,7 @@ static ConfigKey const new_keys[] = | |
{ CK_PLAYER_PACKET, "player packet" }, | ||
{ CK_RULE_PACKET, "rule packet" }, | ||
{ CK_PORT_OFFSET, "status port offset" }, | ||
{ 0, NULL }, | ||
{ 0, NULL }, | ||
}; | ||
|
||
static ConfigKey const modify_keys[] = | ||
|
@@ -127,7 +127,7 @@ static ConfigKey const modify_keys[] = | |
{ CK_MASTER_PACKET, "master packet" }, | ||
{ CK_FLAGS, "flags" }, | ||
{ CK_MASTER_TYPE, "master for gametype" }, | ||
{ 0, NULL }, | ||
{ 0, NULL }, | ||
}; | ||
|
||
typedef struct { | ||
|
@@ -153,7 +153,7 @@ ServerFlag const server_flags[] = | |
SERVER_FLAG(TF_RAW_STYLE_GHOSTRECON), | ||
SERVER_FLAG(TF_NO_PORT_OFFSET), | ||
SERVER_FLAG(TF_SHOW_GAME_PORT), | ||
{ NULL, 0 } | ||
{ NULL, 0} | ||
}; | ||
#undef SERVER_FLAG | ||
|
||
|
@@ -200,8 +200,8 @@ qsc_load_default_config_files() | |
} | ||
strncpy(path, var, len); | ||
path[len] = '\0'; | ||
strcat(path, "/"); | ||
strcat(path, HOME_CONFIG_FILE); | ||
strncat(path, "/", sizeof(path) - 1 - strlen(path)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this truncates the length and doesn't null terminate then it will break anyway, so I concerned this just adds needless and broken complexity. It should be noted there is actually no possible buffer overrun here as its protected against by the len check above. |
||
strncat(path, HOME_CONFIG_FILE, sizeof(path) - 1 - strlen(path)); | ||
/* sprintf( path, "%s/%s", var, HOME_CONFIG_FILE); */ | ||
rc = try_load_config_file(path, 0); | ||
if ((rc == 0) || (rc == -1)) { | ||
|
@@ -210,14 +210,16 @@ qsc_load_default_config_files() | |
} | ||
|
||
#ifdef sysconfdir | ||
strcpy(path, sysconfdir "/qstat.cfg"); | ||
strncpy(path, sysconfdir "/qstat.cfg", sizeof(path)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar to above, the better fix would be to use malloc'ed buffer here |
||
path[sizeof(path) -1] = '\0'; | ||
filename = path; | ||
#elif defined(_WIN32) | ||
if ((filename == NULL) && _pgmptr && strchr(_pgmptr, '\\')) { | ||
char *slash = strrchr(_pgmptr, '\\'); | ||
strncpy(path, _pgmptr, slash - _pgmptr); | ||
path[slash - _pgmptr] = '\0'; | ||
strcat(path, "\\qstat.cfg"); | ||
strncat(path, "\\qstat.cfg", sizeof(path) -1); | ||
path[sizeof(path) -1] = '\0'; | ||
filename = path; | ||
} | ||
#endif | ||
|
@@ -556,7 +558,8 @@ get_config_key(char *first_token, const ConfigKey *keys) | |
char key_name[1024], *token; | ||
int key = 0; | ||
|
||
strcpy(key_name, first_token); | ||
strncpy(key_name, first_token, sizeof(key_name)); | ||
key_name[sizeof(key_name) -1] = '\0'; | ||
do { | ||
int k; | ||
for (k = 0; keys[k].key_name; k++) { | ||
|
@@ -576,8 +579,8 @@ get_config_key(char *first_token, const ConfigKey *keys) | |
REPORT_ERROR((stderr, "Key name too long")); | ||
return (-1); | ||
} | ||
strcat(key_name, " "); | ||
strcat(key_name, token); | ||
strncat(key_name, " ", sizeof(key_name) - 1 - strlen(key_name)); | ||
strncat(key_name, token, sizeof(key_name) - 1 - strlen(key_name)); | ||
} while (1); | ||
|
||
if (key == 0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,15 +46,15 @@ send_crysis_request_packet(struct qserver *server) | |
case 0: | ||
// Not seen a challenge yet, request it | ||
server->challenge++; | ||
sprintf(cmd, "challenge"); | ||
snprintf(cmd, sizeof(cmd), "challenge"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
break; | ||
|
||
case 1: | ||
server->challenge++; | ||
password = get_param_value(server, "password", ""); | ||
sprintf(cmd, "%s:%s", server->challenge_string, password); | ||
snprintf(cmd, sizeof(cmd), "%s:%s", server->challenge_string, password); | ||
md5 = md5_hex(cmd, strlen(cmd)); | ||
sprintf(cmd, "authenticate %s", md5); | ||
snprintf(cmd, sizeof(cmd), "authenticate %s", md5); | ||
free(md5); | ||
break; | ||
|
||
|
@@ -63,15 +63,15 @@ send_crysis_request_packet(struct qserver *server) | |
server->challenge++; | ||
server->flags |= TF_STATUS_QUERY; | ||
server->n_servers = 3; | ||
sprintf(cmd, "status"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
snprintf(cmd, sizeof(cmd), "status"); | ||
break; | ||
|
||
case 3: | ||
return (DONE_FORCE); | ||
} | ||
|
||
server->saved_data.pkt_max = -1; | ||
sprintf(buf, "POST /RPC2 HTTP/1.1\015\012Keep-Alive: 300\015\012User-Agent: qstat %s\015\012Content-Length: %d\015\012Content-Type: text/xml\015\012\015\012<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>%s</methodName><params /></methodCall>", VERSION, (int)(98 + strlen(cmd)), cmd); | ||
snprintf(buf, sizeof(buf), "POST /RPC2 HTTP/1.1\015\012Keep-Alive: 300\015\012User-Agent: qstat %s\015\012Content-Length: %d\015\012Content-Type: text/xml\015\012\015\012<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>%s</methodName><params /></methodCall>", VERSION, (int)(98 + strlen(cmd)), cmd); | ||
|
||
return (send_packet(server, buf, strlen(buf))); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -114,7 +114,7 @@ malformed_packet(const struct qserver *server, const char *fmt, ...) | |
char fn[PATH_MAX] = { 0 }; | ||
int fd; | ||
|
||
sprintf(fn, "%03u_%s.pkt", count++, tag); | ||
snprintf(fn, sizeof(fn), "%03u_%s.pkt", count++, tag); | ||
fprintf(stderr, "dumping to %s\n", fn); | ||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0644); | ||
if (fd == -1) { | ||
|
@@ -171,7 +171,7 @@ output_packet(struct qserver *server, const char *buf, int buflen, int to) | |
for (i = buflen; i; offset += 16) { | ||
memset(line, ' ', 256); | ||
h = 0; | ||
h += sprintf(line, "%5d:", offset); | ||
h += snprintf(line, sizeof(line), "%5d:", offset); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
a = astart = h + 16 * 2 + 16 / 4 + 2; | ||
for (b = 16; b && i; b--, i--, p++) { | ||
if ((b & 3) == 0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -340,20 +340,20 @@ deal_with_fl_packet(struct qserver *server, char *rawpkt, int pktlen) | |
add_rule(server, "passworded", (*pkt++) ? "1" : "0", 0); | ||
|
||
// FrameTime | ||
sprintf(buf, "%hhu", *pkt++); | ||
snprintf(buf, sizeof(buf), "%hhu", *pkt++); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized same for all in this function. |
||
add_rule(server, "frametime", buf, 0); | ||
|
||
// Round | ||
sprintf(buf, "%hhu", *pkt++); | ||
snprintf(buf, sizeof(buf), "%hhu", *pkt++); | ||
add_rule(server, "round", buf, 0); | ||
|
||
// RoundMax | ||
sprintf(buf, "%hhu", *pkt++); | ||
snprintf(buf, sizeof(buf), "%hhu", *pkt++); | ||
add_rule(server, "roundmax", buf, 0); | ||
|
||
// RoundSeconds | ||
tmp_short = ((unsigned short)pkt[0] << 8) | ((unsigned short)pkt[1]); | ||
sprintf(buf, "%hu", tmp_short); | ||
snprintf(buf, sizeof(buf), "%hhu", tmp_short); | ||
add_rule(server, "roundseconds", buf, 0); | ||
pkt += 2; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -229,8 +229,8 @@ deal_with_gs3_status(struct qserver *server, char *rawpkt, int pktlen) | |
if (server->server_name) { | ||
char *name = (char *)realloc(server->server_name, strlen(server->server_name) + strlen(val) + 3); | ||
if (name) { | ||
strcat(name, ": "); | ||
strcat(name, val); | ||
strncat(name, ": ", sizeof(name) - 1 - strlen(name)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. buffer is correctly sized |
||
strncat(name, val, sizeof(name) - 1 - strlen(name)); | ||
server->server_name = name; | ||
} | ||
} | ||
|
@@ -381,8 +381,8 @@ process_gs3_packet(struct qserver *server) | |
if (server->server_name) { | ||
char *name = (char *)realloc(server->server_name, strlen(server->server_name) + strlen(val) + 3); | ||
if (name) { | ||
strcat(name, ": "); | ||
strcat(name, val); | ||
strncat(name, ": ", sizeof(name) - 1 - strlen(name)); | ||
strncat(name, val, sizeof(name) - 1 - strlen(name)); | ||
server->server_name = name; | ||
} | ||
} | ||
|
@@ -643,7 +643,7 @@ process_gs3_packet(struct qserver *server) | |
case TEAM_OTHER_HEADER: | ||
default: | ||
// add as a server rule | ||
sprintf(rule, "%s%d", header, total_teams); | ||
snprintf(rule, sizeof(rule), "%s%d", header, total_teams); | ||
add_rule(server, rule, val, NO_FLAGS); | ||
break; | ||
} | ||
|
@@ -675,8 +675,9 @@ send_gs3_request_packet(struct qserver *server) | |
server->flags |= TF_PLAYER_QUERY | TF_RULES_QUERY; | ||
if (server->challenge) { | ||
// we've recieved a challenge response, send the query + challenge id | ||
len = sprintf( | ||
len = snprintf( | ||
query_buf, | ||
sizeof(query_buf), | ||
"\xfe\xfd%c\x10\x20\x30\x40%c%c%c%c\xff\xff\xff\x01", | ||
0x00, | ||
(unsigned char)(server->challenge >> 24), | ||
|
@@ -694,8 +695,9 @@ send_gs3_request_packet(struct qserver *server) | |
server->flags |= TF_STATUS_QUERY; | ||
if (server->challenge) { | ||
// we've recieved a challenge response, send the query + challenge id | ||
len = sprintf( | ||
len = snprintf( | ||
query_buf, | ||
sizeof(query_buf), | ||
"\xfe\xfd%c\x10\x20\x30\x40%c%c%c%c\x06\x01\x06\x05\x08\x0a\x04%c%c", | ||
0x00, | ||
(unsigned char)(server->challenge >> 24), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buffer is correctly sized