MFC Rev 1.188 + 1.192 Avoid file lock leakage when linuxthreads port or rfork is used: - Mark the process leader as having an advisory lock - Check if process leader is marked as having advisory lock when closing file - Check that file is still open after lock has been obtained - Don't allow file descriptor table sharing between processes with different leaders --- sys/kern/kern_fork.c.orig Sun Feb 23 00:16:47 2003 +++ sys/kern/kern_fork.c Sun Feb 23 00:17:52 2003 @@ -130,6 +130,14 @@ int error; struct proc *p2; + /* + * Don't allow sharing of file descriptor table unless + * RFTHREAD flag is supplied + */ + if ((uap->flags & (RFPROC | RFTHREAD | RFFDG | RFCFDG)) == + RFPROC) + return(EINVAL); + error = fork1(p, uap->flags, &p2); if (error == 0) { p->p_retval[0] = p2 ? p2->p_pid : 0; --- sys/kern/kern_descrip.c.orig Mon Nov 11 02:43:31 2002 +++ sys/kern/kern_descrip.c Sat Mar 22 15:19:04 2003 @@ -311,7 +311,7 @@ fcntl(p, uap) error = EBADF; break; } - p->p_flag |= P_ADVLOCK; + p->p_leader->p_flag |= P_ADVLOCK; error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg); break; @@ -320,7 +320,7 @@ fcntl(p, uap) error = EBADF; break; } - p->p_flag |= P_ADVLOCK; + p->p_leader->p_flag |= P_ADVLOCK; error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg); break; @@ -332,6 +332,15 @@ fcntl(p, uap) error = EINVAL; break; } + /* Check for race with close */ + if ((unsigned)uap->fd >= fdp->fd_nfiles || + fp != fdp->fd_ofiles[uap->fd]) { + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = F_UNLCK; + (void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &fl, F_POSIX); + } fdrop(fp, p); return(error); @@ -1268,7 +1277,8 @@ closef(fp, p) * If the descriptor was in a message, POSIX-style locks * aren't passed with the descriptor. */ - if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) { + if (p != NULL && (p->p_leader->p_flag & P_ADVLOCK) != 0 && + fp->f_type == DTYPE_VNODE) { lf.l_whence = SEEK_SET; lf.l_start = 0; lf.l_len = 0;