Skip to content

Commit

Permalink
lib-dcrypt: Fixed accessing out-of-bounds data in istream.
Browse files Browse the repository at this point in the history
Also some small cleanups to make it clearer what's actually happening.
  • Loading branch information
sirainen committed Aug 17, 2016
1 parent b99357f commit a84b413
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
22 changes: 12 additions & 10 deletions src/lib-dcrypt/istream-decrypt.c
Expand Up @@ -54,13 +54,13 @@ ssize_t i_stream_decrypt_read_header_v1(struct decrypt_istream *stream,
const unsigned char *data, size_t mlen)
{
const char *error = NULL;
size_t hdr_len = 0;
size_t keydata_len = 0;
uint16_t len;
int ec, i = 0;

const unsigned char *digest_pos = NULL, *key_digest_pos = NULL, *key_ct_pos = NULL;

size_t pos = 9;
size_t pos = sizeof(IOSTREAM_CRYPT_MAGIC);
size_t digest_len = 0;
size_t key_ct_len = 0;
size_t key_digest_size = 0;
Expand All @@ -69,22 +69,25 @@ ssize_t i_stream_decrypt_read_header_v1(struct decrypt_istream *stream,
buffer_t *secret = buffer_create_dynamic(pool_datastack_create(), 256);
buffer_t *key = buffer_create_dynamic(pool_datastack_create(), 256);

hdr_len = ((data[0] << 8) | data[1]) + 12;

if (mlen < hdr_len - pos) {
if (mlen < 2)
return 0;
keydata_len = (data[0] << 8) | data[1];
if (mlen-2 < keydata_len) {
/* try to read more */
return 0;
}

data+=2;
mlen-=2;

memcpy(&len, data, 2);

while(i < 4 && mlen > 2 && (len = ntohs(len)) <= (mlen - 2) && len > 0) {
while (i < 4 && mlen > 2) {
memcpy(&len, data, 2);
len = ntohs(len);
data += 2;
mlen -= 2;
pos += 2;
if (len == 0 || len > mlen)
break;

switch(i++) {
case 0:
Expand All @@ -109,7 +112,6 @@ ssize_t i_stream_decrypt_read_header_v1(struct decrypt_istream *stream,
pos += len;
data += len;
mlen -= len;
memcpy(&len, data, 2);
}

if (i < 4) {
Expand Down Expand Up @@ -227,7 +229,7 @@ ssize_t i_stream_decrypt_read_header_v1(struct decrypt_istream *stream,
stream->initialized = TRUE;
/* now we are ready to decrypt stream */

return hdr_len;
return sizeof(IOSTREAM_CRYPT_MAGIC) + 1 + 2 + keydata_len;
}

static bool get_msb32(const unsigned char **_data, const unsigned char *end, uint32_t *num_r)
Expand Down
2 changes: 1 addition & 1 deletion src/lib-dcrypt/ostream-encrypt.c
Expand Up @@ -84,7 +84,7 @@ int o_stream_encrypt_send_header_v1(struct encrypt_ostream *stream)
/* version */
c = 1;
buffer_append(values, &c, 1);
/* header length including this and data written so far */
/* key data length */
s = htons(stream->key_data_len);
buffer_append(values, &s, 2);
/* then write key data */
Expand Down

0 comments on commit a84b413

Please sign in to comment.