On 17/01/17(Tue) 00:24, Alexander Bluhm wrote: > On Mon, Jan 16, 2017 at 08:36:46PM +0100, [email protected] wrote: > > kernel: protection fault trap, code=0 > > Stopped at fd_getfile+0x20: testb $0x2,mptramp_gdt32_desc+0x1e(%r > > ax) > > ddb{3}> fd_getfile() at fd_getfile+0x20 > > sys_fstat() at sys_fstat+0x43 > > syscall() at syscall+0x27b > > It crashes in fd_getfile() FILE_IS_USABLE(fp) as fdp->fd_ofiles has > been freed. > > fdexpand() assumes that is has the write lock, calls free(fdp->fd_ofiles) > and then sleeps in mallocarray(M_WAITOK) before updating fdp->fd_ofiles. > > As fd_getfile() does not grab a readlock, it may get scheduled while > fdexpand() sleeps. > > Simply calling rw_enter_read(&fdp->fd_lock) in fd_getfile() does > not work, as sometimes it is called with the writelock already held. > Not sure wether such a write lock check is nice style, but it avoids > to fix all callers.
Fixing all the callers might not be a bad idea. I think that fd_getfile() should return a proper reference counted fp. In other words we might tends toward including FREF() inside fd_getfile(). Once that's done we would need to protect the counter increment and decrement for MP safety. This could be done by ensuring ``fd_lock'' is held.
