Skip to content

Commit 34918f1

Browse files
rlubosnashif
authored andcommitted
net: mqtt: Improve PUBLISH message length validation
Identify when received PUBLISH message is malformed and overall packet length received is smaller than parsed variable header lenght. Add unit test to cover this case. Signed-off-by: Robert Lubos <[email protected]>
1 parent c450130 commit 34918f1

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

subsys/net/lib/mqtt/mqtt_decoder.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,13 @@ int publish_decode(u8_t flags, u32_t var_length, struct buf_ctx *buf,
256256
var_header_length += sizeof(u16_t);
257257
}
258258

259+
if (var_length < var_header_length) {
260+
MQTT_ERR("Corrupted PUBLISH message, header length (%u) larger "
261+
"than total length (%u)", var_header_length,
262+
var_length);
263+
return -EINVAL;
264+
}
265+
259266
param->message.payload.data = NULL;
260267
param->message.payload.len = var_length - var_header_length;
261268

tests/net/lib/mqtt_packet/src/mqtt_packet.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ static int eval_msg_connect(struct mqtt_test *mqtt_test);
109109
*/
110110
static int eval_msg_publish(struct mqtt_test *mqtt_test);
111111

112+
/**
113+
* @brief eval_msg_corrupted_publish Evaluate the given mqtt_test against the
114+
* corrupted publish message.
115+
* @param [in] mqtt_test MQTT test structure
116+
* @return TC_PASS on success
117+
* @return TC_FAIL on error
118+
*/
119+
static int eval_msg_corrupted_publish(struct mqtt_test *mqtt_test);
120+
112121
/**
113122
* @brief eval_msg_subscribe Evaluate the given mqtt_test against the
114123
* subscribe packing/unpacking routines.
@@ -452,6 +461,14 @@ static ZTEST_DMEM struct mqtt_publish_param msg_publish4 = {
452461
.message.payload.len = 2,
453462
};
454463

464+
static ZTEST_DMEM
465+
u8_t publish_corrupted[] = {0x30, 0x07, 0x00, 0x07, 0x73, 0x65, 0x6e, 0x73,
466+
0x6f, 0x72, 0x73, 0x00, 0x01, 0x4f, 0x4b};
467+
static ZTEST_DMEM struct buf_ctx publish_corrupted_buf = {
468+
.cur = publish_corrupted,
469+
.end = publish_corrupted + sizeof(publish_corrupted)
470+
};
471+
455472
/*
456473
* MQTT SUBSCRIBE msg:
457474
* pkt_id: 1, topic: sensors, qos: 0
@@ -622,6 +639,9 @@ struct mqtt_test mqtt_tests[] = {
622639
.ctx = &msg_publish4, .eval_fcn = eval_msg_publish,
623640
.expected = publish4, .expected_len = sizeof(publish4)},
624641

642+
{.test_name = "PUBLISH, corrupted message length (smaller than topic)",
643+
.ctx = &publish_corrupted_buf, .eval_fcn = eval_msg_corrupted_publish},
644+
625645
{.test_name = "SUBSCRIBE, one topic, qos = 0",
626646
.ctx = &msg_subscribe1, .eval_fcn = eval_msg_subscribe,
627647
.expected = subscribe1, .expected_len = sizeof(subscribe1)},
@@ -829,6 +849,23 @@ static int eval_msg_publish(struct mqtt_test *mqtt_test)
829849
return TC_PASS;
830850
}
831851

852+
static int eval_msg_corrupted_publish(struct mqtt_test *mqtt_test)
853+
{
854+
struct buf_ctx *buf = (struct buf_ctx *)mqtt_test->ctx;
855+
int rc;
856+
u8_t type_and_flags;
857+
u32_t length;
858+
struct mqtt_publish_param dec_param;
859+
860+
rc = fixed_header_decode(buf, &type_and_flags, &length);
861+
zassert_equal(rc, 0, "fixed_header_decode failed");
862+
863+
rc = publish_decode(type_and_flags, length, buf, &dec_param);
864+
zassert_equal(rc, -EINVAL, "publish_decode should fail");
865+
866+
return TC_PASS;
867+
}
868+
832869
static int eval_msg_subscribe(struct mqtt_test *mqtt_test)
833870
{
834871
struct mqtt_subscription_list *param =

0 commit comments

Comments
 (0)