Re: Question about potential buffer issue in nfs_request_mount() - seeking feedback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2025-09-01 at 01:38 +0000, SSH wrote:
> Hi NFS maintainers,
> 
> I was looking at a kernel warning from 6.1-rc1 to understand it better and tried to trace through the code to understand what was happening. I think I may have found something, although now the most up-to-date kernel HEAD is August, 2025 and most of all, I'm not a kernel developer so I wanted to ask for your feedback on whether my analysis makes sense.
> 
> ## Context
> * This was on all NFS v3 TCP mounts
> * The warning came from kernel's hardened memcpy detection
> * The mount seemed to work despite the warning
> 
> ### Additional Context
> I noticed this warning was originally reported around 6.1-rc1 timeframe (~2022), but checking the current kernel source, it would appear that the same code pattern exists.
> I'm not sure if this was previously reported to the NFS maintainers specifically, or if there's a reason it wasn't addressed. Either way, I thought it was worth bringing up again in case it got missed or deprioritized.
> 
> Source: https://lkml.org/lkml/2022/10/16/461
> 
> ## The Original Warning
> I saw this warning during NFS v3 TCP mount:
> 
> ```
> [   19.617475] memcpy: detected field-spanning write (size 28) of single field "request.sap" at fs/nfs/super.c:857 (size 18446744073709551615)
> [   19.617504] WARNING: CPU: 3 PID: 1300 at fs/nfs/super.c:857 nfs_request_mount.constprop.0.isra.0+0x1c0/0x1f0
> ```
> 
> ## Likely Source of Failure
> 
> Looking at `nfs_request_mount()` in `fs/nfs/super.c`, I see this code:
> 
> ```c
> // Around line 850
> struct nfs_mount_request request = {
>     .sap = &ctx->mount_server._address,
>     // ... other fields
> };
> 
> // Later, around line 881
> if (ctx->mount_server.address.sa_family == AF_UNSPEC) {
>     memcpy(request.sap, &ctx->nfs_server._address, ctx->nfs_server.addrlen);
>     ctx->mount_server.addrlen = ctx->nfs_server.addrlen;
> }
> ```
> 
> My understanding is:
> 1. `request.sap` points to `ctx->mount_server._address`
> 2. We're copying from `ctx->nfs_server._address` (which could be 28 bytes for IPv6)
> 3. Into whatever `mount_server._address` points to (which might be smaller?)
> 
> The weird size value (18446744073709551615) in the warning makes me think there might be memory corruption happening.
> 
> Does this seem like a real issue? If so, would adding a size check before the memcpy make sense, something like:
> 
> ```c
> if (ctx->mount_server.address.sa_family == AF_UNSPEC) {
>     if (ctx->nfs_server.addrlen <= sizeof(ctx->mount_server._address)) {
>         memcpy(request.sap, &ctx->nfs_server._address, ctx->nfs_server.addrlen);
>         ctx->mount_server.addrlen = ctx->nfs_server.addrlen;
>     } else {
>         // handle error case; maybe -EINVAL?
>         return -EINVAL;
>     }
> }
> ```
> 
> I could easily be misunderstanding something fundamental here, so please let me know if I'm off track. I just wanted to share this in case it's helpful.
> 
> Thanks for your time and for maintaining NFS!
> 

(cc'ing Kees, our resident hardening expert)

FYI, that large size field is 0xffffffffffffffff (a 64-bit integer with
all bits set to 1). The doc header over __fortify_memcpy_chk()
definition is a little helpful, but the commit it refers to
(6f7630b1b5bc) has a bit more info.

It looks like that means that the size detection was broken for this
memcpy check? That commit mentions that this may be due to a GCC bug.

Kees, any thoughts?
-- 
Jeff Layton <jlayton@xxxxxxxxxx>





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux