fd_lastfile should be -1 when there are no opened file descriptors.

Hence, make find_last_set return -1 in such situation, and initialize it
such.  Otherwise, with 0 meaning two things, it confused the F_CLOSEM
fcntl which could end up looping indifintely (PR#28929 by Brian Marcotte).

However, this change enlightens another bug in fdcopy(), where more entries
than needed were cleared in the new file descriptor table, so the memset()
call there is fixed too.

Analyzed with the help of Greg Oster.
This commit is contained in:
cube 2005-01-12 20:41:45 +00:00
parent 0db75d3501
commit 8ec7c6764b
1 changed files with 10 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_descrip.c,v 1.127 2004/11/30 04:25:43 christos Exp $ */
/* $NetBSD: kern_descrip.c,v 1.128 2005/01/12 20:41:45 cube Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.127 2004/11/30 04:25:43 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.128 2005/01/12 20:41:45 cube Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -141,7 +141,7 @@ find_last_set(struct filedesc *fd, int last)
off--;
if (off < 0)
return (0);
return (-1);
i = ((off + 1) << NDENTRYSHIFT) - 1;
if (i >= last)
@ -1100,6 +1100,7 @@ fdinit1(struct filedesc0 *newfdp)
newfdp->fd_fd.fd_knlistsize = -1;
newfdp->fd_fd.fd_himap = newfdp->fd_dhimap;
newfdp->fd_fd.fd_lomap = newfdp->fd_dlomap;
newfdp->fd_fd.fd_lastfile = -1;
simple_lock_init(&newfdp->fd_fd.fd_slock);
}
@ -1222,8 +1223,12 @@ restart:
newfdp->fd_lastfile = lastfile;
newfdp->fd_freefile = fdp->fd_freefile;
memset(newfdp->fd_ofiles + lastfile, 0,
(i - lastfile) * sizeof(struct file **));
/* Clear the entries that will not be copied over.
* Avoid calling memset with 0 size (i.e. when
* lastfile == i-1 */
if (lastfile < (i-1))
memset(newfdp->fd_ofiles + lastfile + 1, 0,
(i - lastfile - 1) * sizeof(struct file **));
memcpy(newfdp->fd_ofileflags, fdp->fd_ofileflags, i * sizeof(char));
if (i < NDENTRIES * NDENTRIES)
i = NDENTRIES * NDENTRIES; /* size of inlined bitmaps */