NetBSD Problem Report #58266

From www@netbsd.org  Sat May 18 23:00:31 2024
Return-Path: <www@netbsd.org>
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 58B041A9262
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 18 May 2024 23:00:31 +0000 (UTC)
Message-Id: <20240518230019.16CA81A9265@mollari.NetBSD.org>
Date: Sat, 18 May 2024 23:00:19 +0000 (UTC)
From: collin.funk1@gmail.com
Reply-To: collin.funk1@gmail.com
To: gnats-bugs@NetBSD.org
Subject: dup3 behavior differs from FreeBSD, OpenBSD, and glibc.
X-Send-Pr-Version: www-1.0

>Number:         58266
>Category:       lib
>Synopsis:       dup3 behavior differs from FreeBSD, OpenBSD, and glibc.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 18 23:05:00 +0000 2024
>Last-Modified:  Mon May 20 02:00:02 +0000 2024
>Originator:     Collin Funk
>Release:        NetBSD 10.0 amd64
>Organization:
GNU
>Environment:
NetBSD netbsd 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC 2024  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64

>Description:
Hello,

A CI job on NetBSD 9.0 and NetBSD 10.0 caught some test failures in Gnulib, one of which being dup3 [1]. I've reproduced it on a NetBSD 10.0 virtual machine and found a fix for Gnulib.

However, when looking into the test failure I noticed that dup3 on NetBSD behaves differently than FreeBSD, OpenBSD, and glibc.

From the Linux man pages describing the return value [2]:

    If oldfd equals newfd, then dup3() fails with the error EINVAL.

The man pages for FreeBSD and OpenBSD describe this same behavior [3] [4].

On NetBSD the man pages describe a different behavior [5]:

     These calls return the new file descriptor value.  In the case of dup2()
     and dup3() this is always the same as newfd.  If an error occurs, the
     value -1 is returned and errno is set to indicate what happened.

I'm not sure if there was a reasoning behind this difference, so I figured it was worth reporting. I've taken the test case that fails and put it in a sample program attached to help reproduce the behavior. All the other test cases in Gnulib seem to work as expected besides that one.

[1] https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00271.html
[2] https://man7.org/linux/man-pages/man2/dup3.2.html
[3] https://man.freebsd.org/cgi/man.cgi?query=dup3&sektion=3
[4] https://man.openbsd.org/dup.2
[5] https://man.netbsd.org/dup3.2
>How-To-Repeat:

I've extracted the relevant test case and placed it in this program:

=====================================================
#define _GNU_SOURCE 1
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

int
main (void)
{
  const char *file = "test-dup3.tmp";
  int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);
  int result = dup3 (fd, fd, 0);
  int saved_errno = errno;

  /* Check that the file could be created.  */
  if (fd == -1)
    abort ();
  /* Cleanup the file and restore errno.  */
  (void) unlink (file);
  errno = saved_errno;
  /* Expect dup3 to fail with errno == EINVAL.  */
  if (result != -1)
    {
      (void) close (result);
      fprintf (stderr, "dup3 (fd, fd, 0) should fail with EINVAL\n");
      abort ();
    }
  printf ("%s\n", strerror (errno));
  return 0;
}
=====================================================

Here are the results on different platforms. Unfortunately, I don't have access to an OpenBSD machine but I expect it to behave like GNU/Linux and FreeBSD.

On GNU/Linux and FreeBSD:
$ gcc main.c
$ ./a.out 
Invalid argument
$ echo $?
0

On NetBSD:
$ gcc main.c 
$ ./a.out 
dup3 (fd, fd, 0) should fail with EINVAL
Abort trap (core dumped)

>Fix:
I believe that a small change in the 'dodup' function in src/sys/kern/sys_descrip.c should change the behavior to align with the other systems. I am not too familiar with NetBSD though so I may be missing something.

>Audit-Trail:
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 11:56:55 -0400

 Module Name:	src
 Committed By:	christos
 Date:		Sun May 19 15:56:55 UTC 2024

 Modified Files:
 	src/sys/kern: sys_descrip.c

 Log Message:
 PR/58266: Collin Funk: Fail if from == to, like FreeBSD and Linux. The test
 is done in dup3 before any other tests so even if a bad descriptor it is
 passed we will return EINVAL not EBADFD like Linux does.


 To generate a diff of this commit:
 cvs rdiff -u -r1.48 -r1.49 src/sys/kern/sys_descrip.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Jason Thorpe <thorpej@me.com>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org,
 collin.funk1@gmail.com
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 09:07:15 -0700

 > On May 19, 2024, at 9:00=E2=80=AFAM, Christos Zoulas =
 <christos@netbsd.org> wrote:
 >=20
 > The following reply was made to PR lib/58266; it has been noted by =
 GNATS.
 >=20
 > From: "Christos Zoulas" <christos@netbsd.org>
 > To: gnats-bugs@gnats.NetBSD.org
 > Cc:=20
 > Subject: PR/58266 CVS commit: src/sys/kern
 > Date: Sun, 19 May 2024 11:56:55 -0400
 >=20
 > Module Name: src
 > Committed By: christos
 > Date: Sun May 19 15:56:55 UTC 2024
 >=20
 > Modified Files:
 > src/sys/kern: sys_descrip.c
 >=20
 > Log Message:
 > PR/58266: Collin Funk: Fail if from =3D=3D to, like FreeBSD and Linux. =
 The test
 > is done in dup3 before any other tests so even if a bad descriptor it =
 is
 > passed we will return EINVAL not EBADFD like Linux does.

 What is the point of this?  The previous behavior seemed perfectly =
 reasonable, and it=E2=80=99s not like we=E2=80=99re bound by the =
 dictates of POSIX for dup3().

 -- thorpej

From: Christos Zoulas <christos@zoulas.com>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org,
 collin.funk1@gmail.com
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 13:54:02 -0400

 > 
 > What is the point of this?  The previous behavior seemed perfectly =
 > reasonable, and it=E2=80=99s not like we=E2=80=99re bound by the =
 > dictates of POSIX for dup3().

 We copied the API from linux, so we should be compatible. Being incompatible
 in subtle ways means that some programs that depend on the behavior can
 break.

 Best,

 christos

From: Jason Thorpe <thorpej@me.com>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org,
 collin.funk1@gmail.com
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 12:11:16 -0700

 > On May 19, 2024, at 10:55=E2=80=AFAM, Christos Zoulas =
 <christos@zoulas.com> wrote:
 >=20
 >=20
 > We copied the API from linux, so we should be compatible. Being =
 incompatible
 > in subtle ways means that some programs that depend on the behavior =
 can
 > break.

 Well, now we=E2=80=99re incompatible with previous versions of NetBSD.  =
 You should have rev=E2=80=99d the system call.

 -- thorpej

From: Christos Zoulas <christos@zoulas.com>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org,
 collin.funk1@gmail.com
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 17:26:23 -0400

 > 
 > Well, now we=E2=80=99re incompatible with previous versions of NetBSD.  =
 > You should have rev=E2=80=99d the system call.
 > 
 > -- thorpej

 Doing it now...

 christos

From: Collin Funk <collin.funk1@gmail.com>
To: Christos Zoulas <christos@zoulas.com>, gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 14:39:31 -0700

 Hi,

 On 5/19/24 2:26 PM, Christos Zoulas wrote:
 >> Well, now we=E2=80=99re incompatible with previous versions of NetBSD.  =
 >> You should have rev=E2=80=99d the system call.
 >>
 >> -- thorpej
 >
 > Doing it now...

 Thank you for looking into this. I still think that it would be nice
 for NetBSD to behave like the other implementations. But backwards
 compatability is an issue.

 Also what does "rev’d the system call." mean?
 Sorry, I am not very familiar with NetBSD or CVS so it is probably a
 silly question.

 Collin

From: Christos Zoulas <christos@zoulas.com>
To: Collin Funk <collin.funk1@gmail.com>
Cc: gnats-bugs@netbsd.org,
 lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 17:41:47 -0400

 >=20
 > Thank you for looking into this. I still think that it would be nice
 > for NetBSD to behave like the other implementations. But backwards
 > compatability is an issue.
 >=20
 > Also what does "rev=E2=80=99d the system call." mean?
 > Sorry, I am not very familiar with NetBSD or CVS so it is probably a
 > silly question.

 Provide both the old (for already existing binaries) and the new =
 behavior=20
 (for newly compiled binaries) by versioning the system call.
 See versioningsyscalls(9).

 christos

From: Collin Funk <collin.funk1@gmail.com>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@netbsd.org, lib-bug-people@netbsd.org, gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org
Subject: Re: PR/58266 CVS commit: src/sys/kern
Date: Sun, 19 May 2024 18:57:18 -0700

 On 5/19/24 2:41 PM, Christos Zoulas wrote:
 >> Also what does "rev’d the system call." mean?
 >> Sorry, I am not very familiar with NetBSD or CVS so it is probably a
 >> silly question.
 >
 > Provide both the old (for already existing binaries) and the new behavior 
 > (for newly compiled binaries) by versioning the system call.
 > See versioningsyscalls(9).

 Ah, okay I understand now. Thank you. Sounds like a good solution to me.

 Collin

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.