From owner-svn-src-all@FreeBSD.ORG Tue Apr 29 00:02:52 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C537A766; Tue, 29 Apr 2014 00:02:52 +0000 (UTC) Received: from mail104.syd.optusnet.com.au (mail104.syd.optusnet.com.au [211.29.132.246]) by mx1.freebsd.org (Postfix) with ESMTP id 86F8612D9; Tue, 29 Apr 2014 00:02:52 +0000 (UTC) Received: from c122-106-147-133.carlnfd1.nsw.optusnet.com.au (c122-106-147-133.carlnfd1.nsw.optusnet.com.au [122.106.147.133]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id 00F89424EBF; Tue, 29 Apr 2014 09:43:19 +1000 (EST) Date: Tue, 29 Apr 2014 09:43:19 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Ed Maste Subject: Re: svn commit: r265051 - head/sys/sys In-Reply-To: <201404281342.s3SDgfIO055824@svn.freebsd.org> Message-ID: <20140429080705.T1041@besplex.bde.org> References: <201404281342.s3SDgfIO055824@svn.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=QIpRGG7L c=1 sm=1 tr=0 a=7NqvjVvQucbO2RlWB8PEog==:117 a=PO7r1zJSAAAA:8 a=9hPZJVi7WwkA:10 a=kj9zAlcOel0A:10 a=JzwRw_2MAAAA:8 a=6I5d2MoRAAAA:8 a=nkv3H-rXro4_lS4O7XIA:9 a=CjuIK1q_8ugA:10 a=EMdYaVHK1hYA:10 Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Apr 2014 00:02:52 -0000 On Mon, 28 Apr 2014, Ed Maste wrote: > Log: > Drop explicit unsigned from FD_SETSIZE constant > > FD_SETSIZE is often used as an argument to select or compared with an > integer file descriptor. Rather than force 3rd party software to add > explicit casts, just make it a plain (int) constant as on other > operating systems. > > Previous discussion: > http://lists.freebsd.org/pipermail/freebsd-standards/2012-July/002410.html Thanks. The above discussion refers to my mail in 2002 about related things. I just debugged why this is (now) a non-problem for poll(). It is because the design error of using an unsigned type for a count is standard for poll(), so the unwanted promotions to unsigned should already be expected and handled for poll(). They mainly give confusing differences from select(). % #ifndef _SYS_SYSPROTO_H_ % struct poll_args { % struct pollfd *fds; % u_int nfds; % int timeout; % }; % #endif nfds actually has type nfds_t, but nfds_t is just u_int. POSIX specificies that nfsd_t is an unsigned integer type. % int % sys_poll(td, uap) % struct thread *td; % struct poll_args *uap; % { % struct pollfd *bits; % struct pollfd smallbits[32]; % sbintime_t asbt, precision, rsbt; % u_int nfds; As mentioned in old mail: The nfsds arg has always had type u_int in FreeBSD. The bounds checking of the nfds arg worked between 1997 and 2001 since it was done directly on the arg. However, it was broken for 3 weeks in Feb 2001, by introducing this local variable nfds and giving it a wrong type (int). This gave overflow for negative nfds. Other BSDs apparently had this bug in poll() and/or select() for longer. % int error; % size_t ni; % % nfds = uap->nfds; % if (nfds > maxfilesperproc && nfds > FD_SETSIZE) % return (EINVAL); The "fix" in Feb 2001 was to bogusly cast "int nfds" back to the correct type u_int. The behaviour on overflow was stll undefined, but was benign. Then in Feb 2002, breaking the type of FD_SETSIZE to u_int would have given the same bogus conversion. Then in Jun 2002, the type of the local variable was fixed (modulo the assumption than nfds_t == u_int). So except in the 3 week broken period, we just exploit the arg type being bogusly unsigned. Promotions still occur, but are harmless. (maxfilesperproc has the correct type (int), so it gets promoted to the type of nfds (u_int) in the first comparison. Promotion preserves its value, except possibly on weird arches where maxfilesperproc is weirdly large. So the comparison works. Now, a similar promotion occurs for FD_SETSIZE, and any weirdness in the first comparison would be compensated for by the second comparison, provided FD_SETSIZE is not also weirdly large.) Bruce