mirror of
https://github.com/libssh2/libssh2.git
synced 2026-10-24 03:48:58 +03:00
agent: fix bounds checks, and potential OOB access on 32-bit platforms in agent_sign()
Also limit payload to `UINT32_MAX`, since the protocol uses 32-bit value to store the size. (I'd guess a lower, sane limit may be even better.) Reported-by: afldl on github Fixes #2021 Closes #2046
This commit is contained in:
44
src/agent.c
44
src/agent.c
@@ -745,13 +745,19 @@ static int agent_sign(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *)(*abstract);
|
||||
struct agent_transaction_ctx *transctx = &agent->transctx;
|
||||
struct agent_publickey *identity = agent->identity;
|
||||
ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4;
|
||||
ssize_t method_len;
|
||||
size_t len, method_len, plain_len;
|
||||
unsigned char *s;
|
||||
int rc;
|
||||
unsigned char *method_name = NULL;
|
||||
uint32_t sign_flags = 0;
|
||||
ssize_t plain_len;
|
||||
|
||||
len = 1 + 4 + 4 + 4; /* fixed parts */
|
||||
if(identity->external.blob_len > UINT32_MAX - len ||
|
||||
data_len > UINT32_MAX - len - identity->external.blob_len) {
|
||||
return ssh2_err(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
|
||||
"Agent sign request too large");
|
||||
}
|
||||
len += identity->external.blob_len + data_len;
|
||||
|
||||
/* Create a request to sign the data */
|
||||
if(transctx->state == agent_NB_state_init) {
|
||||
@@ -790,8 +796,8 @@ static int agent_sign(LIBSSH2_SESSION *session,
|
||||
if(*transctx->request != SSH2_AGENTC_SIGN_REQUEST)
|
||||
return ssh2_err(session, LIBSSH2_ERROR_BAD_USE, "illegal request");
|
||||
|
||||
/* if no agent has been connected, bail out */
|
||||
if(!agent->ops)
|
||||
/* if no agent has been connected, bail out */
|
||||
return ssh2_err(session, LIBSSH2_ERROR_BAD_USE, "agent not connected");
|
||||
|
||||
rc = agent->ops->transact(agent, transctx);
|
||||
@@ -803,8 +809,7 @@ static int agent_sign(LIBSSH2_SESSION *session,
|
||||
|
||||
len = transctx->response_len;
|
||||
s = transctx->response;
|
||||
len--;
|
||||
if(len < 0) {
|
||||
if(len < 1) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
@@ -812,26 +817,29 @@ static int agent_sign(LIBSSH2_SESSION *session,
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
len--;
|
||||
s++;
|
||||
|
||||
/* Skip the entire length of the signature */
|
||||
len -= 4;
|
||||
if(len < 0) {
|
||||
if(len < 4) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
len -= 4;
|
||||
s += 4;
|
||||
|
||||
/* Skip signing method */
|
||||
len -= 4;
|
||||
if(len < 0) {
|
||||
if(len < 4) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* method length */
|
||||
method_len = ssh2_ntohu32(s);
|
||||
len -= 4;
|
||||
s += 4;
|
||||
len -= method_len;
|
||||
if(len < 0) {
|
||||
|
||||
if(len < method_len) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
@@ -843,13 +851,14 @@ static int agent_sign(LIBSSH2_SESSION *session,
|
||||
goto error;
|
||||
}
|
||||
memcpy(method_name, s, method_len);
|
||||
len -= method_len;
|
||||
s += method_len;
|
||||
|
||||
plain_len = plain_method((char *)session->userauth_pblc_method,
|
||||
session->userauth_pblc_method_len);
|
||||
|
||||
/* check to see if we match requested */
|
||||
if(((size_t)method_len != session->userauth_pblc_method_len &&
|
||||
if((method_len != session->userauth_pblc_method_len &&
|
||||
method_len != plain_len) ||
|
||||
memcmp(method_name, session->userauth_pblc_method, method_len)) {
|
||||
ssh2_deb((session, LIBSSH2_TRACE_KEX, "Agent sign method %.*s",
|
||||
@@ -860,15 +869,16 @@ static int agent_sign(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
/* Read the signature */
|
||||
len -= 4;
|
||||
if(len < 0) {
|
||||
if(len < 4) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
*sig_len = ssh2_ntohu32(s);
|
||||
len -= 4;
|
||||
s += 4;
|
||||
len -= *sig_len;
|
||||
if(len < 0) {
|
||||
|
||||
if(len < *sig_len) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user