From: Jerome Forissier <jerome.forissier@arm.com>
To: Shahriyar Jalayeri <shahriyar@byteray.co.uk>,
u-boot@lists.u-boot-project.org
Cc: Tom Rini <trini@konsulko.com>,
Sebastian Josue Alba Vives <sebasjosue84@gmail.com>,
Argus <argus@byteray.co.uk>
Subject: Re: [PATCH v2 0/3] net: nfs: bound server-supplied lengths in READ and READLINK replies
Date: Fri, 14 Aug 2026 10:56:25 +0200 [thread overview]
Message-ID: <1fa9b820-d4e5-4956-b1ab-928e06e024bf@arm.com> (raw)
In-Reply-To: <20260813-nfs-oob-fix-v2-0-80993770518e@byteray.co.uk>
Hi Shahriyar,
On 13/08/2026 17:48, Shahriyar Jalayeri wrote:
> A malicious NFS server can return replies whose 32-bit lengths are crafted
> to defeat the client's bounds checks.
>
> nfs_read_reply() keeps the READ length in a signed int. On LP64 a value
> with the top bit set is negative, the bounds check passes, and
> store_block() then hands a ~2 GB length to memcpy(), which reads past the
> 1152-byte reply buffer on the stack and writes past image_load_addr.
>
> nfs_readlink_reply() has the same signed-length flaw. A length of -1 slips
> past the destination bound as pathlen - 1 and drives a memcpy() off
> nfs_path_buff. The bound is also measured from the reply header rather than
> from the symlink data, so a large positive length reads a few bytes past
> the received reply. A server reaches this handler by answering the READ
> with an ISDIR status, which moves the client into the readlink state.
>
> Both handlers are shared by the classic and lwIP NFS clients through
> nfs_pkt_recv().
>
> Patch 1 bounds the READ length by NFS_READ_SIZE. Patch 2 rejects a negative
> readlink length and measures its bound from the symlink data. Patch 3
> enables CONFIG_CMD_NFS in the sandbox config and adds DM regression tests
> that drive nfs_pkt_recv() with crafted replies.
I think the rlen < 0 check in patches 1 and 2 is awkward and not fully robust.
I suggest making rlen a u32 instead.
- For nfs_read_reply() in patch 1:
u32 rlen;
size_t data_offset;
rlen = ntohl(rpc_pkt.u.reply.data[3 + nfsv3_data_offset]);
if (rlen > NFS_READ_SIZE)
return -9999;
data_offset = data_ptr - (uchar *)&rpc_pkt;
if (data_offset > len || rlen > len - data_offset)
return -9999;
- For nfs_readlink_reply() in patch 2:
u32 rlen;
size_t data_offset;
rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
data_offset = (uchar *)&rpc_pkt.u.reply.data[2 + nfsv3_data_offset] -
(uchar *)&rpc_pkt;
if (data_offset > len || rlen > len - data_offset)
return -NFS_RPC_DROP;
In addition, nfs_readlink_reply() has this check:
if (pathlen + rlen >= sizeof(nfs_path_buff))
IMO pathlen should be size_t and the test replaced with:
if (pathlen >= sizeof(nfs_path_buff) ||
rlen >= sizeof(nfs_path_buff) - pathlen)
return -NFS_RPC_DROP;
What do you think?
Thanks,
--
Jerome
>
> A reproducer is available on request.
>
> Signed-off-by: Shahriyar Jalayeri <shahriyar@byteray.co.uk>
> ---
> Changes in v2:
> - Add a fix for the same signed-length flaw in nfs_readlink_reply(),
> rejecting a negative length and measuring the bound from the symlink
> data.
> - Enable CONFIG_CMD_NFS in sandbox_defconfig so the regression tests are
> built and run under sandbox; the v1 test was skipped in CI.
> - Add a readlink regression test alongside the read one.
>
> ---
> Shahriyar Jalayeri (3):
> net: nfs: reject a negative or oversized NFS read length
> net: nfs: reject a negative or oversized readlink length
> test: dm: nfs: add regression tests for the NFS reply-length checks
>
> configs/sandbox_defconfig | 1 +
> net/nfs-common.c | 9 ++++-
> test/dm/Makefile | 1 +
> test/dm/nfs.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 100 insertions(+), 1 deletion(-)
> ---
> base-commit: baa64b2f892890f00a377eac4a3e685472bb56b5
> change-id: 20260811-nfs-oob-fix-31c433a22c91
>
> Best regards,
> --
> Shahriyar Jalayeri <shahriyar@byteray.co.uk>
>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
prev parent reply other threads:[~2026-08-14 8:57 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 15:48 [PATCH v2 0/3] net: nfs: bound server-supplied lengths in READ and READLINK replies Shahriyar Jalayeri
2026-08-13 15:48 ` [PATCH v2 1/3] net: nfs: reject a negative or oversized NFS read length Shahriyar Jalayeri
2026-08-13 15:48 ` [PATCH v2 2/3] net: nfs: reject a negative or oversized readlink length Shahriyar Jalayeri
2026-08-13 15:48 ` [PATCH v2 3/3] test: dm: nfs: add regression tests for the NFS reply-length checks Shahriyar Jalayeri
2026-08-14 8:56 ` Jerome Forissier [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1fa9b820-d4e5-4956-b1ab-928e06e024bf@arm.com \
--to=jerome.forissier@arm.com \
--cc=argus@byteray.co.uk \
--cc=sebasjosue84@gmail.com \
--cc=shahriyar@byteray.co.uk \
--cc=trini@konsulko.com \
--cc=u-boot@lists.u-boot-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox