Re: BUG: unable to handle kernel paging request in fuse_copy_do

From: David Hildenbrand
Date: Fri Mar 22 2024 - 11:41:44 EST


On 22.03.24 14:50, Miklos Szeredi wrote:
[MM list + secretmem author CC-d]

On Thu, 21 Mar 2024 at 08:52, xingwei lee <xrivendell7@xxxxxxxxx> wrote:

Hello I found a bug titled "BUG: unable to handle kernel paging
request in fuse_copy_do” with modified syzkaller, and maybe it is
related to fs/fuse.
I also confirmed in the latest upstream.

If you fix this issue, please add the following tag to the commit:
Reported-by: xingwei lee <xrivendell7@xxxxxxxxx>
Reported-by: yue sun <samsun1006219@xxxxxxxxx>

Thanks for the report. This looks like a secretmem vs get_user_pages issue.

I reduced the syz reproducer to a minimal one that isn't dependent on fuse:

=== repro.c ===
#define _GNU_SOURCE

#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/socket.h>

int main(void)
{
int fd1, fd2, fd3;
int pip[2];
struct iovec iov;
void *addr;

fd1 = syscall(__NR_memfd_secret, 0);
addr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, fd1, 0);
ftruncate(fd1, 7);
fd2 = socket(AF_INET, SOCK_DGRAM, 0);
getsockopt(fd2, 0, 0, NULL, addr);

pipe(pip);
iov.iov_base = addr;
iov.iov_len = 0x50;
vmsplice(pip[1], &iov, 1, 0);

pip[1] should be the write end. So it will be used as the source.

I assume we go the ITER_SOURCE path in vmsplice, and call vmsplice_to_pipe(). Then we call iter_to_pipe().

I would expect iov_iter_get_pages2() -> get_user_pages_fast() to fail on secretmem pages?

But at least the vmsplice() just seems to work. Which is weird, because GUP-fast should not apply (page not faulted in?) and check_vma_flags() bails out early on vma_is_secretmem(vma).

So something is not quite right.


fd3 = open("/tmp/repro-secretmem.test", O_RDWR | O_CREAT, 0x600);
splice(pip[0], NULL, fd3, NULL, 0x50, 0);

return 0;
}




--
Cheers,

David / dhildenb