summaryrefslogtreecommitdiff
path: root/test/dm
diff options
context:
space:
mode:
Diffstat (limited to 'test/dm')
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/hash.c157
-rw-r--r--test/dm/net_defrag.c36
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);