VFS: fix filp reuse race
Pipes consist of two filps (read filp and write filp) and a shared vnode. When the writer leaves the filp reference count drops to zero and subsequent find_filp()s should not find the filp when a reader looks for it and the reader gets EOF. However, the pipe() system call tries to find two filps, marks them in use, and only after a successful node creation on PFS, overwrites the shared vnode with the new vnode. Consequently, this leaves a small window where a just closed 'pipe write filp' gets reused and marked as present, before becoming the actual new 'pipe write filp' for a new pipe. A reader for the old pipe will think a writer is present and wait for that writer to write something or to leave; both actions should revive the suspended reader. This will never happen and the reader will be stuck forever.
This commit is contained in:
parent
e292ba487e
commit
26ec619a30
@ -586,6 +586,8 @@ struct filp *f;
|
|||||||
|
|
||||||
unlock_vnode(f->filp_vno);
|
unlock_vnode(f->filp_vno);
|
||||||
put_vnode(f->filp_vno);
|
put_vnode(f->filp_vno);
|
||||||
|
f->filp_vno = NULL;
|
||||||
|
f->filp_mode = FILP_CLOSED;
|
||||||
} else if (f->filp_count < 0) {
|
} else if (f->filp_count < 0) {
|
||||||
panic("VFS: invalid filp count: %d ino %d/%d", f->filp_count,
|
panic("VFS: invalid filp count: %d ino %d/%d", f->filp_count,
|
||||||
vp->v_dev, vp->v_inode_nr);
|
vp->v_dev, vp->v_inode_nr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user