From owner-cvs-src@FreeBSD.ORG Fri Feb 11 10:52:28 2005 Return-Path: Delivered-To: cvs-src@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 69C3816A4CE; Fri, 11 Feb 2005 10:52:28 +0000 (GMT) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8DEE043D55; Fri, 11 Feb 2005 10:52:27 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87])j1BAqPA6021602; Fri, 11 Feb 2005 21:52:25 +1100 Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) j1BAqNwF017851; Fri, 11 Feb 2005 21:52:24 +1100 Date: Fri, 11 Feb 2005 21:52:22 +1100 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Colin Percival In-Reply-To: <420BC0BD.4030105@freebsd.org> Message-ID: <20050211210252.O32185@delplex.bde.org> References: <200502102009.j1AK92Nf010692@repoman.freebsd.org> <420BC0BD.4030105@freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: cvs-src@freebsd.org cc: src-committers@freebsd.org cc: cvs-all@freebsd.org Subject: Re: cvs commit: src/lib/libc/sys read.2 write.2 X-BeenThere: cvs-src@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: CVS commit messages for the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Feb 2005 10:52:28 -0000 On Thu, 10 Feb 2005, Colin Percival wrote: > Colin Percival wrote: > > read(), pread(), write(), and pwrite() return EINVAL if they are asked > > for more than INT_MAX bytes. Similarly for readv() and writev() if the sum of the counts in the iovec would exceed SSIZE_MAX. Strangely, the behaviour is not implementation-defined for these syscalls -- counts that would exceed SSIZE_MAX force an error. Even more strangely, a negative number of vectors doesn't force an error. The POSIX wording for readv() in an old draft is: %%% 37106 In addition, the readv( ) function shall fail if: 37107 [EINVAL] The sum of the iov_len values in the iov array overflowed an ssize_t. 37108 The readv( ) function may fail if: 37109 [EINVAL] The iovcnt argument was less than or equal to 0, or greater than {IOV_MAX}. %%% FreeBSD already has this with completely different, less correct wording: "The sum of the iov_len values in the iov array overflowed a 32-bit integer." Similarly for other syscalls that return ssize_t. In POSIX, these are about 17 of these, the main other ones being readlink(), recv*() and send*(). In FreeBSD, at least readlink() still returns int and has non-POSIX types for all of its 3 args. The commit has some bugs. I noticed these read.2: (0) It is a bug that the limit is INT_MAX. (1) Text was added to the section that describes read(), readv() and pread(), but it doesn't apply to readv() since readv() doesn't have an nbytes arg. A previous commit that added the description of EOVERFLOW is even buggier (readv() doesn't have an nbytes arg and only pread() has offset arg, but I think the internal file offset instead of the offset arg applies to the others). (2) If the new text actually applied to readv(), then it would describe the error twice for readv(). (3) The new text is unsorted at the end of an almost sorted list, so in particular all the things that can cause EINVAL aren't together like they are for the readv() section. > According to POSIX, these calls have "implementation-defined behaviour" if > nbytes is more than SSIZE_MAX (but should presumably operate without complaint > on sizes up to that limit). The offending test is in dofilewrite() and > dofileread() in sys_generic.c, but fixing this might cause problems in lower > layers if there is any 64-bit unclean code lurking. The lower layers are completely 64-bit unclean. They use "int" for most byte counts starting with uio_resid. It is a bug that ssize_t is __int64_t on 64-bit arches and __int32_t on all 32-bit arches except i386. It should be int on all aches, since that is what is supported. Note that ssize_t has very little to do with size_t. It is the return type of the read() family. However, fixing ssize_t would probably cause binary compatibility problems when it is reduced and larger ones when it is increased after fixing the type of uio_resid. Bruce