Skip to content

Commit c5be23e

Browse files
committed
Revew comment: intercept invalid packet, do not latch TID before
verification
1 parent d148606 commit c5be23e

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

src/test/unit/unit_tests_tftp.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,42 @@ START_TEST(test_tftp_client_unexpected_opcode_rejected)
16211621
}
16221622
END_TEST
16231623

1624+
START_TEST(test_tftp_client_invalid_first_data_does_not_lock_tid)
1625+
{
1626+
struct tftp_test_ctx ctx;
1627+
struct wolftftp_client client;
1628+
struct wolftftp_transfer_cfg cfg = tftp_cfg_defaults();
1629+
struct wolftftp_transport_ops transport;
1630+
struct wolftftp_io_ops io;
1631+
struct wolftftp_endpoint srv = tftp_remote(0x0A000080U, 0);
1632+
struct wolftftp_endpoint attacker = tftp_remote(srv.ip, 4321);
1633+
struct wolftftp_endpoint tid = tftp_remote(srv.ip, 5678);
1634+
uint8_t pkt[WOLFTFTP_PKT_MAX];
1635+
int len;
1636+
1637+
tftp_test_ctx_reset(&ctx);
1638+
transport = tftp_transport_ops(&ctx);
1639+
io = tftp_io_ops(&ctx);
1640+
wolftftp_client_init(&client, &transport, &io, &cfg);
1641+
ck_assert_int_eq(wolftftp_client_start_rrq(&client, &srv, "fw.bin"), 0);
1642+
1643+
/* A malformed first DATA must be rejected without latching its TID. */
1644+
memset(pkt, 0, sizeof(pkt));
1645+
wolftftp_write_u16(pkt, WOLFTFTP_OP_DATA);
1646+
ck_assert_int_eq(wolftftp_client_receive(&client, cfg.local_port,
1647+
&attacker, pkt, 3), WOLFTFTP_ERR_PACKET);
1648+
ck_assert_uint_eq(client.tid_locked, 0U);
1649+
ck_assert_uint_eq(client.server.port, WOLFTFTP_PORT);
1650+
1651+
memcpy(pkt + 4, "0123456789abcdef", 16);
1652+
len = wolftftp_build_data(pkt, sizeof(pkt), 1, pkt + 4, 16);
1653+
ck_assert_int_eq(wolftftp_client_receive(&client, cfg.local_port,
1654+
&tid, pkt, (uint16_t)len), 0);
1655+
ck_assert_uint_eq(client.tid_locked, 1U);
1656+
ck_assert_uint_eq(client.server.port, tid.port);
1657+
}
1658+
END_TEST
1659+
16241660
START_TEST(test_tftp_client_max_image_size_enforced_on_data)
16251661
{
16261662
/* OACK didn't trip the tsize check (no tsize); enforcement
@@ -2035,6 +2071,7 @@ static void add_tftp_tests(TCase *tc_proto)
20352071
tcase_add_test(tc_proto, test_tftp_send_failure_propagation);
20362072
tcase_add_test(tc_proto, test_tftp_parse_option_ranges);
20372073
tcase_add_test(tc_proto, test_tftp_client_unexpected_opcode_rejected);
2074+
tcase_add_test(tc_proto, test_tftp_client_invalid_first_data_does_not_lock_tid);
20382075
tcase_add_test(tc_proto, test_tftp_client_max_image_size_enforced_on_data);
20392076
tcase_add_test(tc_proto, test_tftp_client_duplicate_block_replays_last_ack);
20402077
tcase_add_test(tc_proto, test_tftp_client_open_sink_missing_callbacks);

src/tftp/wolftftp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,10 @@ int wolftftp_client_receive(struct wolftftp_client *client, uint16_t local_port,
741741
if (opcode != WOLFTFTP_OP_DATA)
742742
return WOLFTFTP_ERR_PACKET;
743743

744+
ret = wolftftp_parse_data(buf, len, &data);
745+
if (ret != 0)
746+
return ret;
747+
744748
if (client->tid_locked == 0U) {
745749
client->server.port = remote->port;
746750
client->tid_locked = 1;
@@ -754,9 +758,6 @@ int wolftftp_client_receive(struct wolftftp_client *client, uint16_t local_port,
754758
client->advertised_size = 0;
755759
client->state = WOLFTFTP_CLIENT_RECV_DATA;
756760
}
757-
ret = wolftftp_parse_data(buf, len, &data);
758-
if (ret != 0)
759-
return ret;
760761
client->deadline_ms = 0;
761762
client->retries = 0;
762763
return wolftftp_client_accept_data(client, &data);

0 commit comments

Comments
 (0)