From 3d0b4ab20c4d1c0dd376319fe533886f55558647 Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Fri, 6 Dec 2024 17:45:53 +0100 Subject: [PATCH] http: http_decap_udp_payload_datagram fix Properly handle incomplete capsule. Type: fix Change-Id: Ied7fca861f02e401451beaff09e612bcf471d8e0 Signed-off-by: Matus Fabian --- extras/hs-test/http_test.go | 2 +- src/plugins/http/http.h | 11 +++++++++++ src/plugins/http/test/http_test.c | 23 ++++++++++++++++++++--- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/extras/hs-test/http_test.go b/extras/hs-test/http_test.go index cdc52a1f76c..8127fdca0e7 100644 --- a/extras/hs-test/http_test.go +++ b/extras/hs-test/http_test.go @@ -516,7 +516,7 @@ func HttpUnitTest(s *NoTopoSuite) { vpp := s.GetContainerByName("vpp").VppInstance o := vpp.Vppctl("test http all") s.Log(o) - s.AssertNotContains(o, "FAIL") + s.AssertContains(o, "SUCCESS") } func HttpStaticPromTest(s *NoTopoSuite) { diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h index 844235cbdbb..f54b4a040a2 100644 --- a/src/plugins/http/http.h +++ b/src/plugins/http/http.h @@ -1340,6 +1340,12 @@ _http_parse_capsule (u8 *data, u64 len, u64 *type, u8 *value_offset, return -1; } + if (p == end) + { + clib_warning ("capsule length missing"); + return -1; + } + capsule_value_len = _http_decode_varint (&p, end); if (capsule_value_len == HTTP_INVALID_VARINT) { @@ -1389,6 +1395,11 @@ http_decap_udp_payload_datagram (u8 *data, u64 len, u8 *payload_offset, } p += value_offset; + if (p == end) + { + clib_warning ("context ID missing"); + return -1; + } /* context ID field should be zero (RFC9298 section 4) */ context_id = _http_decode_varint (&p, end); diff --git a/src/plugins/http/test/http_test.c b/src/plugins/http/test/http_test.c index a96d5f9d9f7..40fd4463b61 100644 --- a/src/plugins/http/test/http_test.c +++ b/src/plugins/http/test/http_test.c @@ -333,11 +333,26 @@ http_test_udp_payload_datagram (vlib_main_t *vm) HTTP_TEST ((payload_offset == 4), "payload_offset=%u should be 4", payload_offset); + /* Type = 0x00, Len = incomplete */ u8 invalid_input[] = { 0x00, 0x7B }; rv = http_decap_udp_payload_datagram (invalid_input, sizeof (invalid_input), &payload_offset, &payload_len); - HTTP_TEST ((rv == -1), "'%U' should be invalid", format_hex_bytes, - invalid_input, sizeof (invalid_input)); + HTTP_TEST ((rv == -1), "'%U' should be invalid (length incomplete)", + format_hex_bytes, invalid_input, sizeof (invalid_input)); + + /* Type = 0x00, Len = missing */ + u8 invalid_input2[] = { 0x00 }; + rv = http_decap_udp_payload_datagram ( + invalid_input2, sizeof (invalid_input2), &payload_offset, &payload_len); + HTTP_TEST ((rv == -1), "'%U' should be invalid (length missing)", + format_hex_bytes, invalid_input2, sizeof (invalid_input2)); + + /* Type = 0x00, Len = 15293, Context ID = missing */ + u8 invalid_input3[] = { 0x00, 0x7B, 0xBD }; + rv = http_decap_udp_payload_datagram ( + invalid_input3, sizeof (invalid_input3), &payload_offset, &payload_len); + HTTP_TEST ((rv == -1), "'%U' should be invalid (context id missing)", + format_hex_bytes, invalid_input3, sizeof (invalid_input3)); /* Type = 0x00, Len = 494878333, Context ID = 0x00 */ u8 long_payload_input[] = { 0x00, 0x9D, 0x7F, 0x3E, 0x7D, 0x00, 0x12 }; @@ -408,7 +423,9 @@ test_http_command_fn (vlib_main_t *vm, unformat_input_t *input, done: if (res) - return clib_error_return (0, "HTTP unit test failed"); + return clib_error_return (0, "FAILED"); + + vlib_cli_output (vm, "SUCCESS"); return 0; }