From kent@erix.ericsson.se  Tue Mar 31 07:40:22 1998
Received: from penguin.wise.edt.ericsson.se (penguin-ext.wise.edt.ericsson.se [194.237.142.5])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id HAA05190
          for <FreeBSD-gnats-submit@freebsd.org>; Tue, 31 Mar 1998 07:40:21 -0800 (PST)
          (envelope-from kent@erix.ericsson.se)
Received: from super.du.etx.ericsson.se (root@super.du.etx.ericsson.se [150.236.14.16]) by penguin.wise.edt.ericsson.se (8.7.5/8.7.3/glacier-1.12) with ESMTP id RAA06572 for <FreeBSD-gnats-submit@freebsd.org>; Tue, 31 Mar 1998 17:40:18 +0200 (MET DST)
Received: from scotch.du.etx.ericsson.se (kent@scotch.du.etx.ericsson.se [150.236.14.76])
	by super.du.etx.ericsson.se (8.9.0.Beta3/8.9.0.Beta3/erix-1.4) with ESMTP id RAA10092
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 31 Mar 1998 17:40:17 +0200 (MET DST)
Received: by scotch.du.etx.ericsson.se (8.8.8/client-1.4)
	id RAA18108; Tue, 31 Mar 1998 17:40:17 +0200 (CEST)
Message-Id: <199803311540.RAA18108@scotch.du.etx.ericsson.se>
Date: Tue, 31 Mar 1998 17:40:17 +0200 (CEST)
From: Kent Boortz <kent@erix.ericsson.se>
Reply-To: kent@erix.ericsson.se
To: FreeBSD-gnats-submit@freebsd.org
Subject: No error if resulting file pos in lseek is negative
X-Send-Pr-Version: 3.2

>Number:         6184
>Category:       kern
>Synopsis:       No error if resulting file pos in lseek is negative
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar 31 07:50:02 PST 1998
>Closed-Date:    Sun Nov 13 07:34:17 GMT 2005
>Last-Modified:  Sun Nov 13 07:34:17 GMT 2005
>Originator:     
>Release:        FreeBSD 2.2.5-STABLE i386
>Organization:
Ericsson Software Technology
>Environment:
 
>Description:
 
In FreeBSD 2.2.5 lseek moves the file position without any error
checks. If the resulting position is negative we have the problem that
the result value -1 can mean two things, that there was an error or
that the file position was set to -1 and no error. We have to clear
errno before the call and examine errno after the call to find out if
there was an error or not.
 
If the resulting position is negative, Linux and Solaris will
preserve the file position before the call to lseek and return an
error.
 
Is this a bug in FreeBSD or a different interpretations of the POSIX
standard?
 
>How-To-Repeat:
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
 
void main()
{
  char *Name = "myfile";
  int pos, fd = open(Name,O_WRONLY | O_CREAT);
 
  write(fd,"ABCDEFGH",8);
  close(fd);
 
  fd = open(Name,O_RDONLY);
 
  if ((pos = lseek(fd,-5,SEEK_CUR)) != -1) {
    printf("No error moving to pos -5: %d\n",pos);
    exit(1);
  }

  printf("ERROR: %s\n",strerror(errno));
 
  pos = lseek(fd,0,SEEK_CUR);
 
  printf("The error moved the file pointer to: %d\n",pos);
}

>Fix:
	
I belive the fix should be in the file
"/usr/src/sys/kern/vfs_syscalls.c" and the function lseek(). Prior to
setting the new file position the function should test if the new
value is negative. If so the old position should be preserved and the
function return an error with errno EINVAL.
>Release-Note:
>Audit-Trail:

From: Poul-Henning Kamp <phk@critter.freebsd.dk>
To: freebsd-gnats-submit@freebsd.org
Cc:  Subject: Re: kern/6184 
Date: Wed, 20 May 1998 08:59:08 +0200

 In message <xzp7m4ob1a5.fsf@hrotti.ifi.uio.no>, Dag-Erling Coidan =?iso-8859-1?
 Q?Sm=F8rgrav?= writes:
 >I have a patch which I hope fixes kern/6184 (lseek allows seeks to
 >negative offsets), but I don't want to commit it without having
 >someone look at it first:
 >
 >Index: src/sys/kern/vfs_syscalls.c
 >===================================================================
 >RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
 >retrieving revision 1.97
 >diff -u -r1.97 vfs_syscalls.c
 >--- vfs_syscalls.c      1998/04/08 18:31:57     1.97
 >+++ vfs_syscalls.c      1998/04/17 21:03:13
 >@@ -1324,6 +1324,7 @@
 >        register struct filedesc *fdp = p->p_fd;
 >        register struct file *fp;
 >        struct vattr vattr;
 >+       off_t ofs;
 >        int error;
 >
 >        if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
 >@@ -1333,21 +1334,22 @@
 >                return (ESPIPE);
 >        switch (SCARG(uap, whence)) {
 >        case L_INCR:
 >-               fp->f_offset += SCARG(uap, offset);
 >+               ofs = fp->f_offset + SCARG(uap, offset);
 >                break;
 >        case L_XTND:
 >                error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p);
 >                if (error)
 >                        return (error);
 >-               fp->f_offset = SCARG(uap, offset) + vattr.va_size;
 >+               ofs = SCARG(uap, offset) + vattr.va_size;
 >                break;
 >        case L_SET:
 >-               fp->f_offset = SCARG(uap, offset);
 >+               ofs = SCARG(uap, offset);
 >                break;
 >        default:
 >                return (EINVAL);
 >        }
 >-       *(off_t *)(p->p_retval) = fp->f_offset;
 >+       if (ofs < 0) return (EINVAL);
 >+       *(off_t *)(p->p_retval) = fp->f_offset = ofs;
 >        return (0);
 > }
 >
 >Index: src/lib/libc/sys/lseek.2
 >===================================================================
 >RCS file: /home/ncvs/src/lib/libc/sys/lseek.2,v
 >retrieving revision 1.6
 >diff -u -r1.6 lseek.2
 >--- lseek.2     1997/02/22 15:04:01     1.6
 >+++ lseek.2     1998/04/17 21:05:23
 >@@ -120,7 +120,7 @@
 > is associated with a pipe, socket, or FIFO.
 > .It Bq Er EINVAL
 > .Fa Whence
 >-is not a proper value.
 >+is not a proper value, or the resulting offset is negative.
 > .El
 > .Sh SEE ALSO
 > .Xr dup 2 ,
 >
 >-- 
 >Nobody else has a .sig like this one.
 >
 >To Unsubscribe: send mail to majordomo@FreeBSD.org
 >with "unsubscribe freebsd-current" in the body of the message
 >
 
 --
 Poul-Henning Kamp             FreeBSD coreteam member
 phk@FreeBSD.ORG               "Real hackers run -current on their laptop."
 "ttyv0" -- What UNIX calls a $20K state-of-the-art, 3D, hi-res color terminal

From: <jkoshy@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc: phk@FreeBSD.org, des@FreeBSD.org
Subject: Re: kern/6184: No error if resulting file pos in lseek is negative
Date: Tue, 7 Sep 1999 01:34:55 -0700 (PDT)

 This is a multipart MIME message.
 
 --==_Exmh_-3322228240
 Content-Type: text/plain
 
 
 The patch given in the PR seems fine.  I've touched it up a little to
 avoid some style nits and have reworded the manual page to make the
 behaviour clearer.  A small test program is included.
 
 Any reason why this shouldn't go into -current?  If there aren't any
 objections, I'd like to commit this and take the change up with JKH for
 merging to 3.3-RC.
 
 Regards,
 Koshy
 
 
 --==_Exmh_-3322228240
 Content-Type: text/plain ; name="a.c"
 Content-Description: test-program
 Content-Disposition: attachment; filename="a.c"
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <errno.h>
 
 int main(int argc, char **argv)
 {
   char *Name = "myfile";
   int pos, fd = open(Name,O_WRONLY | O_CREAT,0777);
 
   write(fd,"ABCDEFGH",8);
   close(fd);
 
   fd = open(Name,O_RDONLY);
 
 #define fail 1
 #define succeed 0
 #define TEST_LSEEK(whence, value, shouldfail) do {\
 	printf("> " #whence "(%d): ", value); \
 	pos = lseek(fd, value, whence); \
 	printf((shouldfail ? (pos == -1) : (pos >= 0)) ? "pass\n" : "fail\n"); \
 	(void) lseek(fd, 0, SEEK_SET); \
 	} while (0)
 	
 
   TEST_LSEEK(SEEK_CUR, -5, fail);
   TEST_LSEEK(SEEK_CUR, +5, succeed);
   TEST_LSEEK(SEEK_CUR, +10, succeed);
 
   TEST_LSEEK(SEEK_SET, -5, fail);
   TEST_LSEEK(SEEK_SET, +5, succeed);
   TEST_LSEEK(SEEK_SET, +10, succeed);
 
   TEST_LSEEK(SEEK_END, -10, fail);
   TEST_LSEEK(SEEK_END, -5, succeed);
   TEST_LSEEK(SEEK_END, +10, succeed);
 
   return 0;
 }
 
 --==_Exmh_-3322228240
 Content-Type: text/plain ; name="foo"
 Content-Description: revised-lseek-patch
 Content-Disposition: attachment; filename="foo"
 
 Index: sys/kern/vfs_syscalls.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
 retrieving revision 1.130
 diff -u -r1.130 vfs_syscalls.c
 --- vfs_syscalls.c	1999/08/12 20:38:32	1.130
 +++ vfs_syscalls.c	1999/09/07 12:28:15
 @@ -1423,6 +1423,7 @@
  	register struct file *fp;
  	struct vattr vattr;
  	int error;
 +	off_t ofs;
  
  	if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
  	    (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
 @@ -1431,21 +1432,23 @@
  		return (ESPIPE);
  	switch (SCARG(uap, whence)) {
  	case L_INCR:
 -		fp->f_offset += SCARG(uap, offset);
 +		ofs = fp->f_offset + SCARG(uap, offset);
  		break;
  	case L_XTND:
  		error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p);
  		if (error)
  			return (error);
 -		fp->f_offset = SCARG(uap, offset) + vattr.va_size;
 +		ofs = SCARG(uap, offset) + vattr.va_size;
  		break;
  	case L_SET:
 -		fp->f_offset = SCARG(uap, offset);
 +		ofs = SCARG(uap, offset);
  		break;
  	default:
  		return (EINVAL);
  	}
 -	*(off_t *)(p->p_retval) = fp->f_offset;
 +	if (ofs < 0)
 +		return (EINVAL);
 +	*(off_t *)(p->p_retval) = fp->f_offset = ofs;
  	return (0);
  }
  
 Index: lib/libc/sys/lseek.2
 ===================================================================
 RCS file: /home/ncvs/src/lib/libc/sys/lseek.2,v
 retrieving revision 1.8
 diff -u -r1.8 lseek.2
 --- lseek.2	1998/04/19 22:20:08	1.8
 +++ lseek.2	1999/09/07 13:03:50
 @@ -95,6 +95,7 @@
  of the existing end-of-file of the file. If data is later written
  at this point, subsequent reads of the data in the gap return
  bytes of zeros (until data is actually written into the gap).
 +Setting the file offset to negative values is not permitted.
  .Pp
  Some devices are incapable of seeking.  The value of the pointer
  associated with such a device is undefined.
 @@ -120,7 +121,7 @@
  is associated with a pipe, socket, or FIFO.
  .It Bq Er EINVAL
  .Fa Whence
 -is not a proper value.
 +is not a proper value or the resulting file offset would be negative.
  .El
  .Sh SEE ALSO
  .Xr dup 2 ,
 
 --==_Exmh_-3322228240--
 
 
 

From: Dag-Erling Smorgrav <des@flood.ping.uio.no>
To: jkoshy@FreeBSD.org
Cc: FreeBSD-gnats-submit@FreeBSD.org, phk@FreeBSD.org
Subject: Re: kern/6184: No error if resulting file pos in lseek is negative
Date: 09 Sep 1999 10:42:04 +0200

 jkoshy@FreeBSD.org writes:
 > The patch given in the PR seems fine.  I've touched it up a little to
 > avoid some style nits and have reworded the manual page to make the
 > behaviour clearer.  A small test program is included.
 
 Hmf, I had totally forgotten this PR. Took me a while to remember what
 it was about and why it concerned me :)
 
 There's a reason why I didn't commit that patch - I don't remember the
 details, but I vaguely recall someone convincing me that returning an
 error was not necessarily the right thing. It's been so long I'd have
 to search the archives to find out for sure.
 
 This took me back a long way, BTW - I'd only had commits for something
 like a month and a half when I wrote this :)
 
 DES
 -- 
 Dag-Erling Smorgrav - des@flood.ping.uio.no
 

From: <jkoshy@FreeBSD.org>
To: Dag-Erling Smorgrav <des@flood.ping.uio.no>
Cc: FreeBSD-gnats-submit@freebsd.org, phk@freebsd.org,
	bde@freebsd.org
Subject: Re: kern/6184: No error if resulting file pos in lseek is negative 
Date: Thu, 9 Sep 1999 02:42:26 -0700 (PDT)

 > There's a reason why I didn't commit that patch - I don't remember the
 > details, but I vaguely recall someone convincing me that returning an
 > error was not necessarily the right thing. It's been so long I'd have
 > to search the archives to find out for sure.
 
 As it stands, the patch is not correct because we need to be able to lseek
 to half-way of a 64 bit address range after opening /dev/[k]mem. 
 POSIX allows negative file offsets for special devices. 
 {ISO/IEC 9945-1:1996 Rationale [B.6.5.3]}.
 
 OpenBSD solves this problem by allowing negative file offsets if the
 file descriptor refers to a character device. NetBSD has a VOP_SEEK()
 operation and defers checking of the validity of the offset to its
 lower layers.  IMO, the NetBSD way is correct because EINVAL is supposed to
 be returned if an 'invalid offset' results from the attempted lseek(), and
 different filesystems can have different 'invalid offsets'.
 
 For now I'm testing a simple version which checks for character 
 devices and allows negative offsets.
 
 Regards,
 Koshy
 
State-Changed-From-To: open->analyzed 
State-Changed-By: ache 
State-Changed-When: Wed Feb 20 05:17:31 PST 2002 
State-Changed-Why:  
Fixed in -current 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=6184 
State-Changed-From-To: analyzed->patched 
State-Changed-By: ache 
State-Changed-When: Sat Jun 8 12:58:58 PDT 2002 
State-Changed-Why:  
This PR state must be "patched" according to guideline 

http://www.freebsd.org/cgi/query-pr.cgi?pr=6184 
State-Changed-From-To: patched->closed 
State-Changed-By: linimon 
State-Changed-When: Sun Nov 13 07:33:57 GMT 2005 
State-Changed-Why:  
Fixed back in 2002. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=6184 
>Unformatted:
