Linux filesystem development
 help / color / mirror / Atom feed
From: Viacheslav Dubeyko <vdubeyko@redhat.com>
To: Alex Markuze <amarkuze@redhat.com>,
	Viacheslav Dubeyko <slava@dubeyko.com>
Cc: ceph-devel@vger.kernel.org, idryomov@gmail.com,
	 linux-fsdevel@vger.kernel.org, pdonnell@redhat.com
Subject: Re: [RFC PATCH] ceph: fix kernel memory exposure issue in ceph_netfs_issue_op_inline()
Date: Mon, 27 Apr 2026 15:00:07 -0700	[thread overview]
Message-ID: <f2bb92bd6f5b34b92f229a3ec1f2e4fe20931240.camel@redhat.com> (raw)
In-Reply-To: <CAO8a2Sh+=ef4mjp8tOR4HeqY9r4CaPJ7rCq1-WEmO25on7uSRA@mail.gmail.com>

On Mon, 2026-04-27 at 15:27 +0300, Alex Markuze wrote:
> Apologies, I acked the wrong patch here.
> 
> The Bug is real and needs fixing, but there is a problem:
> 
> 
>   1. subreq->start is silently dropped
> 
>   The original code:
>   len = min_t(size_t, iinfo->inline_len - subreq->start, subreq->len);
>   err = copy_to_iter(iinfo->inline_data + subreq->start, len, &subreq->io_iter);

The subreq->start is meaningless here. We cannot use subreq->start at all. We
need to know the offset inside of inline buffer. Mostly, it should be small
enough. If we would like to process it in the correct way, probably, we need to
introduce some special field in some structure. But subreq->start is completely
inapplicable in this calculation.

During testing I saw that subreq->start was 0. And I saw subreq->start == 32768
something for the case of issue.

> 
>   The new code:
>   len = min_t(size_t, iinfo->inline_len, subreq->len);
>   err = copy_to_iter(iinfo->inline_data, len, &subreq->io_iter);
> 
>   The subreq->start offset is completely removed. If subreq->start > 0
> with valid inline data, the wrong bytes are copied (always from offset
> 0 instead of the requested offset).
>    While CephFS inline data is typically small and subreq->start is
> likely 0 in practice, the fix is still semantically incorrect for the
> general case.
> 
>   2. -EFAULT is the wrong error code. When inline_len == 0, the data
> was uninlined; there's no inline payload.
>       Returning -EFAULT signals a user-address fault, which is
> misleading and will propagate as an I/O error instead of falling back
> to the OSD path.
> 

Which error code do you suggest to use here?

>   3. Coding style violation. The } else without braces:
>       } else
>           err = -EFAULT;
> 

I can rework it.

>   I suggest the following:
> 
>   A cleaner approach would preserve the offset logic and handle the
> edge cases properly:
> 
>   if (iinfo->inline_len == 0 || subreq->start >= iinfo->inline_len) {
>       /* Nothing to copy; CLEAR_TAIL flag will zero-fill */
>       len = 0;
>   } else {
>       len = min_t(size_t, iinfo->inline_len - subreq->start, subreq->len);
>       err = copy_to_iter(iinfo->inline_data + subreq->start,
>                          len, &subreq->io_iter);
>       if (err == 0)
>           err = -EFAULT;
>       else {
>           subreq->transferred += err;
>           err = 0;
>       }
>   }
> 
>   Or alternatively, treat inline_len == 0 the same way as
> inline_version == CEPH_INLINE_NONE and return false to let the caller
> fall back to a normal OSD read.
> 

We can use subreq->start at all. We need to consider something else.

Thanks,
Slava.

>  Alex
> 
> On Mon, Apr 27, 2026 at 3:16 PM Alex Markuze <amarkuze@redhat.com> wrote:
> > 
> > Reviewed-by: Alex Markuze <amarkuze@redhat.com>
> > 
> > On Fri, Feb 27, 2026 at 12:30 AM Viacheslav Dubeyko <slava@dubeyko.com> wrote:
> > > 
> > > From: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
> > > 
> > > Repeatable running of generic/013 test has revealed
> > > the kernel memory exposure attempt for 6.19.0-rc8+ in
> > > ceph_netfs_issue_op_inline():
> > > 
> > > while true; do
> > >   sudo ./check generic/013
> > > done
> > > 
> > > [17660.888303] ceph: ceph_netfs_issue_op_inline():317 iinfo->inline_data ffff8881000b0112,
> > > iinfo->inline_len 0, subreq->start 328187904, subreq->len 4096, len 0
> > > [17660.891728] usercopy: Kernel memory exposure attempt detected from SLUB object 'kmemleak_object' (offset 274, size 4096)!
> > > [17660.893370] ------------[ cut here ]------------
> > > [17660.893377] kernel BUG at mm/usercopy.c:102!
> > > [17660.894426] Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
> > > [17660.895749] CPU: 1 UID: 0 PID: 150873 Comm: fsstress Not tainted 6.19.0-rc8+ #13 PREEMPT(voluntary)
> > > [17660.896823] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-9.fc43 06/10/2025
> > > [17660.897891] RIP: 0010:usercopy_abort+0x7a/0x7c
> > > [17660.898575] Code: 48 c7 c6 80 bb 3e 8c eb 0e 48 c7 c7 c0 bb 3e 8c 48 c7 c6 00 bc 3e 8c 52
> > > 48 89 fa 48 c7 c7 40 bc 3e 8c 50 41 52 e8 e6 00 fb ff <0f> 0b e8 ef 0e fb 00 4d 89 e0 31 c9 44 89 f2 48 c7 c6 c0 bd 3e 8c
> > > [17660.901225] RSP: 0018:ffff888179fbf340 EFLAGS: 00010246
> > > [17660.901762] RAX: 000000000000006d RBX: ffff8881139ac112 RCX: 0000000000000000
> > > [17660.902295] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
> > > [17660.902813] RBP: ffff888179fbf358 R08: 0000000000000000 R09: 0000000000000000
> > > [17660.903317] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000001000
> > > [17660.903820] R13: ffff8881139ad112 R14: 0000000000000001 R15: ffff888119da8bb0
> > > [17660.904283] FS:  0000747714d62740(0000) GS:ffff888266112000(0000) knlGS:0000000000000000
> > > [17660.904719] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > > [17660.905122] CR2: 00007477143ffff0 CR3: 00000001014f9005 CR4: 0000000000772ef0
> > > [17660.905555] PKRU: 55555554
> > > [17660.905743] Call Trace:
> > > [17660.905902]  <TASK>
> > > [17660.906042]  __check_heap_object+0xf1/0x130
> > > [17660.906372]  ? __virt_addr_valid+0x26b/0x510
> > > [17660.906667]  __check_object_size+0x401/0x700
> > > [17660.906959]  ceph_netfs_issue_read.cold+0x295/0x2f1
> > > [17660.907322]  ? __pfx_ceph_netfs_issue_read+0x10/0x10
> > > [17660.907657]  ? __kasan_check_write+0x14/0x30
> > > [17660.907940]  ? kvm_sched_clock_read+0x11/0x20
> > > [17660.908268]  ? sched_clock_noinstr+0x9/0x10
> > > [17660.908531]  ? local_clock_noinstr+0xf/0x120
> > > [17660.908817]  netfs_read_to_pagecache+0x45a/0x10f0
> > > [17660.909168]  ? netfs_read_to_pagecache+0x45a/0x10f0
> > > [17660.909482]  netfs_write_begin+0x589/0xfc0
> > > [17660.909761]  ? __kasan_check_read+0x11/0x20
> > > [17660.910019]  ? __pfx_netfs_write_begin+0x10/0x10
> > > [17660.910340]  ? mark_held_locks+0x46/0x90
> > > [17660.910629]  ? inode_set_ctime_current+0x3d0/0x520
> > > [17660.910965]  ceph_write_begin+0x8c/0x1c0
> > > [17660.911237]  generic_perform_write+0x391/0x8f0
> > > 
> > > The reason of the issue is located in this code:
> > > 
> > > err = copy_to_iter(iinfo->inline_data + subreq->start,
> > >                    len, &subreq->io_iter);
> > > 
> > > We have valid pointer iinfo->inline_data ffff8881000b0112.
> > > The iinfo->inline_len has 0 size in bytes. However, subreq->start
> > > has really big value 328187904. Finally, the sum of iinfo->inline_data
> > > and subreq->start results in the pointer that is out of available
> > > memory area.
> > > 
> > > This patch checks the iinfo->inline_len value. If it has zero value,
> > > then -EFAULT code error will be return. Otherwise, the copy_to_iter()
> > > logic will be executed.
> > > 
> > > Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
> > > cc: Alex Markuze <amarkuze@redhat.com>
> > > cc: Ilya Dryomov <idryomov@gmail.com>
> > > cc: Patrick Donnelly <pdonnell@redhat.com>
> > > cc: Ceph Development <ceph-devel@vger.kernel.org>
> > > ---
> > >  fs/ceph/addr.c | 18 +++++++++++-------
> > >  1 file changed, 11 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> > > index e87b3bb94ee8..426121e38f3f 100644
> > > --- a/fs/ceph/addr.c
> > > +++ b/fs/ceph/addr.c
> > > @@ -314,14 +314,18 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq)
> > >                 return false;
> > >         }
> > > 
> > > -       len = min_t(size_t, iinfo->inline_len - subreq->start, subreq->len);
> > > -       err = copy_to_iter(iinfo->inline_data + subreq->start, len, &subreq->io_iter);
> > > -       if (err == 0) {
> > > +       if (iinfo->inline_len > 0) {
> > > +               len = min_t(size_t, iinfo->inline_len, subreq->len);
> > > +
> > > +               err = copy_to_iter(iinfo->inline_data, len, &subreq->io_iter);
> > > +               if (err == 0) {
> > > +                       err = -EFAULT;
> > > +               } else {
> > > +                       subreq->transferred += err;
> > > +                       err = 0;
> > > +               }
> > > +       } else
> > >                 err = -EFAULT;
> > > -       } else {
> > > -               subreq->transferred += err;
> > > -               err = 0;
> > > -       }
> > > 
> > >         ceph_mdsc_put_request(req);
> > >  out:
> > > --
> > > 2.53.0
> > > 


  reply	other threads:[~2026-04-27 22:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-26 22:30 [RFC PATCH] ceph: fix kernel memory exposure issue in ceph_netfs_issue_op_inline() Viacheslav Dubeyko
2026-04-27 12:16 ` Alex Markuze
2026-04-27 12:27   ` Alex Markuze
2026-04-27 22:00     ` Viacheslav Dubeyko [this message]
2026-04-28 22:34     ` Ilya Dryomov

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=f2bb92bd6f5b34b92f229a3ec1f2e4fe20931240.camel@redhat.com \
    --to=vdubeyko@redhat.com \
    --cc=amarkuze@redhat.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=idryomov@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=pdonnell@redhat.com \
    --cc=slava@dubeyko.com \
    /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