NetBSD Problem Report #57622

From martin@duskware.de  Wed Sep 20 13:19:41 2023
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id E62A91A9238
	for <gnats-bugs@gnats.NetBSD.org>; Wed, 20 Sep 2023 13:19:40 +0000 (UTC)
From: martin@NetBSD.org
Reply-To: martin@NetBSD.org
To: gnats-bugs@NetBSD.org
Subject: memfd mmap does not work for requests < page size
X-Send-Pr-Version: 3.95

>Number:         57622
>Category:       kern
>Synopsis:       memfd mmap does not work for requests < page size
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 20 13:20:01 +0000 2023
>Last-Modified:  Sun Mar 17 08:55:01 +0000 2024
>Originator:     Martin Husemann
>Release:        NetBSD 10.99.8
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD thirdstage.duskware.de 10.99.8 NetBSD 10.99.8 (MODULAR) #666: Wed Sep 20 15:01:11 CEST 2023 martin@thirdstage.duskware.de:/usr/src/sys/arch/sparc64/compile/MODULAR sparc64
Architecture: sparc64
Machine: sparc64
>Description:

I noticed a new failing test in the sparc64 test runs:

tc-end: 1695216107.518483, seal_grow, failed, /usr/src/tests/kernel/t_memfd_create.c:270: Mmap failed unexpectedly (Invalid argument)

and tracked it down to the test writing 4096 byte to the memfd and then trying
to map that. On sparc64 the page size is 8k.

This makes the code sys/kern/sys_memfd.c line 352 fail:

        if (*offp + size > mfd->mfd_size) {
                error = EINVAL;
                goto leave;
        }

because mmap rounded up the requested size "size" to full pages already,
but mfd->mfd_size is smaller:

	*offp: 0 + size: 8192 > mfd_size: 4096

>How-To-Repeat:
s/a

>Fix:
Adjust mfd_size to full pages and make sure the surplus bytes are zeroed?
Keep track of the number of pages separately from content size and make the
if test against the #pages?

>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/57622: memfd mmap does not work for requests < page size
Date: Thu, 21 Sep 2023 05:37:57 -0000 (UTC)

 martin@NetBSD.org writes:

 >This makes the code sys/kern/sys_memfd.c line 352 fail:
 >        if (*offp + size > mfd->mfd_size) {
 >                error = EINVAL;
 >                goto leave;
 >        }
 >because mmap rounded up the requested size "size" to full pages already,

 >>Fix:
 >Adjust mfd_size to full pages and make sure the surplus bytes are zeroed?
 >Keep track of the number of pages separately from content size and make the
 >if test against the #pages?


 mfd_size must stay as is to keep the correct "file" size for
 read/write operations. The partial page must be zero filled when
 mapped and that part of the page must not be "written back" in
 case it gets modified.

From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/57622: memfd mmap does not work for requests < page size
Date: Sun, 17 Mar 2024 09:51:05 +0100

 Maybe this:

 Index: sys/kern/sys_memfd.c
 ===================================================================
 RCS file: /cvsroot/src/sys/kern/sys_memfd.c,v
 retrieving revision 1.11
 diff -p -u -r1.11 sys_memfd.c
 --- sys/kern/sys_memfd.c	12 Aug 2023 23:22:49 -0000	1.11
 +++ sys/kern/sys_memfd.c	17 Mar 2024 08:46:34 -0000
 @@ -348,7 +348,7 @@ memfd_mmap(file_t *fp, off_t *offp, size
  		error = EINVAL;
  		goto leave;
  	}
 -	if (*offp + size > mfd->mfd_size) {
 +	if (*offp + size < 0) {
  		error = EINVAL;
  		goto leave;
  	}
 @@ -359,6 +359,12 @@ memfd_mmap(file_t *fp, off_t *offp, size
  		goto leave;
  	}

 +	/* Zero fill end of partial page */
 +	if (*offp + size > mfd->mfd_size) {
 +		ubc_zerorange(mfd->mfd_uobj, mfd->mfd_size,
 +		    *offp + size - mfd->mfd_size, 0);
 +	}
 +
  	uao_reference(fp->f_memfd->mfd_uobj);
  	*uobjp = fp->f_memfd->mfd_uobj;


 Greetings,
 -- 
                                 Michael van Elst
 Internet: mlelstv@serpens.de
                                 "A potential Snark may lurk in every tree."

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.