Skip to content

Commit

Permalink
Merge pull request #504 from h2o/kazuho/report-tls-block-overflow
Browse files Browse the repository at this point in the history
detect and report TLS buffer overflows
  • Loading branch information
kazuho authored Jan 9, 2024
2 parents df13092 + 6031b2e commit b64735c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/picotls.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ extern "C" {
#define PTLS_ERROR_REJECT_EARLY_DATA (PTLS_ERROR_CLASS_INTERNAL + 9)
#define PTLS_ERROR_DELEGATE (PTLS_ERROR_CLASS_INTERNAL + 10)
#define PTLS_ERROR_ASYNC_OPERATION (PTLS_ERROR_CLASS_INTERNAL + 11)
#define PTLS_ERROR_BLOCK_OVERFLOW (PTLS_ERROR_CLASS_INTERNAL + 12)

#define PTLS_ERROR_INCORRECT_BASE64 (PTLS_ERROR_CLASS_INTERNAL + 50)
#define PTLS_ERROR_PEM_LABEL_NOT_FOUND (PTLS_ERROR_CLASS_INTERNAL + 51)
Expand Down Expand Up @@ -1203,6 +1204,10 @@ static uint8_t *ptls_encode_quicint(uint8_t *p, uint64_t v);
} while (0); \
size_t body_size = (buf)->off - body_start; \
if (capacity != -1) { \
if (capacity < sizeof(size_t) && body_size >= (size_t)1 << (capacity * 8)) { \
ret = PTLS_ERROR_BLOCK_OVERFLOW; \
goto Exit; \
} \
for (; capacity != 0; --capacity) \
(buf)->base[body_start - capacity] = (uint8_t)(body_size >> (8 * (capacity - 1))); \
} else { \
Expand Down
56 changes: 56 additions & 0 deletions t/picotls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,60 @@ static void test_all_handshakes(void)
ctx->sign_certificate = second_sc_orig;
}

static void do_test_tlsblock(size_t len_encoded, size_t max_bytes)
{
ptls_buffer_t buf;
const uint8_t *src, *end;
int expect_overflow = 0, ret;

/* block that fits in */
ptls_buffer_init(&buf, "", 0);
ptls_buffer_push_block(&buf, len_encoded, {
for (size_t i = 0; i < max_bytes; ++i)
ptls_buffer_push(&buf, (uint8_t)i);
});
src = buf.base;
end = buf.base + buf.off;
ptls_decode_block(src, end, len_encoded, {
ok(end - src == max_bytes);
int bytes_eq = 1;
for (size_t i = 0; i < max_bytes; ++i) {
if (src[i] != (uint8_t)i)
bytes_eq = 0;
}
ok(bytes_eq);
src = end;
});

/* block that does not fit in */
ptls_buffer_push_block(&buf, len_encoded, {
for (size_t i = 0; i < max_bytes + 1; i++)
ptls_buffer_push(&buf, 1);
expect_overflow = 1;
});
ok(!"fail");

Exit:
if (ret != 0) {
if (expect_overflow) {
ok(ret == PTLS_ERROR_BLOCK_OVERFLOW);
} else {
ok(!"fail");
}
}
ptls_buffer_dispose(&buf);
}

static void test_tlsblock8(void)
{
do_test_tlsblock(1, 255);
}

static void test_tlsblock16(void)
{
do_test_tlsblock(2, 65535);
}

static void test_quicint(void)
{
#define CHECK_PATTERN(output, ...) \
Expand Down Expand Up @@ -2161,6 +2215,8 @@ void test_picotls(void)
subtest("chacha20", test_chacha20);
subtest("ffx", test_ffx);
subtest("base64-decode", test_base64_decode);
subtest("tls-block8", test_tlsblock8);
subtest("tls-block16", test_tlsblock16);
subtest("ech", test_ech);
subtest("fragmented-message", test_fragmented_message);
subtest("handshake", test_all_handshakes);
Expand Down

0 comments on commit b64735c

Please sign in to comment.