Subject: Re: sys_select() EBADF bug
To: Greywolf <greywolf@starwolf.com>
From: Tad Hunt <tad@entrisphere.com>
List: tech-kern
Date: 11/14/2002 15:38:57
Hmm. I didn't realize that you could shrink the resource limits
below something that was already open and still have the files open.
This should fix that problem then:
by making nd unsigned, we can make this cost about the same as
before by removing the "if(SCARG(uap, nd) < 0)" check.
sys_select()
{
...
u_int nd;
...
nd = SCARG(uap, nd);
/*
* it is possible to shrink the resource limits below the current
* number of open files. Make sure that we handle that case.
*/
if (nd > p->p_fd->fd_nfiles && nd > p->p_rlimit[RLIMIT_NOFILE].rlim_cur)
return (EINVAL);
...
}
In message <Pine.NEB.4.44.0211141522390.625-100000@lothlorien.starwolf.com>, you said:
;On Thu, 14 Nov 2002, Tad Hunt wrote:
;
;# Currently, select will happily block forever if a bad fd is in the
;# list and greater than fd_nfiles. selscan() was already rewritten
;# to use fd_getfile(), which correctly handles a fd beyond the end
;# of the array.
;#
;# This way, if the process puts a fd > the number of open files in,
;# it will still get an EBADF error back from select(2).
;
;So what do you do in the case the proc.curproc.rlimit.nofiles.* gets
;pushed below the selected fd? It's still a valid descriptor.
;
;Now, granted, it's a contrived edge case, but...what if? Theoretically,
;we might want to keep stdin, stdout, stderr opened, and maybe open a
;socket or two, but decrease nofiles to 0 to prevent a given process from
;(re)opening another file (call it paranoia). What then on select()?
;
; --*greywolf;
;--
;NetBSD: No Worries!