Commit 187a09ac authored by Ian Goldberg's avatar Ian Goldberg

Guard against a potential integer overflow in future code paths

* b64.c (otrl_base64_otr_encode): In case some future code path
tries to call otrl_base64_otr_encode with a buffer more than
3/4 the size of all addressable memory, return NULL rather than
causing an integer overflow and a heap overrun.  Thanks to
David Remahl <david@remahl.se> for the report.

* proto.c (otrl_proto_create_data): Tiny refactor to call
otrl_base64_otr_encode instead of duplicating the code here.

Fixes #64
parent c9710e9b
2014-11-11
* b64.c (otrl_base64_otr_encode): In case some future code path
tries to call otrl_base64_otr_encode with a buffer more than
3/4 the size of all addressable memory, return NULL rather than
causing an integer overflow and a heap overrun. Thanks to
David Remahl <david@remahl.se> for the report.
* proto.c (otrl_proto_create_data): Tiny refactor to call
otrl_base64_otr_encode instead of duplicating the code here.
2014-10-18
* README:
......
......@@ -197,6 +197,16 @@ char *otrl_base64_otr_encode(const unsigned char *buf, size_t buflen)
{
char *base64buf;
size_t base64len;
const size_t HALF_MAX_SIZE_T = ((size_t)-1) >> 1;
if (buflen > HALF_MAX_SIZE_T) {
/* You somehow have a buffer that's of size more than half of
* all addressable memory, and you now want a base64 version in
* a new buffer 33% larger? Not going to happen. Exit now,
* rather in the malloc below, to avoid integer overflowing the
* computation of base64len. */
return NULL;
}
/* Make the base64-encoding. */
base64len = ((buflen + 2) / 3) * 4;
......
......@@ -490,7 +490,6 @@ gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
DH_sesskeys *sess = &(context->context_priv->sesskeys[1][0]);
gcry_error_t err;
size_t reveallen = 20 * context->context_priv->numsavedkeys;
size_t base64len;
char *base64buf = NULL;
unsigned char *msgbuf = NULL;
enum gcry_mpi_format format = GCRYMPI_FMT_USG;
......@@ -605,16 +604,11 @@ gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
assert(lenp == 0);
/* Make the base64-encoding. */
base64len = ((buflen + 2) / 3) * 4;
base64buf = malloc(5 + base64len + 1 + 1);
base64buf = otrl_base64_otr_encode(buf, buflen);
if (base64buf == NULL) {
err = gcry_error(GPG_ERR_ENOMEM);
goto err;
}
memmove(base64buf, "?OTR:", 5);
otrl_base64_encode(base64buf+5, buf, buflen);
base64buf[5 + base64len] = '.';
base64buf[5 + base64len + 1] = '\0';
free(buf);
gcry_free(msgbuf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment