mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2025-12-13 23:16:48 +03:00
Fix segfault in parse_quic_decrypted
This commit is contained in:
52
src/quic.c
52
src/quic.c
@@ -109,11 +109,11 @@ int quic_parse_data(const uint8_t *raw_payload, uint32_t raw_payload_len,
|
|||||||
int64_t qversion = quic_get_version(nqch);
|
int64_t qversion = quic_get_version(nqch);
|
||||||
|
|
||||||
if (qversion < 0) {
|
if (qversion < 0) {
|
||||||
lgtrace_addp("quic version undefined %ld", -qversion);
|
lgtrace_addp("quic version undefined %u", (uint32_t)(-qversion));
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
lgtrace_addp("quic version valid %ld", qversion);
|
lgtrace_addp("quic version valid %u", (uint32_t)qversion);
|
||||||
|
|
||||||
if (left_len < 2) goto invalid_packet;
|
if (left_len < 2) goto invalid_packet;
|
||||||
struct quic_cids nqci = {0};
|
struct quic_cids nqci = {0};
|
||||||
@@ -336,9 +336,10 @@ int gen_fake_udp(struct udp_fake_type type,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tls_verdict parse_quic_decrypted(
|
int parse_quic_decrypted(
|
||||||
const struct section_config_t *section,
|
const struct section_config_t *section,
|
||||||
const uint8_t *decrypted_message, uint32_t decrypted_message_len
|
const uint8_t *decrypted_message, uint32_t decrypted_message_len,
|
||||||
|
uint8_t **crypto_message_buf, uint32_t *crypto_message_buf_len
|
||||||
) {
|
) {
|
||||||
const uint8_t *curptr = decrypted_message;
|
const uint8_t *curptr = decrypted_message;
|
||||||
ssize_t curptr_len = decrypted_message_len;
|
ssize_t curptr_len = decrypted_message_len;
|
||||||
@@ -350,7 +351,7 @@ struct tls_verdict parse_quic_decrypted(
|
|||||||
uint8_t *crypto_message = calloc(AVAILABLE_MTU, 1);
|
uint8_t *crypto_message = calloc(AVAILABLE_MTU, 1);
|
||||||
if (crypto_message == NULL) {
|
if (crypto_message == NULL) {
|
||||||
lgerror(-ENOMEM, "No memory");
|
lgerror(-ENOMEM, "No memory");
|
||||||
return tlsv;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypto_message_len = AVAILABLE_MTU;
|
int crypto_message_len = AVAILABLE_MTU;
|
||||||
@@ -371,7 +372,7 @@ pl_incr:
|
|||||||
break;
|
break;
|
||||||
case QUIC_FRAME_CRYPTO:
|
case QUIC_FRAME_CRYPTO:
|
||||||
fret = quic_parse_crypto(&fr_cr, curptr, curptr_len);
|
fret = quic_parse_crypto(&fr_cr, curptr, curptr_len);
|
||||||
lgtrace_addp("crypto %lu", fr_cr.offset);
|
lgtrace_addp("crypto %d %d %d", (int)fr_cr.offset, (int)fr_cr.payload_length, (int)fret);
|
||||||
if (fret < 0)
|
if (fret < 0)
|
||||||
break;
|
break;
|
||||||
curptr += fret;
|
curptr += fret;
|
||||||
@@ -391,16 +392,10 @@ pl_incr:
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (section->sni_detection == SNI_DETECTION_BRUTE) {
|
*crypto_message_buf = crypto_message;
|
||||||
ret = bruteforce_analyze_sni_str(section, crypto_message, crypto_message_len, &tlsv);
|
*crypto_message_buf_len = crypto_message_len;
|
||||||
} else {
|
|
||||||
ret = analyze_tls_message(
|
|
||||||
section, crypto_message, crypto_message_len, &tlsv
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(crypto_message);
|
return 0;
|
||||||
return tlsv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int detect_udp_filtered(const struct section_config_t *section,
|
int detect_udp_filtered(const struct section_config_t *section,
|
||||||
@@ -461,6 +456,8 @@ int detect_udp_filtered(const struct section_config_t *section,
|
|||||||
uint32_t decrypted_payload_len;
|
uint32_t decrypted_payload_len;
|
||||||
const uint8_t *decrypted_message;
|
const uint8_t *decrypted_message;
|
||||||
uint32_t decrypted_message_len;
|
uint32_t decrypted_message_len;
|
||||||
|
uint8_t *crypto_message;
|
||||||
|
uint32_t crypto_message_len;
|
||||||
struct tls_verdict tlsv;
|
struct tls_verdict tlsv;
|
||||||
|
|
||||||
ret = quic_parse_initial_message(
|
ret = quic_parse_initial_message(
|
||||||
@@ -473,9 +470,24 @@ int detect_udp_filtered(const struct section_config_t *section,
|
|||||||
goto match_port;
|
goto match_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsv = parse_quic_decrypted(section,
|
ret = parse_quic_decrypted(section,
|
||||||
decrypted_message, decrypted_message_len
|
decrypted_message, decrypted_message_len,
|
||||||
|
&crypto_message, &crypto_message_len
|
||||||
);
|
);
|
||||||
|
free(decrypted_payload);
|
||||||
|
decrypted_payload = NULL;
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
goto match_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section->sni_detection == SNI_DETECTION_BRUTE) {
|
||||||
|
ret = bruteforce_analyze_sni_str(section, crypto_message, crypto_message_len, &tlsv);
|
||||||
|
} else {
|
||||||
|
ret = analyze_tls_message(
|
||||||
|
section, crypto_message, crypto_message_len, &tlsv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (tlsv.sni_len != 0) {
|
if (tlsv.sni_len != 0) {
|
||||||
lgtrace_addp("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
|
lgtrace_addp("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
|
||||||
@@ -483,11 +495,13 @@ int detect_udp_filtered(const struct section_config_t *section,
|
|||||||
|
|
||||||
if (tlsv.target_sni) {
|
if (tlsv.target_sni) {
|
||||||
lgdebugmsg("QUIC target SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
|
lgdebugmsg("QUIC target SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
|
||||||
free(decrypted_payload);
|
free(crypto_message);
|
||||||
|
crypto_message = NULL;
|
||||||
goto approve;
|
goto approve;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(decrypted_payload);
|
free(crypto_message);
|
||||||
|
crypto_message = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
match_port:
|
match_port:
|
||||||
|
|||||||
@@ -221,11 +221,14 @@ int quic_parse_initial_message(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like analyze_tls_data for QUIC
|
* CRYPTO frames may be randomly spried in the message.
|
||||||
|
* This function _allocates_ crypto_message_buf and fills it with CRYPTO frames
|
||||||
|
* according to offset and payload_length
|
||||||
*/
|
*/
|
||||||
struct tls_verdict parse_quic_decrypted(
|
int parse_quic_decrypted(
|
||||||
const struct section_config_t *section,
|
const struct section_config_t *section,
|
||||||
const uint8_t *decrypted_message, uint32_t decrypted_message_len
|
const uint8_t *decrypted_message, uint32_t decrypted_message_len,
|
||||||
|
uint8_t **crypto_message_buf, uint32_t *crypto_message_buf_len
|
||||||
);
|
);
|
||||||
|
|
||||||
// Like fail_packet for TCP
|
// Like fail_packet for TCP
|
||||||
|
|||||||
42
test/quic.c
42
test/quic.c
@@ -141,11 +141,15 @@ TEST(QuicTest, Test_varlength_parser)
|
|||||||
|
|
||||||
TEST(QuicTest, Test_parse_quic_decrypted)
|
TEST(QuicTest, Test_parse_quic_decrypted)
|
||||||
{
|
{
|
||||||
|
#undef free
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t *decrypted_payload;
|
uint8_t *decrypted_payload;
|
||||||
uint32_t decrypted_payload_len;
|
uint32_t decrypted_payload_len;
|
||||||
const uint8_t *decrypted_message;
|
const uint8_t *decrypted_message;
|
||||||
uint32_t decrypted_message_len;
|
uint32_t decrypted_message_len;
|
||||||
|
uint8_t *crypto_message;
|
||||||
|
uint32_t crypto_message_len;
|
||||||
struct tls_verdict tlsv = {0};
|
struct tls_verdict tlsv = {0};
|
||||||
|
|
||||||
ret = quic_parse_initial_message(
|
ret = quic_parse_initial_message(
|
||||||
@@ -153,22 +157,35 @@ TEST(QuicTest, Test_parse_quic_decrypted)
|
|||||||
&decrypted_payload, &decrypted_payload_len,
|
&decrypted_payload, &decrypted_payload_len,
|
||||||
&decrypted_message, &decrypted_message_len
|
&decrypted_message, &decrypted_message_len
|
||||||
);
|
);
|
||||||
TEST_ASSERT_EQUAL(ret, 0);
|
TEST_ASSERT_EQUAL(0, ret);
|
||||||
|
|
||||||
tlsv = parse_quic_decrypted(&sconf, decrypted_message, decrypted_message_len);
|
ret = parse_quic_decrypted(
|
||||||
TEST_ASSERT_EQUAL_STRING_LEN("example.com", tlsv.sni_ptr, 11);
|
&sconf, decrypted_message, decrypted_message_len,
|
||||||
#undef free
|
&crypto_message, &crypto_message_len);
|
||||||
|
TEST_ASSERT_EQUAL(0, ret);
|
||||||
free(decrypted_payload);
|
free(decrypted_payload);
|
||||||
|
decrypted_payload = NULL;
|
||||||
|
|
||||||
|
ret = analyze_tls_message(
|
||||||
|
&sconf, crypto_message, crypto_message_len, &tlsv
|
||||||
|
);
|
||||||
|
TEST_ASSERT_EQUAL_STRING_LEN("example.com", tlsv.sni_ptr, 11);
|
||||||
|
free(crypto_message);
|
||||||
|
|
||||||
#define free unity_free
|
#define free unity_free
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(QuicTest, Test_parse_quic_decrypted_on_sparse)
|
TEST(QuicTest, Test_parse_quic_decrypted_on_sparse)
|
||||||
{
|
{
|
||||||
|
#undef free
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t *decrypted_payload;
|
uint8_t *decrypted_payload;
|
||||||
uint32_t decrypted_payload_len;
|
uint32_t decrypted_payload_len;
|
||||||
const uint8_t *decrypted_message;
|
const uint8_t *decrypted_message;
|
||||||
uint32_t decrypted_message_len;
|
uint32_t decrypted_message_len;
|
||||||
|
uint8_t *crypto_message;
|
||||||
|
uint32_t crypto_message_len;
|
||||||
struct tls_verdict tlsv = {0};
|
struct tls_verdict tlsv = {0};
|
||||||
|
|
||||||
ret = quic_parse_initial_message(
|
ret = quic_parse_initial_message(
|
||||||
@@ -176,13 +193,22 @@ TEST(QuicTest, Test_parse_quic_decrypted_on_sparse)
|
|||||||
&decrypted_payload, &decrypted_payload_len,
|
&decrypted_payload, &decrypted_payload_len,
|
||||||
&decrypted_message, &decrypted_message_len
|
&decrypted_message, &decrypted_message_len
|
||||||
);
|
);
|
||||||
TEST_ASSERT_EQUAL(ret, 0);
|
TEST_ASSERT_EQUAL(0, ret);
|
||||||
|
|
||||||
tlsv = parse_quic_decrypted(&sconf, decrypted_message, decrypted_message_len);
|
ret = parse_quic_decrypted(
|
||||||
|
&sconf, decrypted_message, decrypted_message_len,
|
||||||
|
&crypto_message, &crypto_message_len);
|
||||||
|
TEST_ASSERT_EQUAL(0, ret);
|
||||||
|
free(decrypted_payload);
|
||||||
|
decrypted_payload = NULL;
|
||||||
|
|
||||||
|
ret = analyze_tls_message(
|
||||||
|
&sconf, crypto_message, crypto_message_len, &tlsv
|
||||||
|
);
|
||||||
TEST_ASSERT_EQUAL(19, tlsv.sni_len);
|
TEST_ASSERT_EQUAL(19, tlsv.sni_len);
|
||||||
TEST_ASSERT_EQUAL_STRING_LEN("ipm.adblockplus.dev", tlsv.sni_ptr, 19);
|
TEST_ASSERT_EQUAL_STRING_LEN("ipm.adblockplus.dev", tlsv.sni_ptr, 19);
|
||||||
#undef free
|
free(crypto_message);
|
||||||
free(decrypted_payload);
|
|
||||||
#define free unity_free
|
#define free unity_free
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user