Hi Bruno,

On 5/18/24 5:03 PM, Bruno Haible wrote:
> And it's a good idea to reference the bug report in a comment:
> @c https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58266
> So that in the future it helps us to understand what the bug is
> about and how to reproduce it in newer versions of NetBSD.

The bug report got addressed today. In the following commit [1]:

  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.

and then a second to deal with syscall versioning [2].

Looking into their comment about EINVAL vs EBADF, they follow what
FreeBSD and OpenBSD do [3][4]. I think we may have the ordering wrong
in lib/dup3.c:

  if (newfd < 0 || newfd >= getdtablesize () || fcntl (oldfd, F_GETFD) == -1)
    {
      errno = EBADF;
      return -1;
    }

  if (newfd == oldfd)
    {
      errno = EINVAL;
      return -1;
    }

In the Linux kernel sources they are done in this order [5]:

    if ((flags & ~O_CLOEXEC) != 0)
      return -EINVAL;

    if (unlikely(oldfd == newfd))
      return -EINVAL;

    if (newfd >= rlimit(RLIMIT_NOFILE))
       return -EBADF;

Unless glibc wraps the syscall in it's own functions where the order
is changed. I'm not too sure how that stuff works but I couldn't seem
to find it.

Collin

[1] 
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/kern/sys_descrip.c.diff?r1=1.48&r2=1.49&only_with_tag=MAIN
[2] 
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/kern/sys_descrip.c.diff?r1=1.49&r2=1.50&only_with_tag=MAIN
[3] https://github.com/freebsd/freebsd-src/blob/main/lib/libc/gen/dup3.c
[4] 
https://github.com/openbsd/src/blob/8b68e9dedc5b1a2ef9fae4d11f703c6d7be32352/sys/kern/kern_descrip.c#L328
[5] 
https://github.com/torvalds/linux/blob/eb6a9339efeb6f3d2b5c86fdf2382cdc293eca2c/fs/file.c#L1354

Reply via email to