diff options
Diffstat (limited to 'test/dm')
| -rw-r--r-- | test/dm/Makefile | 1 | ||||
| -rw-r--r-- | test/dm/hash.c | 157 | ||||
| -rw-r--r-- | test/dm/net_defrag.c | 36 |
3 files changed, 194 insertions, 0 deletions
diff --git a/test/dm/Makefile b/test/dm/Makefile index 76aa1fff9ba..fb3e6a7008f 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_DMA) += dma.o obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o obj-$(CONFIG_DM_DSA) += dsa.o obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o +obj-$(CONFIG_DM_HASH) += hash.o obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_EXTCON) += extcon.o diff --git a/test/dm/hash.c b/test/dm/hash.c new file mode 100644 index 00000000000..6adf916dc77 --- /dev/null +++ b/test/dm/hash.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for driver-model hash-provider selection + * + * Copyright (C) 2026 James Hilliard + */ + +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/root.h> +#include <dm/test.h> +#include <dm/uclass-internal.h> +#include <u-boot/hash.h> +#include <test/test.h> +#include <test/ut.h> + +static int unsupported_calls; +static int success_calls; +static int hard_error_calls; + +static int hash_test_unsupported(struct udevice *dev, enum HASH_ALGO algo, + const void *ibuf, const uint32_t ilen, + void *obuf, uint32_t chunk_sz) +{ + unsupported_calls++; + + return -EOPNOTSUPP; +} + +static int hash_test_success(struct udevice *dev, enum HASH_ALGO algo, + const void *ibuf, const uint32_t ilen, + void *obuf, uint32_t chunk_sz) +{ + ssize_t digest_size; + + success_calls++; + digest_size = hash_algo_digest_size(algo); + if (digest_size < 0) + return digest_size; + + memset(obuf, 0x5a, digest_size); + + return 0; +} + +static int hash_test_hard_error(struct udevice *dev, enum HASH_ALGO algo, + const void *ibuf, const uint32_t ilen, + void *obuf, uint32_t chunk_sz) +{ + hard_error_calls++; + + return -EINVAL; +} + +static const struct hash_ops hash_test_unsupported_ops = { + .hash_digest_wd = hash_test_unsupported, +}; + +static const struct hash_ops hash_test_success_ops = { + .hash_digest_wd = hash_test_success, +}; + +static const struct hash_ops hash_test_hard_error_ops = { + .hash_digest_wd = hash_test_hard_error, +}; + +U_BOOT_DRIVER(hash_test_unsupported_drv) = { + .name = "hash_test_unsupported", + .id = UCLASS_HASH, + .ops = &hash_test_unsupported_ops, +}; + +U_BOOT_DRIVER(hash_test_success_drv) = { + .name = "hash_test_success", + .id = UCLASS_HASH, + .ops = &hash_test_success_ops, +}; + +U_BOOT_DRIVER(hash_test_hard_error_drv) = { + .name = "hash_test_hard_error", + .id = UCLASS_HASH, + .ops = &hash_test_hard_error_ops, +}; + +static int hash_test_unbind_all(void) +{ + struct udevice *dev; + int ret; + + for (;;) { + ret = uclass_find_first_device(UCLASS_HASH, &dev); + if (ret || !dev) + return ret; + if (device_active(dev)) { + ret = device_remove(dev, DM_REMOVE_NORMAL); + if (ret) + return ret; + } + ret = device_unbind(dev); + if (ret) + return ret; + } +} + +static int hash_test_bind(const struct driver *drv, const char *name) +{ + struct udevice *dev; + + return device_bind(dm_root(), drv, name, 0, ofnode_null(), &dev); +} + +static int dm_test_hash_provider_selection(struct unit_test_state *uts) +{ + u8 digest[32]; + int ret; + + ut_assertok(hash_test_unbind_all()); + ut_assertok(hash_test_bind(DM_DRIVER_GET(hash_test_unsupported_drv), + "hash-unsupported")); + ut_assertok(hash_test_bind(DM_DRIVER_GET(hash_test_success_drv), + "hash-success")); + + unsupported_calls = 0; + success_calls = 0; + memset(digest, 0, sizeof(digest)); + ret = hash_digest_wd_lookup(HASH_ALGO_SHA256, "test", 4, digest, 4); + ut_assertok(ret); + ut_asserteq(1, unsupported_calls); + ut_asserteq(1, success_calls); + for (int i = 0; i < sizeof(digest); i++) + ut_asserteq(0x5a, digest[i]); + + memset(digest, 0, sizeof(digest)); + ret = hash_digest_wd_lookup(HASH_ALGO_INVALID, "test", 4, digest, 4); + ut_asserteq(-EINVAL, ret); + ut_asserteq(2, unsupported_calls); + ut_asserteq(2, success_calls); + for (int i = 0; i < sizeof(digest); i++) + ut_asserteq(0, digest[i]); + + ut_assertok(hash_test_unbind_all()); + ut_assertok(hash_test_bind(DM_DRIVER_GET(hash_test_hard_error_drv), + "hash-hard-error")); + ut_assertok(hash_test_bind(DM_DRIVER_GET(hash_test_success_drv), + "hash-success")); + + hard_error_calls = 0; + success_calls = 0; + ret = hash_digest_wd_lookup(HASH_ALGO_SHA256, "test", 4, digest, 4); + ut_asserteq(-EINVAL, ret); + ut_asserteq(1, hard_error_calls); + ut_asserteq(0, success_calls); + + return 0; +} + +DM_TEST(dm_test_hash_provider_selection, UTF_SCAN_FDT); diff --git a/test/dm/net_defrag.c b/test/dm/net_defrag.c index 3fd40de90cd..7501b252db9 100644 --- a/test/dm/net_defrag.c +++ b/test/dm/net_defrag.c @@ -80,3 +80,39 @@ static int dm_test_net_ip_defrag_dup_last(struct unit_test_state *uts) } DM_TEST(dm_test_net_ip_defrag_dup_last, 0); + +/* + * A fragment placed at the very top of the reassembly buffer takes the + * split-hole branch, which writes an 8-byte "struct hole" at + * pkt_buff + IP_HDR_SIZE + (offset8 + len / 8) * 8. With start + len equal to + * IP_MAXUDP that write reaches the end of pkt_buff and spills past it. pkt_buff + * is a static array, so this is flagged under AddressSanitizer; the fix rejects + * such a fragment instead. The datagram is incomplete, so nothing is delivered + * either way. + */ +static int dm_test_net_ip_defrag_oob(struct unit_test_state *uts) +{ + rxhand_f *saved_handler = net_get_udp_handler(); + uchar frame[FRAME_LEN]; + struct ip_udp_hdr *ip = (struct ip_udp_hdr *)(frame + ETHER_HDR_SIZE); + u16 payload[4] = { 0, 0, 0, 0 }; + /* Offset (8-byte units) so that start + FRAG_LEN == IP_MAXUDP. */ + u16 off8 = (CONFIG_NET_MAXDEFRAG - IP_HDR_SIZE - FRAG_LEN) / 8; + + udp_rx_count = 0; + net_set_udp_handler(defrag_udp_handler); + + build_frag(frame, IP_FLAGS_MFRAG | off8, payload); + /* A distinct id forces a fresh reassembly independent of earlier tests. */ + ip->ip_id = htons(0x7abc); + ip->ip_sum = 0; + ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); + net_process_received_packet(frame, FRAME_LEN); + + ut_asserteq(0, udp_rx_count); + + net_set_udp_handler(saved_handler); + + return 0; +} +DM_TEST(dm_test_net_ip_defrag_oob, 0); |
