Skip to content

Commit

Permalink
lib-dcrypt: Avoid infinite loop if istream header is too large.
Browse files Browse the repository at this point in the history
We'll return an error now instead. We can't just return -2 here, because nothing
was actually being returned to the caller. Attempting to do that would just trigger
an assert:

Panic: file istream.c: line 182 (i_stream_read): assertion failed: (_stream->skip != _stream->pos)
  • Loading branch information
sirainen committed Sep 5, 2016
1 parent 9913ea5 commit 8a2f21f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/lib-dcrypt/istream-decrypt.c
Expand Up @@ -732,6 +732,12 @@ i_stream_decrypt_read(struct istream_private *stream)

if (hret == 0) {
/* see if we can get more data */
if (ret == -2) {
stream->istream.stream_errno = EINVAL;
io_stream_set_error(&stream->iostream,
"Header too large (more than %"PRIuSIZE_T" bytes)", size);
return -1;
}
continue;
} else {
/* clean up buffer */
Expand Down
17 changes: 17 additions & 0 deletions src/lib-dcrypt/test-stream.c
Expand Up @@ -497,6 +497,22 @@ static void test_read_0_to_400_byte_garbage(void)
test_end();
}

static void test_read_large_header(void)
{
test_begin("test_read_large_header");

struct istream *is = test_istream_create_data(IOSTREAM_CRYPT_MAGIC, sizeof(IOSTREAM_CRYPT_MAGIC));
struct istream *ds = i_stream_create_decrypt_callback(is, no_op_cb, NULL);
test_istream_set_allow_eof(is, FALSE);
test_istream_set_max_buffer_size(is, sizeof(IOSTREAM_CRYPT_MAGIC));

test_assert(i_stream_read(ds) == -1);
i_stream_unref(&ds);
i_stream_unref(&is);

test_end();
}

static
void test_free_keys() {
dcrypt_key_unref_private(&test_v1_kp.priv);
Expand Down Expand Up @@ -529,6 +545,7 @@ int main(void) {
test_write_read_v2_empty,
test_free_keys,
test_read_0_to_400_byte_garbage,
test_read_large_header,
NULL
};

Expand Down

0 comments on commit 8a2f21f

Please sign in to comment.