This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH,HURD] Fix __dup2 _hurd_dtable_lock usage.
Ok, here is an updated patch.
Samuel
2009-01-12 Samuel Thibault <samuel.thibault@ens-lyon.org>
* hurd/hurd/fd.h (_hurd_fd_get): Call HURD_CRITICAL_BEGIN/
HURD_CRITICAL_END around holding _hurd_dtable_lock.
* sysdeps/mach/hurd/dirfd (dirfd): Likewise.
* sysdeps/mach/hurd/dup2.c (__dup2): Lock _hurd_dtable_lock
before checking for _hurd_dtablesize. Unlock it right after
having finished _hurd_dtable allocation.
* sysdeps/mach/hurd/opendir.c (_hurd_fd_opendir): Call
HURD_CRITICAL_BEGIN/HURD_CRITICAL_END around holding
d->port.lock.
Index: hurd/hurd/fd.h
===================================================================
RCS file: /cvs/glibc/libc/hurd/hurd/fd.h,v
retrieving revision 1.37
diff -u -p -r1.37 fd.h
--- hurd/hurd/fd.h 2 Jul 2008 09:53:29 -0000 1.37
+++ hurd/hurd/fd.h 12 Jan 2009 01:59:28 -0000
@@ -65,6 +65,7 @@ _hurd_fd_get (int fd)
{
struct hurd_fd *descriptor;
+ HURD_CRITICAL_BEGIN;
__mutex_lock (&_hurd_dtable_lock);
if (fd < 0 || fd >= _hurd_dtablesize)
descriptor = NULL;
@@ -87,6 +91,7 @@ _hurd_fd_get (int fd)
}
}
__mutex_unlock (&_hurd_dtable_lock);
+ HURD_CRITICAL_END;
return descriptor;
}
Index: sysdeps/mach/hurd/dirfd.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/mach/hurd/dirfd.c,v
retrieving revision 1.4
diff -u -p -r1.4 dirfd.c
--- sysdeps/mach/hurd/dirfd.c 6 Jul 2001 04:55:56 -0000 1.4
+++ sysdeps/mach/hurd/dirfd.c 12 Jan 2009 01:59:30 -0000
@@ -26,6 +26,8 @@ int
dirfd (DIR *dirp)
{
int fd;
+
+ HURD_CRITICAL_BEGIN;
__mutex_lock (&_hurd_dtable_lock);
for (fd = 0; fd < _hurd_dtablesize; ++fd)
if (_hurd_dtable[fd] == dirp->__fd)
@@ -36,6 +38,7 @@ dirfd (DIR *dirp)
fd = -1;
}
__mutex_unlock (&_hurd_dtable_lock);
+ HURD_CRITICAL_END;
return fd;
}
Index: sysdeps/mach/hurd/dup2.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/mach/hurd/dup2.c,v
retrieving revision 1.20
diff -u -p -r1.20 dup2.c
--- sysdeps/mach/hurd/dup2.c 3 Aug 2002 06:46:57 -0000 1.20
+++ sysdeps/mach/hurd/dup2.c 12 Jan 2009 01:59:30 -0000
@@ -68,15 +68,14 @@ __dup2 (fd, fd2)
/* Get a hold of the destination descriptor. */
struct hurd_fd *d2;
+ __mutex_lock (&_hurd_dtable_lock);
+
if (fd2 >= _hurd_dtablesize)
{
/* The table is not large enough to hold the destination
descriptor. Enlarge it as necessary to allocate this
descriptor. */
__mutex_unlock (&_hurd_dtable_lock);
- /* We still hold FD1's lock, but this is safe because
- _hurd_alloc_fd will only examine the cells starting
- at FD2. */
d2 = _hurd_alloc_fd (NULL, fd2);
if (d2)
__spin_unlock (&d2->port.lock);
@@ -96,6 +95,7 @@ __dup2 (fd, fd2)
MACH_PORT_NULL);
}
}
+ __mutex_unlock (&_hurd_dtable_lock);
if (d2 == NULL)
{
@@ -119,7 +119,6 @@ __dup2 (fd, fd2)
_hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */
}
}
- __mutex_unlock (&_hurd_dtable_lock);
_hurd_port_free (&d->port, &ulink, port);
if (ctty != MACH_PORT_NULL)
Index: sysdeps/mach/hurd/opendir.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/mach/hurd/opendir.c,v
retrieving revision 1.17
diff -u -p -r1.17 opendir.c
--- sysdeps/mach/hurd/opendir.c 5 Mar 2006 11:53:30 -0000 1.17
+++ sysdeps/mach/hurd/opendir.c 12 Jan 2009 01:59:31 -0000
@@ -51,9 +51,11 @@ _hurd_fd_opendir (struct hurd_fd *d)
return NULL;
/* Set the descriptor to close on exec. */
+ HURD_CRITICAL_BEGIN;
__spin_lock (&d->port.lock);
d->flags |= FD_CLOEXEC;
__spin_unlock (&d->port.lock);
+ HURD_CRITICAL_END;
dirp->__fd = d;
dirp->__data = dirp->__ptr = NULL;