From nobody@FreeBSD.org  Mon Dec  5 08:00:57 2011
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 68A6A1065678
	for <freebsd-gnats-submit@FreeBSD.org>; Mon,  5 Dec 2011 08:00:57 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 58A258FC1A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon,  5 Dec 2011 08:00:57 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id pB580uE1014902
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 5 Dec 2011 08:00:56 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id pB580uKZ014901;
	Mon, 5 Dec 2011 08:00:56 GMT
	(envelope-from nobody)
Message-Id: <201112050800.pB580uKZ014901@red.freebsd.org>
Date: Mon, 5 Dec 2011 08:00:56 GMT
From: Petr Salinger <Petr.Salinger@seznam.cz>
To: freebsd-gnats-submit@FreeBSD.org
Subject: It is not possible to read in chunks from linprocfs  and procfs.
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         163076
>Category:       kern
>Synopsis:       [linprocfs] It is not possible to read in chunks from linprocfs and procfs [regression]
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    jh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 05 08:10:08 UTC 2011
>Closed-Date:    Mon Jan 23 16:37:56 UTC 2012
>Last-Modified:  Mon Jan 23 16:37:56 UTC 2012
>Originator:     Petr Salinger
>Release:        9.0-RC2
>Organization:
>Environment:
>Description:
It is not possible to read in chunks from linprocfs and procfs.
It is a regression against stable-8.
I suspect it is due to changes of sbuf implementation between 8 and 9.

Some files are rather big (over 4KB) and it is really standard to read them in blocks.
>How-To-Repeat:
"dd if=$FILE bs=1", with FILE any file in procfs or linprocfs
The result is empty output.

Tried with FILE /proc/version from linprocfs 
and /proc/curproc/map from procfs. 

For more details see Debian GNU/kFreeBSD bug report 
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=650667

>Fix:


>Release-Note:
>Audit-Trail:

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Petr Salinger <Petr.Salinger@seznam.cz>
Cc: bug-followup@FreeBSD.org, phk@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Mon, 5 Dec 2011 16:49:47 +0200

 Hi,
 
 On 2011-12-05, Petr Salinger wrote:
 > It is not possible to read in chunks from linprocfs and procfs.
 > It is a regression against stable-8.
 > I suspect it is due to changes of sbuf implementation between 8 and 9.
 
 Yes, r222004 changed sbuf_finish() to not clear s->s_error which causes
 the regression. I am not sure if we should blame r222004 or the pseudofs
 code.
 
 I have Cc'd the committer of r222004.
 
 > Some files are rather big (over 4KB) and it is really standard to read them in blocks.
 > >How-To-Repeat:
 > "dd if=$FILE bs=1", with FILE any file in procfs or linprocfs
 > The result is empty output.
 > 
 > Tried with FILE /proc/version from linprocfs 
 > and /proc/curproc/map from procfs. 
 > 
 > For more details see Debian GNU/kFreeBSD bug report 
 > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=650667
 
 -- 
 Jaakko

From: Bruce Evans <brde@optusnet.com.au>
To: Petr Salinger <Petr.Salinger@seznam.cz>
Cc: freebsd-gnats-submit@FreeBSD.org, freebsd-bugs@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Tue, 6 Dec 2011 02:07:02 +1100 (EST)

 On Mon, 5 Dec 2011, Petr Salinger wrote:
 
 >> Description:
 > It is not possible to read in chunks from linprocfs and procfs.
 > It is a regression against stable-8.
 > I suspect it is due to changes of sbuf implementation between 8 and 9.
 >
 > Some files are rather big (over 4KB) and it is really standard to read them in blocks.
 >> How-To-Repeat:
 > "dd if=$FILE bs=1", with FILE any file in procfs or linprocfs
 > The result is empty output.
 
 I don't remember this ever working.  The correct way to fix it is
 unclear (start by not claiming that the highly irregular files in
 procfs are regular), but empty output is unnecessarily bad - I
 would expect to get at least 1 byte.  Under FreeBSD-~5.2, I get
 the following file sizes:
 
 file       dd (1 byte)   dd (10k)   dd (1m)   wc | cut... wc -c      stat
 --------   -----------   --------   -------   --------    --------   --------
 cmdline    0             6          EIO       6           0          0
 ctl        EBADF         EBADF      EBADF     EBADF       ctl        0
 dbregs     hangs         hangs      hangs     hangs       0          0
 etype      0             14         EIO       14          0          0
 file@      575712        575712     575712    575712      575712     575712
 fpregs     hangs         hangs      hangs     hangs       0          0
 map        0             1150       EIO       1150        0          0
 mem        EBADF         EBADF      EBADF     EBADF       0          0
 note       EBADF         EBADF      EBADF     EBADF       0          0
 notepg     EBADF         EBADF      EBADF     EBADF       0          0
 regs       hangs         hangs      hangs     hangs       0          0
 rlimit     0             65         EIO       65          0          0
 status     0             94         EIO       94          0          0
 
 The irregularity is so large that it confuses wc -c into not working,
 while plain wc works.  This is apparently because wc -c believes the
 claim that the file is regular, so it stats the file to get its size
 and finds 0, while plain wc reads the whole file using block size 64K.
      (md5 is another utility that is broken on such files, but it
      is broken even for files that don't claim to be regular.  E.g.,
      md5 on /dev/zero (or any device file that you can open) gives
      the same result as md5 on /dev/null, because it just stats the
      file, although this is completely wrong for device files.  md5
      is unbroken on pipes, so you can apply it to device files using
      the apparent beginner's pessimization "cat /dev/foo | md5".
      This method works for the irregular regular files in procfs
      too.  You would have to use dd instead of cat to control the
      block size, and choose a size that is large enough to work and
      small enough to avoid EIO.)
 
 The *regs files don't block doing the read(), but just loop endlessly
 trying to read an infinite amount.  This is because the uio offset is
 reset to 0 after each read.  ISTR this being done for some other file
 types.  This is a different feeble attempt to fix the problem in this
 PR.  The basic problem is that seeking is not implemented for many
 files, so there is no way to continue reading from the previous uio
 offset, so the new offset must be either infinity (for most files) or
 0 (for regs files).
 
 I can now explain more of the above irregularities:
 - for tiny files, seeking is easy to implement by sprintf()ing the
    whole file and using an offset in the string.  The string constant
    should be either invariant or the previously generated string must
    be saved across reads (saving the string is only reasonable if it
    is tiny).  This (except possibly for sufficient invariance/saving)
    is done.  But some bug breaks reads of size 1.  Perhaps this is fixed
    in -current, or was fixed and has been broken again.  dd seems to
    work with block sizes betwen 2 and 128k inclusive in cases where it
    works with a block size of 10k in the above.  The 128k limit would
    be explained by the misimplementation of attempting to malloc() the
    user-specified read size instead of the tiny size actually needed.
    The user must not be allowed to malloc() large sizes and there is
    an arbitrary limit of 128k.
 - the regs files are small although not tiny.  But they are highly
    variable so they should be read atomically using read() syscalls.
    Thus seeking in them is not useful.  This should probably by enforced
    by only allowing the uio offset to be 0 or EOF.  Instead, it is only
    partially enforced by resetting the offset to 0 after each read (I
    hink applications can mess this up by lseek()ing between reads), So
    callers don't need to do an lseek() for this.  This API was invented
    before pread() existed.  pread() should be used now.  This API results
    in casual observers reading the same data endlessly.  I sometimes
    look at these files using hd and would prefer that EOF worked normally
    for them.
 
 Bruce

From: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Mon, 05 Dec 2011 16:38:35 +0000

 In message <20111205144947.GA2267@a91-153-116-96.elisa-laajakaista.fi>, Jaakko 
 Heinonen writes:
 
 >Yes, r222004 changed sbuf_finish() to not clear s->s_error which causes
 >the regression. I am not sure if we should blame r222004 or the pseudofs
 >code.
 
 The sbuf code is correct.
 
 Sbufs were designed to have "latching error semantics" and any errors
 should not be cleared by sbuf_finish() for exactly that reason.
 
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk@FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Mon, 5 Dec 2011 23:42:02 +0200

 On 2011-12-05, Poul-Henning Kamp wrote:
 > >Yes, r222004 changed sbuf_finish() to not clear s->s_error which causes
 > >the regression. I am not sure if we should blame r222004 or the pseudofs
 > >code.
 > 
 > The sbuf code is correct.
 > 
 > Sbufs were designed to have "latching error semantics" and any errors
 > should not be cleared by sbuf_finish() for exactly that reason.
 
 Shouldn't sbuf_finish() then check s->s_error before appending the
 trailing '\0' and setting the SBUF_FINISHED flag? The problem in
 question wasn't caught earlier because sbuf_finish() happily finishes
 the buffer even if it has an error.
 
 -- 
 Jaakko

From: Petr Salinger <Petr.Salinger@seznam.cz>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>, bug-followup@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Tue, 6 Dec 2011 09:38:49 +0100 (CET)

 >>> Yes, r222004 changed sbuf_finish() to not clear s->s_error which causes
 >>> the regression. I am not sure if we should blame r222004 or the pseudofs
 >>> code.
 
 The "dd testcase" works for us with change bellow.
 It also solves the original problem.
 I am unsure whether it is a right way, though.
 
 Petr
 
 
 --- a/sys/fs/pseudofs/pseudofs_vnops.c
 +++ b/sys/fs/pseudofs/pseudofs_vnops.c
 @@ -640,7 +640,7 @@
          if (buflen > MAXPHYS + 1)
                  buflen = MAXPHYS + 1;
 
 -       sb = sbuf_new(sb, NULL, buflen, 0);
 +       sb = sbuf_new(sb, NULL, MAXPHYS + 1, 0);
          if (sb == NULL) {
                  error = EIO;
                  goto ret;
 @@ -654,7 +654,12 @@
          }
 
          sbuf_finish(sb);
 -       error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
 +
 +       if (buflen > sbuf_len(sb))
 +           buflen = sbuf_len(sb);
 +       else
 +           buflen--;
 +       error = uiomove_frombuf(sbuf_data(sb), buflen, uio);
          sbuf_delete(sb);
   ret:
          vn_lock(vn, locked | LK_RETRY);
 

From: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Tue, 06 Dec 2011 11:20:09 +0000

 In message <20111205214201.GA37871@jh>, Jaakko Heinonen writes:
 >On 2011-12-05, Poul-Henning Kamp wrote:
 
 >> Sbufs were designed to have "latching error semantics" and any errors
 >> should not be cleared by sbuf_finish() for exactly that reason.
 >
 >Shouldn't sbuf_finish() then check s->s_error before appending the
 >trailing '\0' and setting the SBUF_FINISHED flag? The problem in
 >question wasn't caught earlier because sbuf_finish() happily finishes
 >the buffer even if it has an error.
 
 I belive the code is written so that there is always reserved space 
 for the final '\0'
 
 sbuf_finish() should finish _any_ sbuf, and return zero only if
 the finished buffer is fully OK.
 
 I belive it does that, if not its a bug.
 
 The intent is that you don't have to check for errors more than
 one place: sbuf_finish()
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk@FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Tue, 6 Dec 2011 15:21:36 +0200

 On 2011-12-06, Poul-Henning Kamp wrote:
 > >Shouldn't sbuf_finish() then check s->s_error before appending the
 > >trailing '\0' and setting the SBUF_FINISHED flag? The problem in
 > >question wasn't caught earlier because sbuf_finish() happily finishes
 > >the buffer even if it has an error.
 > 
 > I belive the code is written so that there is always reserved space 
 > for the final '\0'
 > 
 > sbuf_finish() should finish _any_ sbuf, and return zero only if
 > the finished buffer is fully OK.
 
 Anyway I find it inconsistent that you can successfully call
 sbuf_finish() and sbuf_data() but not for example sbuf_len() on an
 errored buffer.
 
 Thus you can "fix" the problem with the subtle change below.
 
 %%%
 Index: sys/fs/pseudofs/pseudofs_vnops.c
 ===================================================================
 --- sys/fs/pseudofs/pseudofs_vnops.c	(revision 228153)
 +++ sys/fs/pseudofs/pseudofs_vnops.c	(working copy)
 @@ -651,7 +651,7 @@ pfs_read(struct vop_read_args *va)
  	}
  
  	sbuf_finish(sb);
 -	error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
 +	error = uiomove_frombuf(sbuf_data(sb), strlen(sbuf_data(sb)), uio);
  	sbuf_delete(sb);
  ret:
  	vn_lock(vn, locked | LK_RETRY);
 %%%
 
 -- 
 Jaakko

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	des@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Wed, 7 Dec 2011 18:08:34 +0200

 Hi,
 
 On 2011-12-06, Jaakko Heinonen wrote:
 > On 2011-12-06, Poul-Henning Kamp wrote:
 > > >Shouldn't sbuf_finish() then check s->s_error before appending the
 > > >trailing '\0' and setting the SBUF_FINISHED flag? The problem in
 > > >question wasn't caught earlier because sbuf_finish() happily finishes
 > > >the buffer even if it has an error.
 > > 
 > > I belive the code is written so that there is always reserved space 
 > > for the final '\0'
 > > 
 > > sbuf_finish() should finish _any_ sbuf, and return zero only if
 > > the finished buffer is fully OK.
 > 
 > Anyway I find it inconsistent that you can successfully call
 > sbuf_finish() and sbuf_data() but not for example sbuf_len() on an
 > errored buffer.
 
 After looking at some code using sbufs I think that the sbuf(9) API
 change done in r222004 is problematic. Lots of code doesn't check the
 return value of sbuf_finish() but they expect sbuf_len() to return the
 actual length regardless of the error status after calling
 sbuf_finish(). Since r222004 sbuf_len() may return -1 after
 sbuf_finish().
 
 In user space also SBUF_AUTOEXTEND buffers are affected because
 malloc(3) can fail and cause the error status to be set.
 
 Could we just remove the error check from sbuf_len()? (patch below) I
 have Cc'd more people.
 
 sbuf(9) manual page wrongly claims that sbuf_data() will return NULL if
 the buffer has overflowed.
 
 %%%
 Index: sys/kern/subr_sbuf.c
 ===================================================================
 --- sys/kern/subr_sbuf.c	(revision 228153)
 +++ sys/kern/subr_sbuf.c	(working copy)
 @@ -725,8 +725,6 @@ sbuf_len(struct sbuf *s)
  	KASSERT(s->s_drain_func == NULL,
  	    ("%s makes no sense on sbuf %p with drain", __func__, s));
  
 -	if (s->s_error != 0)
 -		return (-1);
  	return (s->s_len);
  }
  
 Index: share/man/man9/sbuf.9
 ===================================================================
 --- share/man/man9/sbuf.9	(revision 228153)
 +++ share/man/man9/sbuf.9	(working copy)
 @@ -25,7 +25,7 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd January 25, 2011
 +.Dd December 7, 2011
  .Dt SBUF 9
  .Os
  .Sh NAME
 @@ -462,14 +462,6 @@ function returns a non-zero value if the
  drain error, and zero otherwise.
  .Pp
  The
 -.Fn sbuf_data
 -and
 -.Fn sbuf_len
 -functions return
 -.Dv NULL
 -and \-1, respectively, if the buffer overflowed.
 -.Pp
 -The
  .Fn sbuf_copyin
  function
  returns \-1 if copying string from userland failed, and number of bytes
 %%%
 
 -- 
 Jaakko

From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>,  Petr Salinger <Petr.Salinger@seznam.cz>,  bug-followup@FreeBSD.org,  mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Fri, 09 Dec 2011 13:17:59 +0100

 Jaakko Heinonen <jh@FreeBSD.org> writes:
 > After looking at some code using sbufs I think that the sbuf(9) API
 > change done in r222004 is problematic.
 
 I agree, but it's far from the first poorly thought-out change in the
 sbuf API.  The biggest mistake was to allow userland to use the same API
 and code rather than its own implementation of a subset of the API.
 
 > Could we just remove the error check from sbuf_len()? (patch below) I
 > have Cc'd more people.
 
 Why?
 
 > sbuf(9) manual page wrongly claims that sbuf_data() will return NULL if
 > the buffer has overflowed.
 
 This used to be the case.  I don't know why I removed the check.
 
 DES
 --=20
 Dag-Erling Sm=C3=B8rgrav - des@des.no

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>,
	Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Fri, 9 Dec 2011 14:36:17 +0200

 On 2011-12-09, Dag-Erling Smørgrav wrote:
 > > Could we just remove the error check from sbuf_len()? (patch below) I
 > > have Cc'd more people.
 > 
 > Why?
 
 As I wrote existing code depends on sbuf_len() to return the actual
 length regardless of the error status after sbuf_finish(). I am not
 willing to through all code using sbufs to check where it causes
 problems. phk@ asserts that r222004 is correct.
 
 -- 
 Jaakko

From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>,  Petr Salinger <Petr.Salinger@seznam.cz>,  bug-followup@FreeBSD.org,  mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Fri, 09 Dec 2011 15:04:22 +0100

 Jaakko Heinonen <jh@FreeBSD.org> writes:
 > As I wrote existing code depends on sbuf_len() to return the actual
 > length regardless of the error status after sbuf_finish(). I am not
 > willing to through all code using sbufs to check where it causes
 > problems. phk@ asserts that r222004 is correct.
 
 What if the sbuf is in a state where asking for its length is
 meaningless?
 
 DES
 --=20
 Dag-Erling Sm=C3=B8rgrav - des@des.no

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>,
	Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Fri, 9 Dec 2011 16:35:30 +0200

 On 2011-12-09, Dag-Erling Smørgrav wrote:
 > Jaakko Heinonen <jh@FreeBSD.org> writes:
 > > As I wrote existing code depends on sbuf_len() to return the actual
 > > length regardless of the error status after sbuf_finish(). I am not
 > > willing to through all code using sbufs to check where it causes
 > > problems. phk@ asserts that r222004 is correct.
 > 
 > What if the sbuf is in a state where asking for its length is
 > meaningless?
 
 Could you give an example about such state? Isn't the length first
 initialized to zero and then increased only when byte(s) has been
 successfully appended to the buffer? sbuf_len() has worked for
 unfinished buffers since r71724.
 
 -- 
 Jaakko

From: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
To: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
Cc: Jaakko Heinonen <jh@FreeBSD.org>, Petr Salinger <Petr.Salinger@seznam.cz>,
        bug-followup@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Fri, 09 Dec 2011 14:51:15 +0000

 In message <86d3bxaljt.fsf@ds4.des.no>, =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= wr
 ites:
 >Jaakko Heinonen <jh@FreeBSD.org> writes:
 >> As I wrote existing code depends on sbuf_len() to return the actual
 >> length regardless of the error status after sbuf_finish(). I am not
 >> willing to through all code using sbufs to check where it causes
 >> problems. phk@ asserts that r222004 is correct.
 >
 >What if the sbuf is in a state where asking for its length is
 >meaningless?
 
 It will always have a length, but the length may not represent
 all you tried to stuff into the sbuf, if the sbuf has failed.
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk@FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.

From: mdf@FreeBSD.org
To: Jaakko Heinonen <jh@freebsd.org>
Cc: =?ISO-8859-1?Q?Dag=2DErling_Sm=F8rgrav?= <des@des.no>, 
	Poul-Henning Kamp <phk@phk.freebsd.dk>, Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@freebsd.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Fri, 9 Dec 2011 07:33:46 -0800

 2011/12/9 Jaakko Heinonen <jh@freebsd.org>:
 > On 2011-12-09, Dag-Erling Sm=F8rgrav wrote:
 >> > Could we just remove the error check from sbuf_len()? (patch below) I
 >> > have Cc'd more people.
 >>
 >> Why?
 >
 > As I wrote existing code depends on sbuf_len() to return the actual
 > length regardless of the error status after sbuf_finish(). I am not
 > willing to through all code using sbufs to check where it causes
 > problems. phk@ asserts that r222004 is correct.
 
 What is causing sbuf to have an error in the first place?  The size of
 flies in /proc are generally small and malloc(3) errors are rare.
 
 Thanks,
 matthew

From: Petr Salinger <Petr.Salinger@seznam.cz>
To: mdf@FreeBSD.org
Cc: Jaakko Heinonen <jh@FreeBSD.org>,
        =?ISO-8859-15?Q?Dag-Erling_Sm=F8rgrav?= <des@des.no>,
        Poul-Henning Kamp <phk@phk.freebsd.dk>, bug-followup@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Fri, 9 Dec 2011 17:18:00 +0100 (CET)

  <CAMBSHm_H95zv48t9x2Whxb-wP5wp36TNCeOY6tUX-vSVAsPbPQ@mail.gmail.com>
 User-Agent: Alpine 2.02 (LRH 1266 2009-07-14)
 MIME-Version: 1.0
 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed
 X-FELK-MailScanner-Information: 
 X-MailScanner-ID: pB9G4r01051652
 X-FELK-MailScanner: Found to be clean
 X-FELK-MailScanner-SpamCheck: not spam, SpamAssassin (not cached,
 	score=-1.12, required 6, BAYES_00 -1.90, FREEMAIL_FROM 0.00,
 	SPF_NEUTRAL 0.78)
 X-FELK-MailScanner-From: petr.salinger@seznam.cz
 X-FELK-MailScanner-To: bug-followup@freebsd.org, des@des.no, jh@freebsd.org,
 	mdf@freebsd.org, phk@phk.freebsd.dk
 X-FELK-MailScanner-Watermark: 1324051494.72495@1Eu3fJUhMt52tBWic+21fw
 X-Spam-Status: No
 
 >> As I wrote existing code depends on sbuf_len() to return the actual
 >> length regardless of the error status after sbuf_finish(). I am not
 >> willing to through all code using sbufs to check where it causes
 >> problems. phk@ asserts that r222004 is correct.
 >
 > What is causing sbuf to have an error in the first place?  The size of
 > flies in /proc are generally small and malloc(3) errors are rare.
 
 In this particular case, the userland wants to read first n bytes,
 the sbuf is allocated as fixed for n bytes.
 The first n bytes are generated and correctly stored in sbuf,
 for the rest bytes, there is no space in sbuf, but these bytes are not 
 needed later anyway.
 
 In stable-8,
 sbuf_data(sb) point to data, the sbuf_len(sb) returns number of stored 
 bytes.
 
 In stable-9,
 sbuf_data(sb) point to data, the sbuf_len(sb) returns -1.
 
 Petr

From: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>,
        Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
        mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Fri, 09 Dec 2011 16:08:12 +0000

 In message <20111209123616.GA32253@a91-153-116-96.elisa-laajakaista.fi>, Jaakko
  Heinonen writes:
 >On 2011-12-09, Dag-Erling Smørgrav wrote:
 
 >As I wrote existing code depends on sbuf_len() to return the actual
 >length regardless of the error status after sbuf_finish().
 
 What do you mean by "actual length" ?
 
 The length it would have if there hadn't been errors ?
 
 I don't object to that.
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk@FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>,
	Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Fri, 9 Dec 2011 18:23:18 +0200

 On 2011-12-09, Poul-Henning Kamp wrote:
 > >As I wrote existing code depends on sbuf_len() to return the actual
 > >length regardless of the error status after sbuf_finish().
 > 
 > What do you mean by "actual length" ?
 > 
 > The length it would have if there hadn't been errors ?
 
 No, I mean returning s->s_len instead of -1. s_len is the length of the
 string without the terminating NUL. s_len doesn't include the bytes that
 didn't fit to the buffer.
 
 -- 
 Jaakko

From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>,  Petr Salinger <Petr.Salinger@seznam.cz>,  bug-followup@FreeBSD.org,  mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Sat, 10 Dec 2011 02:13:56 +0100

 Jaakko Heinonen <jh@FreeBSD.org> writes:
 > Dag-Erling Sm=C3=B8rgrav wrote:
 > > What if the sbuf is in a state where asking for its length is
 > > meaningless?
 > Could you give an example about such state? Isn't the length first
 > initialized to zero and then increased only when byte(s) has been
 > successfully appended to the buffer? sbuf_len() has worked for
 > unfinished buffers since r71724.
 
 A fixed-length sbuf may overflow intentionally (as in pseudofs) or
 unintentionally; a dynamic sbuf may also overflow due to a memory
 allocation failure.  The first two cases are expected, but the third is
 not, and I am not sure the sbuf should be considered valid in such a
 case.
 
 DES
 --=20
 Dag-Erling Sm=C3=B8rgrav - des@des.no

From: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
        des@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Sat, 10 Dec 2011 15:15:56 +0000

 In message <20111207160834.GA2257@a91-153-116-96.elisa-laajakaista.fi>, Jaakko 
 Heinonen writes:
 
 >Could we just remove the error check from sbuf_len()? (patch below) I
 >have Cc'd more people.
 >
 >sbuf(9) manual page wrongly claims that sbuf_data() will return NULL if
 >the buffer has overflowed.
 
 Let me just back up to the beginning to make sure we're not headed
 into the weeds here:
 
 The idea behind sbufs is to have text-composition with a latching
 error handling, so that error checks only needs to be done once,
 and not after each and every *printf() &c. call.
 
 I agree with Dag-Erling that it is at least mistake to not have
 separate sbuf(9) and sbuf(3) pages, possibly also a mistake that
 they share the implementation.
 
 I cannot say that I very much like the "drain" stuff that was added,
 That just sticks out like a sore thumb and the way the drain function
 clutters up the explanation in the manual-page indicates that it
 is a mis-fit bolt on.
 
 Obviously sbuf_finish() should return the error status, and its
 return value SHALL be checked by applications, before the contents
 of the sbuf can be used.
 
 The argument relating to this bug is about what sbuf_len() and
 sbuf_data() should return for an error'ed sbuf.
 
 Given that the mandatory error-check of the sbuf_finish() call
 should prevent these two functions from being called in the first
 place, I'm tempted to say that their return values should be
 documented as undefined, and implemented to cause the maxium amount
 of havoc (ie: -1 and NULL).
 
 It can be argued, that sbuf_len(), like snprintf(3) should return
 how long the result would have been, had there been enough space
 and no trouble.
 
 This argument has merit but I'm not going to entertain it, until a
 credible usecase has been shown, because the main reason snprintf(3)
 does that, is to make it possible to implement what sbufs provide
 a more convenient API for.
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk@FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>,
	Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Sat, 10 Dec 2011 19:35:43 +0200

 On 2011-12-10, Dag-Erling Smørgrav wrote:
 > Jaakko Heinonen <jh@FreeBSD.org> writes:
 > > Could you give an example about such state? Isn't the length first
 > > initialized to zero and then increased only when byte(s) has been
 > > successfully appended to the buffer? sbuf_len() has worked for
 > > unfinished buffers since r71724.
 > 
 > A fixed-length sbuf may overflow intentionally (as in pseudofs) or
 > unintentionally; a dynamic sbuf may also overflow due to a memory
 > allocation failure.  The first two cases are expected, but the third is
 > not, and I am not sure the sbuf should be considered valid in such a
 > case.
 
 Thanks, I see your point. However, currently after a memory allocation
 failure, finishing the buffer is allowed and sbuf_data() will return the
 buffer. According to phk@ sbuf_finish() should finish any buffer.
 
 -- 
 Jaakko

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	des@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Sun, 11 Dec 2011 12:26:08 +0200

 On 2011-12-10, Poul-Henning Kamp wrote:
 > I agree with Dag-Erling that it is at least mistake to not have
 > separate sbuf(9) and sbuf(3) pages, possibly also a mistake that
 > they share the implementation.
 
 One problem is the different malloc() semantics. The kernel version uses
 M_WAITOK allocations while user space malloc(3) can fail.
 
 > Obviously sbuf_finish() should return the error status, and its
 > return value SHALL be checked by applications, before the contents
 > of the sbuf can be used.
 
 Only 21 of 133 calls I grepped through the FreeBSD source tree did check
 the return value. In practice SBUF_AUTOEXTEND buffers can't fail when
 the kernel version is used (due to M_WAITOK malloc).
 
 > The argument relating to this bug is about what sbuf_len() and
 > sbuf_data() should return for an error'ed sbuf.
 > 
 > Given that the mandatory error-check of the sbuf_finish() call
 > should prevent these two functions from being called in the first
 > place, I'm tempted to say that their return values should be
 > documented as undefined, and implemented to cause the maxium amount
 > of havoc (ie: -1 and NULL).
 
 -- 
 Jaakko

From: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
To: Jaakko Heinonen <jh@FreeBSD.org>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
        des@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Sun, 11 Dec 2011 13:41:03 +0000

 In message <20111211102608.GA2266@a91-153-116-96.elisa-laajakaista.fi>, Jaakko 
 Heinonen writes:
 >On 2011-12-10, Poul-Henning Kamp wrote:
 
 >One problem is the different malloc() semantics. The kernel version uses
 >M_WAITOK allocations while user space malloc(3) can fail.
 
 Yes, that's Dag-Erlings and my point:  The semantics are too different.
 
 >Only 21 of 133 calls I grepped through the FreeBSD source tree did check
 >the return value [of sbuf_finish()]
 
 How many of them checked sbuf_error() instead ?
 
 And seriously: how long would it take to fix 112 calls ?
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk@FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.

From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To: "Poul-Henning Kamp" <phk@phk.freebsd.dk>
Cc: Jaakko Heinonen <jh@FreeBSD.org>,  Petr Salinger <Petr.Salinger@seznam.cz>,  bug-followup@FreeBSD.org,  mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs and procfs.
Date: Sun, 11 Dec 2011 18:28:59 +0100

 "Poul-Henning Kamp" <phk@phk.freebsd.dk> writes:
 > Jaakko Heinonen <jh@FreeBSD.org> writes:
 > > One problem is the different malloc() semantics. The kernel version uses
 > > M_WAITOK allocations while user space malloc(3) can fail.
 > Yes, that's Dag-Erlings and my point:  The semantics are too different.
 
 There is another, more important issue.
 
 Synthetic (pseudofs-based) filesystems use sbufs extensively.  If a
 program seeks to a position far into a file in such a filesystem and
 then reads some data from it, we have to allocate an sbuf large enough
 to contain the entire file *up to and including* the data the program
 actually asked for, unless the underlying filler function can somehow
 skip the part the program didn't ask for (or a large part of it), which
 is not always possible.  This basically allows the userland to trick
 pseudofs into allocating and dirtying arbitrary amounts of kernel
 memory, which is obviously not a good thing.
 
 The way sbuf_*printf() was originally implemented, it would have been
 trivial to extend the API to have it allocate no more memory than
 required to hold the amount of data the program requested, and discard
 the first N bytes written to it.  This is not possible with the current
 code: the userland *printf() implementation is too different from the
 kernel *printf() implementation, so they had to tear sbuf_*printf()
 apart.
 
 So what did we do instead?  We added checks in pseudofs to prevent the
 scenario I described.  This effectively sets an arbitrary upper limit on
 the size of sbuf-backed files in pseudofs-based filesystems.  I was very
 unhappy about it, but the only way around it would have been to hide
 this functionality behind ifdefs so it was only available in the kernel,
 and turn the sbuf implementation into an even bigger mess than it
 already is - a mess which is entirely ascribed to the boneheaded
 decision to use the same code in userland as in the kernel.
 
 Before you point out that this *can* in fact be implemented using
 sbuf_drain(): sbuf_drain() has no place in the sbuf API, and should be
 removed.  It breaks the sbuf semantics by a) providing access to the
 contents of an sbuf at a time when the sbuf is, by definition, in an
 inconsistent state, and b) emptying the sbuf at irregular intervals and
 when sbuf_finish() is called, preventing reuse of its contents.  It's
 bad enough that I had to extend sbufs to support binary data; let's
 please not compound that mistake by deviating even further from their
 original purpose.
 
 DES
 --=20
 Dag-Erling Sm=C3=B8rgrav - des@des.no

From: Petr Salinger <Petr.Salinger@seznam.cz>
To: =?ISO-8859-15?Q?Dag-Erling_Sm=F8rgrav?= <des@des.no>
Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>, Jaakko Heinonen <jh@FreeBSD.org>,
        bug-followup@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Tue, 13 Dec 2011 09:13:17 +0100 (CET)

 >>> One problem is the different malloc() semantics. The kernel version uses
 >>> M_WAITOK allocations while user space malloc(3) can fail.
 >> Yes, that's Dag-Erlings and my point:  The semantics are too different.
 >
 > There is another, more important issue.
 
 And yet another point of view.
 
 Will be this regression corrected for 9.0 release ?
 
 Previously (in stable-8), the sbuf_finish() cleared the overflow error.
 It used to return void, and as noted previously,
 only 21 of 133 calls check return value of sbuf_finish(),
 i.e. only 1/6 have been migrated to new API semantics.
 
 What about restore clearing of error during sbuf_finish() for stable-9
 and do the right thing in HEAD ?
 
 Petr
 

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Petr Salinger <Petr.Salinger@seznam.cz>, bug-followup@FreeBSD.org,
	des@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Tue, 13 Dec 2011 17:13:36 +0200

 On 2011-12-11, Poul-Henning Kamp wrote:
 > >Only 21 of 133 calls I grepped through the FreeBSD source tree did check
 > >the return value [of sbuf_finish()]
 > 
 > How many of them checked sbuf_error() instead ?
 
 I grepped 8 sbuf_error() calls. I'd say that 2 of them were used
 correctly instead of checking the return value of sbuf_finish().
 
 > And seriously: how long would it take to fix 112 calls ?
 
 Majority of them seem to be autoextend buffers which are "OK" in kernel
 space. Some of the remaining are easy to fix but then there are harder
 ones like the pseudofs one. It looks like that some applications call
 sbuf_finish() from functions which are not expected to fail.
 
 -- 
 Jaakko

From: Jaakko Heinonen <jh@FreeBSD.org>
To: Petr Salinger <Petr.Salinger@seznam.cz>,
	Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc: Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>,
	bug-followup@FreeBSD.org, mdf@FreeBSD.org
Subject: Re: kern/163076: It is not possible to read in chunks from linprocfs
 and procfs.
Date: Fri, 16 Dec 2011 10:19:35 +0200

 On 2011-12-13, Petr Salinger wrote:
 > Will be this regression corrected for 9.0 release ?
 
 AFAIK it's too late to get such patch approved for 9.0.
 
 > Previously (in stable-8), the sbuf_finish() cleared the overflow error.
 > It used to return void, and as noted previously,
 > only 21 of 133 calls check return value of sbuf_finish(),
 > i.e. only 1/6 have been migrated to new API semantics.
 > 
 > What about restore clearing of error during sbuf_finish() for stable-9
 > and do the right thing in HEAD ?
 
 If nobody can suggest a better alternative, I am inclined to say that
 I'd like to see the change reverted until someone volunteers to fix
 callers.
 
 I don't say that r222004 is incorrect but the fact is that sbuf_finish()
 didn't return an error for a long time (almost 10 years) and when the
 API was changed it looks like API consumers weren't changed along.
 
 I am willing to help but currently I have no idea how to fix pseudofs
 with the new API semantics. I don't like the patch posted because it
 allocates an excessively large buffer on every read.
 
 -- 
 Jaakko
Responsible-Changed-From-To: freebsd-bugs->jh 
Responsible-Changed-By: jh 
Responsible-Changed-When: Fri Jan 6 09:25:17 UTC 2012 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=163076 
State-Changed-From-To: open->patched 
State-Changed-By: jh 
State-Changed-When: Fri Jan 6 10:18:52 UTC 2012 
State-Changed-Why:  
Patched in head (r229694). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=163076 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/163076: commit references a PR
Date: Fri,  6 Jan 2012 10:13:11 +0000 (UTC)

 Author: jh
 Date: Fri Jan  6 10:12:59 2012
 New Revision: 229694
 URL: http://svn.freebsd.org/changeset/base/229694
 
 Log:
   r222004 changed sbuf_finish() to not clear the buffer error status. As a
   consequence sbuf_len() will return -1 for buffers which had the error
   status set prior to sbuf_finish() call. This causes a problem in
   pfs_read() which purposely uses a fixed size sbuf to discard bytes which
   are not needed to fulfill the read request.
   
   Work around the problem by using the full buffer length when
   sbuf_finish() indicates an overflow. An overflowed sbuf with fixed size
   is always full.
   
   PR:		kern/163076
   Approved by:	des
   MFC after:	2 weeks
 
 Modified:
   head/sys/fs/pseudofs/pseudofs_vnops.c
 
 Modified: head/sys/fs/pseudofs/pseudofs_vnops.c
 ==============================================================================
 --- head/sys/fs/pseudofs/pseudofs_vnops.c	Fri Jan  6 09:21:40 2012	(r229693)
 +++ head/sys/fs/pseudofs/pseudofs_vnops.c	Fri Jan  6 10:12:59 2012	(r229694)
 @@ -630,14 +630,14 @@ pfs_read(struct vop_read_args *va)
  	if (uio->uio_offset < 0 || uio->uio_resid < 0 ||
  	    (offset = uio->uio_offset) != uio->uio_offset ||
  	    (resid = uio->uio_resid) != uio->uio_resid ||
 -	    (buflen = offset + resid + 1) < offset || buflen > INT_MAX) {
 +	    (buflen = offset + resid) < offset || buflen >= INT_MAX) {
  		error = EINVAL;
  		goto ret;
  	}
 -	if (buflen > MAXPHYS + 1)
 -		buflen = MAXPHYS + 1;
 +	if (buflen > MAXPHYS)
 +		buflen = MAXPHYS;
  
 -	sb = sbuf_new(sb, NULL, buflen, 0);
 +	sb = sbuf_new(sb, NULL, buflen + 1, 0);
  	if (sb == NULL) {
  		error = EIO;
  		goto ret;
 @@ -650,8 +650,14 @@ pfs_read(struct vop_read_args *va)
  		goto ret;
  	}
  
 -	sbuf_finish(sb);
 -	error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
 +	/*
 +	 * XXX: If the buffer overflowed, sbuf_len() will not return
 +	 * the data length. Then just use the full length because an
 +	 * overflowed sbuf must be full.
 +	 */
 +	if (sbuf_finish(sb) == 0)
 +		buflen = sbuf_len(sb);
 +	error = uiomove_frombuf(sbuf_data(sb), buflen, uio);
  	sbuf_delete(sb);
  ret:
  	vn_lock(vn, locked | LK_RETRY);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/163076: commit references a PR
Date: Mon, 23 Jan 2012 16:28:44 +0000 (UTC)

 Author: jh
 Date: Mon Jan 23 16:28:35 2012
 New Revision: 230485
 URL: http://svn.freebsd.org/changeset/base/230485
 
 Log:
   MFC r229694:
   
   r222004 changed sbuf_finish() to not clear the buffer error status. As a
   consequence sbuf_len() will return -1 for buffers which had the error
   status set prior to sbuf_finish() call. This causes a problem in
   pfs_read() which purposely uses a fixed size sbuf to discard bytes which
   are not needed to fulfill the read request.
   
   Work around the problem by using the full buffer length when
   sbuf_finish() indicates an overflow. An overflowed sbuf with fixed size
   is always full.
   
   PR:		kern/163076
 
 Modified:
   stable/9/sys/fs/pseudofs/pseudofs_vnops.c
 Directory Properties:
   stable/9/sys/   (props changed)
   stable/9/sys/amd64/include/xen/   (props changed)
   stable/9/sys/boot/   (props changed)
   stable/9/sys/boot/i386/efi/   (props changed)
   stable/9/sys/boot/ia64/efi/   (props changed)
   stable/9/sys/boot/ia64/ski/   (props changed)
   stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
   stable/9/sys/boot/powerpc/ofw/   (props changed)
   stable/9/sys/cddl/contrib/opensolaris/   (props changed)
   stable/9/sys/conf/   (props changed)
   stable/9/sys/contrib/dev/acpica/   (props changed)
   stable/9/sys/contrib/octeon-sdk/   (props changed)
   stable/9/sys/contrib/pf/   (props changed)
   stable/9/sys/contrib/x86emu/   (props changed)
 
 Modified: stable/9/sys/fs/pseudofs/pseudofs_vnops.c
 ==============================================================================
 --- stable/9/sys/fs/pseudofs/pseudofs_vnops.c	Mon Jan 23 16:17:54 2012	(r230484)
 +++ stable/9/sys/fs/pseudofs/pseudofs_vnops.c	Mon Jan 23 16:28:35 2012	(r230485)
 @@ -630,14 +630,14 @@ pfs_read(struct vop_read_args *va)
  	if (uio->uio_offset < 0 || uio->uio_resid < 0 ||
  	    (offset = uio->uio_offset) != uio->uio_offset ||
  	    (resid = uio->uio_resid) != uio->uio_resid ||
 -	    (buflen = offset + resid + 1) < offset || buflen > INT_MAX) {
 +	    (buflen = offset + resid) < offset || buflen >= INT_MAX) {
  		error = EINVAL;
  		goto ret;
  	}
 -	if (buflen > MAXPHYS + 1)
 -		buflen = MAXPHYS + 1;
 +	if (buflen > MAXPHYS)
 +		buflen = MAXPHYS;
  
 -	sb = sbuf_new(sb, NULL, buflen, 0);
 +	sb = sbuf_new(sb, NULL, buflen + 1, 0);
  	if (sb == NULL) {
  		error = EIO;
  		goto ret;
 @@ -650,8 +650,14 @@ pfs_read(struct vop_read_args *va)
  		goto ret;
  	}
  
 -	sbuf_finish(sb);
 -	error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
 +	/*
 +	 * XXX: If the buffer overflowed, sbuf_len() will not return
 +	 * the data length. Then just use the full length because an
 +	 * overflowed sbuf must be full.
 +	 */
 +	if (sbuf_finish(sb) == 0)
 +		buflen = sbuf_len(sb);
 +	error = uiomove_frombuf(sbuf_data(sb), buflen, uio);
  	sbuf_delete(sb);
  ret:
  	vn_lock(vn, locked | LK_RETRY);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jh 
State-Changed-When: Mon Jan 23 16:37:55 UTC 2012 
State-Changed-Why:  
Fixed in head and stable/9. 

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