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

Bug#173913: more details on this



On Mon, Dec 23, 2002 at 03:14:33AM +0900, GOTO Masanori wrote:
> 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?

This looks right to me, please send it to libc-alpha.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer



Reply to: