Hi Shahriyar,

On 11/08/2026 20:15, Shahriyar Jalayeri wrote:
> Add a DM test that feeds nfs_pkt_recv() a crafted NFSv3 READ reply whose
> 32-bit count has the top bit set, with a read outstanding, and checks
> that nothing is stored. An out-of-range length reaches store_block() and
> drives a ~2 GB memcpy() out of the reply buffer, which CONFIG_ASAN
> reports as a stack-buffer-overflow.
> 
> Signed-off-by: Shahriyar Jalayeri <[email protected]>
> ---
>  test/dm/Makefile |  1 +
>  test/dm/nfs.c    | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 56 insertions(+)
> 
> diff --git a/test/dm/Makefile b/test/dm/Makefile
> index fb3e6a7008f..cc51fd33079 100644
> --- a/test/dm/Makefile
> +++ b/test/dm/Makefile
> @@ -78,6 +78,7 @@ obj-$(CONFIG_MUX_MMIO) += mux-mmio.o
>  obj-y += fdtdec.o
>  obj-$(CONFIG_MTD_RAW_NAND) += nand.o
>  obj-$(CONFIG_IP_DEFRAG) += net_defrag.o
> +obj-$(CONFIG_CMD_NFS) += nfs.o
>  obj-$(CONFIG_UT_DM) += nop.o
>  obj-y += ofnode.o
>  obj-y += ofread.o
> diff --git a/test/dm/nfs.c b/test/dm/nfs.c
> new file mode 100644
> index 00000000000..abfa75f1941
> --- /dev/null
> +++ b/test/dm/nfs.c
> @@ -0,0 +1,55 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Regression test for the NFS read-length check.
> + *
> + * A crafted NFSv3 READ reply whose 32-bit count has the top bit set is fed 
> to
> + * the real nfs_pkt_recv() with a read outstanding. The signed length reaches
> + * store_block() as a ~2 GB memcpy() out of the reply buffer, flagged under
> + * AddressSanitizer; the fix rejects it and stores nothing.
> + */
> +
> +#include <net.h>
> +#include <string.h>
> +#include <test/ut.h>
> +#include <dm/test.h>
> +#include "../../net/nfs-common.h"
> +
> +static int dm_test_nfs_read_oob(struct unit_test_state *uts)
> +{
> +     int saved_state = nfs_state;
> +     unsigned long saved_id = rpc_id;
> +     int saved_offset = nfs_offset;
> +     enum nfs_version saved_version = choosen_nfs_version;
> +     u32 saved_size = net_boot_file_size;
> +     struct rpc_t reply;
> +
> +     /* Pretend a READ request is outstanding (NFSv3). */
> +     choosen_nfs_version = NFS_V3;
> +     nfs_state = STATE_READ_REQ;
> +     nfs_offset = 0;
> +     rpc_id = 0x11223344;
> +     net_boot_file_size = 0;
> +
> +     /* Accepted reply, matching xid, READ status OK, no attributes, then a
> +      * count with the top bit set.
> +      */
> +     memset(&reply, 0, sizeof(reply));
> +     reply.u.reply.id = htonl((u32)rpc_id);
> +     reply.u.reply.data[0] = 0;                      /* nfsstat3: OK */
> +     reply.u.reply.data[1] = 0;                      /* attributes_follow: 
> no */
> +     reply.u.reply.data[2] = htonl(0x80000000);      /* count */
> +
> +     nfs_pkt_recv((uchar *)&reply.u.reply, sizeof(reply.u.reply));
> +
> +     /* Rejected: nothing stored. */
> +     ut_asserteq(0, net_boot_file_size);
> +
> +     nfs_state = saved_state;
> +     rpc_id = saved_id;
> +     nfs_offset = saved_offset;
> +     choosen_nfs_version = saved_version;
> +     net_boot_file_size = saved_size;
> +
> +     return 0;
> +}
> +DM_TEST(dm_test_nfs_read_oob, 0);
> 

With the series applied to for-main I got a CI error, see:
https://git.u-boot-project.org/u-boot/custodians/u-boot-net/-/jobs/68484

Thanks,
-- 
Jerome

Reply via email to