mqueue,ksem,shm: Fix race condition with setting UF_EXCLOSE.
POSIX mqueue, compatibility ksem and POSIX shm create a file descriptor that has close-on-exec set. However, they do this incorrectly, leaving a window where a thread may fork and exec while the flag has not been set yet. The race is easily reproduced on a multicore system with one thread doing shm_open and close and another thread doing posix_spawnp and waitpid. Set UF_EXCLOSE via falloc()'s flags argument instead. This also simplifies the code. MFC after: 1 week
This commit is contained in:
parent
3550618d0b
commit
b68cf25fe6
@ -1977,7 +1977,7 @@ kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
|
||||
if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
|
||||
return (EINVAL);
|
||||
|
||||
error = falloc(td, &fp, &fd, 0);
|
||||
error = falloc(td, &fp, &fd, O_CLOEXEC);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
@ -2032,10 +2032,6 @@ kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
|
||||
finit(fp, flags & (FREAD | FWRITE | O_NONBLOCK), DTYPE_MQUEUE, pn,
|
||||
&mqueueops);
|
||||
|
||||
FILEDESC_XLOCK(fdp);
|
||||
if (fdp->fd_ofiles[fd].fde_file == fp)
|
||||
fdp->fd_ofiles[fd].fde_flags |= UF_EXCLOSE;
|
||||
FILEDESC_XUNLOCK(fdp);
|
||||
td->td_retval[0] = fd;
|
||||
fdrop(fp, td);
|
||||
return (0);
|
||||
|
@ -485,7 +485,7 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
|
||||
|
||||
fdp = td->td_proc->p_fd;
|
||||
mode = (mode & ~fdp->fd_cmask) & ACCESSPERMS;
|
||||
error = falloc(td, &fp, &fd, 0);
|
||||
error = falloc(td, &fp, &fd, O_CLOEXEC);
|
||||
if (error) {
|
||||
if (name == NULL)
|
||||
error = ENOSPC;
|
||||
@ -578,10 +578,6 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
|
||||
|
||||
finit(fp, FREAD | FWRITE, DTYPE_SEM, ks, &ksem_ops);
|
||||
|
||||
FILEDESC_XLOCK(fdp);
|
||||
if (fdp->fd_ofiles[fd].fde_file == fp)
|
||||
fdp->fd_ofiles[fd].fde_flags |= UF_EXCLOSE;
|
||||
FILEDESC_XUNLOCK(fdp);
|
||||
fdrop(fp, td);
|
||||
|
||||
return (0);
|
||||
|
@ -534,7 +534,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
|
||||
fdp = td->td_proc->p_fd;
|
||||
cmode = (uap->mode & ~fdp->fd_cmask) & ACCESSPERMS;
|
||||
|
||||
error = falloc(td, &fp, &fd, 0);
|
||||
error = falloc(td, &fp, &fd, O_CLOEXEC);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
@ -629,10 +629,6 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
|
||||
|
||||
finit(fp, FFLAGS(uap->flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops);
|
||||
|
||||
FILEDESC_XLOCK(fdp);
|
||||
if (fdp->fd_ofiles[fd].fde_file == fp)
|
||||
fdp->fd_ofiles[fd].fde_flags |= UF_EXCLOSE;
|
||||
FILEDESC_XUNLOCK(fdp);
|
||||
td->td_retval[0] = fd;
|
||||
fdrop(fp, td);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user