Avoid buffer overflows due to sha256_hash's nul-terminator.

This commit is contained in:
Gregor Richards 2018-11-23 08:24:54 -05:00
parent 2a67be3a7c
commit f897b95d09

View File

@ -274,6 +274,7 @@ static void handshake_password(void *ignore, const char *line)
{ {
struct password_buf_s password_buf; struct password_buf_s password_buf;
char password[8+NETPLAY_PASS_LEN]; /* 8 for salt, 128 for password */ char password[8+NETPLAY_PASS_LEN]; /* 8 for salt, 128 for password */
char hash[NETPLAY_PASS_HASH_LEN+1]; /* + NULL terminator */
netplay_t *netplay = handshake_password_netplay; netplay_t *netplay = handshake_password_netplay;
struct netplay_connection *connection = &netplay->connections[0]; struct netplay_connection *connection = &netplay->connections[0];
@ -282,7 +283,8 @@ static void handshake_password(void *ignore, const char *line)
password_buf.cmd[0] = htonl(NETPLAY_CMD_PASSWORD); password_buf.cmd[0] = htonl(NETPLAY_CMD_PASSWORD);
password_buf.cmd[1] = htonl(sizeof(password_buf.password)); password_buf.cmd[1] = htonl(sizeof(password_buf.password));
sha256_hash(password_buf.password, (uint8_t *) password, strlen(password)); sha256_hash(hash, (uint8_t *) password, strlen(password));
memcpy(password_buf.password, hash, NETPLAY_PASS_HASH_LEN);
/* We have no way to handle an error here, so we'll let the next function error out */ /* We have no way to handle an error here, so we'll let the next function error out */
if (netplay_send(&connection->send_packet_buffer, connection->fd, &password_buf, sizeof(password_buf))) if (netplay_send(&connection->send_packet_buffer, connection->fd, &password_buf, sizeof(password_buf)))
@ -750,8 +752,9 @@ bool netplay_handshake_pre_nick(netplay_t *netplay,
bool netplay_handshake_pre_password(netplay_t *netplay, bool netplay_handshake_pre_password(netplay_t *netplay,
struct netplay_connection *connection, bool *had_input) struct netplay_connection *connection, bool *had_input)
{ {
struct password_buf_s password_buf, corr_password_buf; struct password_buf_s password_buf;
char password[8+NETPLAY_PASS_LEN]; /* 8 for salt */ char password[8+NETPLAY_PASS_LEN]; /* 8 for salt */
char hash[NETPLAY_PASS_HASH_LEN+1]; /* + NULL terminator */
ssize_t recvd; ssize_t recvd;
char msg[512]; char msg[512];
bool correct = false; bool correct = false;
@ -787,11 +790,9 @@ bool netplay_handshake_pre_password(netplay_t *netplay,
strlcpy(password + 8, strlcpy(password + 8,
settings->paths.netplay_password, sizeof(password)-8); settings->paths.netplay_password, sizeof(password)-8);
sha256_hash(corr_password_buf.password, sha256_hash(hash, (uint8_t *) password, strlen(password));
(uint8_t *) password, strlen(password));
if (!memcmp(password_buf.password, if (!memcmp(password_buf.password, hash, NETPLAY_PASS_HASH_LEN))
corr_password_buf.password, sizeof(password_buf.password)))
{ {
correct = true; correct = true;
connection->can_play = true; connection->can_play = true;
@ -802,11 +803,9 @@ bool netplay_handshake_pre_password(netplay_t *netplay,
strlcpy(password + 8, strlcpy(password + 8,
settings->paths.netplay_spectate_password, sizeof(password)-8); settings->paths.netplay_spectate_password, sizeof(password)-8);
sha256_hash(corr_password_buf.password, sha256_hash(hash, (uint8_t *) password, strlen(password));
(uint8_t *) password, strlen(password));
if (!memcmp(password_buf.password, if (!memcmp(password_buf.password, hash, NETPLAY_PASS_HASH_LEN))
corr_password_buf.password, sizeof(password_buf.password)))
correct = true; correct = true;
} }