[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#173913: more details on this



At Sun, 22 Dec 2002 09:12:16 -0500,
Ben Collins wrote:
> > fcntl64(3, F_SETFD, FD_CLOEXEC)         = -1 ENOSYS (Function not implemented)
> > fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
> > brk(0)                                  = 0x805b000
> > brk(0x805c000)                          = 0x805c000
> > getdents64(0x3, 0x805a6f8, 0x1000, 0)   = -1 ENOSYS (Function not implemented)
> 
> You see how the fcntl64 falls back to fcntl? Getdents64 should do the
> same and it isn't. I bet all the problems are on 2.2.x kernels, and
> 2.4.x works fine.
> 
> This is a glibc bug. Getdents64 needs to be fixed to fallback to
> getdents when getdents64 returns ENOSYS.

Yes. It's so serious. All 2.2 users get this crash.
This problem is occured by below change.

	2002-12-01  Roland McGrath  <roland@redhat.com>
	
	* sysdeps/unix/sysv/linux/getdents.c (__GETDENTS): Fix condition
	testing getdents64 return value.

	--- sysdeps/unix/sysv/linux/getdents.c  3 Nov 2002 03:47:49 -0000       1.19
	+++ sysdeps/unix/sysv/linux/getdents.c  2 Dec 2002 21:01:50 -0000       1.20
	@@ -126,7 +126,7 @@
	       retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),
	                               kbytes);
	 # ifndef __ASSUME_GETDENTS64_SYSCALL
	-      if (retval != -1 && errno != -EINVAL)
	+      if (retval != -1 || errno != EINVAL)
	 # endif
	        {
	          const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)

This patch fixes getdents error bug, on the contrary if retval == -1 &&
errno == ENOSYS, then this function returns error. I think below
patch fixes the problem (but someone think it's something ad-hoc).

--- sysdeps/unix/sysv/linux/getdents.c.org	2002-12-14 02:09:29.000000000 +0900
+++ sysdeps/unix/sysv/linux/getdents.c	2002-12-23 02:15:12.000000000 +0900
@@ -126,7 +126,7 @@
       retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),
 			       kbytes);
 # ifndef __ASSUME_GETDENTS64_SYSCALL
-      if (retval != -1 || errno != EINVAL)
+      if (retval != -1 || (errno != EINVAL && errno != ENOSYS))
 # endif
 	{
 	  const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)


I test it on kernel 2.2, it works fine. I experimentally commit this
patch in cvs named as glibc23-getdents64-fix.dpatch. If no one
objects, I send it to upstream and release -7 quickly.  Any comments
are welcome. Ben, Drow?

s390x issue is another -6 problem. Is this OK already? If not, we have
to resolve ASAP. Gerhard, Jeff?

-- gotom



Reply to: