Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions apps/wolfssh/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,18 @@ int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx)
pubKeyType[0] = 0;
fp[0] = 0;

/* Get the key type out of the key. */
ato32(pubKey, &sz);
if ((sz > pubKeySz - sizeof(word32))
|| (sz > WOLFSSH_CLIENT_PUBKEYTYPE_SIZE_ESTIMATE - 1)) {
/* Get the key type out of the key. Require at least a word32
* length prefix to avoid an unsigned underflow below. */
if (pubKeySz < (word32)sizeof(word32)) {
ret = -1;
}
else {
ato32(pubKey, &sz);
if ((sz > pubKeySz - sizeof(word32))
|| (sz > WOLFSSH_CLIENT_PUBKEYTYPE_SIZE_ESTIMATE - 1)) {
ret = -1;
}
}
}

if (ret == 0) {
Expand Down
5 changes: 3 additions & 2 deletions src/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,8 @@ static WOLFSSH_AGENT_ID* FindKeyId(WOLFSSH_AGENT_ID* id,
if (ret == WS_SUCCESS) {
while (id != NULL &&
WMEMCMP(digest, id->id, WC_SHA256_DIGEST_SIZE) != 0 &&
WMEMCMP(keyBlob, id->keyBlob, keyBlobSz)) {
(keyBlobSz != id->keyBlobSz ||
WMEMCMP(keyBlob, id->keyBlob, keyBlobSz) != 0)) {
id = id->next;
}
}
Expand Down Expand Up @@ -1386,7 +1387,7 @@ static int DoMessage(WOLFSSH_AGENT_CTX* agent,
ato32(buf + begin, &payloadSz);
WLOG(WS_LOG_AGENT, "payloadSz = %u", payloadSz);
begin += LENGTH_SZ;
if (payloadSz > len - begin) {
if (payloadSz == 0 || payloadSz > len - begin) {
ret = WS_OVERFLOW_E;
}
}
Expand Down
29 changes: 25 additions & 4 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -3509,6 +3509,12 @@ WOLFSSH_CHANNEL* ChannelNew(WOLFSSH* ssh, byte channelType,
WMEMSET(newChannel, 0, sizeof(WOLFSSH_CHANNEL));
newChannel->ssh = ssh;
newChannel->channelType = channelType;
/* Skip channel ids already in use to avoid collisions when
* nextChannel (word32) wraps around. */
while (ChannelFind(ssh, ssh->nextChannel,
WS_CHANNEL_ID_SELF) != NULL) {
ssh->nextChannel++;
}
newChannel->channel = ssh->nextChannel++;
WLOG(WS_LOG_DEBUG, "New channel id = %u", newChannel->channel);
newChannel->windowSz = initialWindowSz;
Expand Down Expand Up @@ -4415,7 +4421,7 @@ static int GetNameList(byte* idList, word32* idListSz,
*/

if (ret == WS_SUCCESS) {
if (*idx >= len || *idx + 4 >= len)
if (*idx >= len || *idx + 4 > len)
ret = WS_BUFFER_E;
}

Expand Down Expand Up @@ -7023,7 +7029,8 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
if (ret == WS_SUCCESS) {
/* Check that scratch isn't larger than the remainder of the
* sig buffer and leaves enough room for another length. */
if (scratch > sigSz - begin - LENGTH_SZ) {
if (begin + LENGTH_SZ > sigSz ||
scratch > sigSz - begin - LENGTH_SZ) {
WLOG(WS_LOG_DEBUG, "sig name size is too large");
ret = WS_PARSE_E;
}
Expand Down Expand Up @@ -12362,6 +12369,10 @@ static int BuildNameList(char* buf, word32 bufSz,

idx = 0;

if (srcSz == 0) {
return 0;
}
Comment on lines +12372 to +12374

do {
name = IdToName(*src);
nameSz = (int)WSTRLEN(name);
Expand Down Expand Up @@ -18773,7 +18784,12 @@ int SendChannelData(WOLFSSH* ssh, word32 channelId,
word32 bound = min(channel->peerWindowSz, channel->peerMaxPacketSz);
bound = min(bound, channel->maxPacketSz);

if (dataSz > bound) {
if (bound == 0 && dataSz != 0) {
WLOG(WS_LOG_DEBUG, "peer max packet size is zero");
ssh->error = WS_WINDOW_FULL;
ret = WS_WINDOW_FULL;
}
else if (dataSz > bound) {
WLOG(WS_LOG_DEBUG,
"Trying to send %u, client will only accept %u, limiting",
dataSz, bound);
Expand Down Expand Up @@ -18886,7 +18902,12 @@ int SendChannelExtendedData(WOLFSSH* ssh, word32 channelId,
word32 bound = min(channel->peerWindowSz, channel->peerMaxPacketSz);
bound = min(bound, channel->maxPacketSz);

if (dataSz > bound) {
if (bound == 0 && dataSz != 0) {
WLOG(WS_LOG_DEBUG, "peer max packet size is zero");
ssh->error = WS_WINDOW_FULL;
ret = WS_WINDOW_FULL;
}
else if (dataSz > bound) {
WLOG(WS_LOG_DEBUG,
"Trying to send %u, client will only accept %u, limiting",
dataSz, bound);
Expand Down
3 changes: 2 additions & 1 deletion src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -3835,7 +3835,8 @@ int wolfSSH_RealPath(const char* defaultPath, char* in,
}
/* Everything else is copied */
else {
if (curSz >= outSz - segSz) {
if (segSz == 0 || segSz >= outSz ||
curSz >= outSz - segSz - (curSz != 1 ? 1 : 0)) {
return WS_INVALID_PATH_E;
}

Expand Down
8 changes: 8 additions & 0 deletions src/wolfsftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -6634,6 +6634,14 @@ static int wolfSSH_SFTP_DoStatus(WOLFSSH* ssh, word32 reqId,
return WS_FATAL_ERROR;
}

/* status is a small enumerated value (0..WOLFSSH_FTP_UNSUPPORTED). An
* out-of-range value from a malicious or broken server must not be
* returned as a negative int, where it would alias an internal WS_*
* error code and bypass the WOLFSSH_FTP_* classification in callers. */
if (status > (word32)WOLFSSH_FTP_UNSUPPORTED) {
status = WOLFSSH_FTP_FAILURE;
}

/* read error message */
if (GetStringRef(&sz, &str, buf, maxIdx, &localIdx) != WS_SUCCESS) {
return WS_FATAL_ERROR;
Expand Down
Loading