pipe() resource exhaustion
Konstantin Belousov
kostikbel at gmail.com
Tue Apr 8 13:24:51 UTC 2014
On Tue, Apr 08, 2014 at 03:07:27PM +0200, Mateusz Guzik wrote:
> On Tue, Apr 08, 2014 at 03:38:27PM +0300, Konstantin Belousov wrote:
> > On Tue, Apr 08, 2014 at 02:12:22PM +0200, Mateusz Guzik wrote:
> > > That said, supporting a reserve for this one sounds like a good idea and
> > > not that hard to implement - one can either play with atomics and double
> > > check or just place a mutex-protected check in pipespace_new (before
> > > vm_map_find).
> > >
> > ...
> >
> > I think more reasonable behaviour there is to just fall back to the
> > buffered pipe if the direct buffer allocation fails. Look at the
> > pipespace_new() calls in the pipe_create(); probably ignoring the error
> > would do the trick.
>
> Yeah, should have checked the caller.
>
> Interesting though how the error was made fatal in thiscase.
>
> Anyhow, the following hack following your suggestion indeed makes the
> issue go away for me:
>
> diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
> index 6ba52e3..5930cf2 100644
> --- a/sys/kern/sys_pipe.c
> +++ b/sys/kern/sys_pipe.c
> @@ -647,19 +647,21 @@ pipe_create(pipe, backing)
> struct pipe *pipe;
> int backing;
> {
> - int error;
>
> if (backing) {
> + /*
> + * Note that these functions can fail, but we ignore
> + * the error as it is not fatal and could be provoked
> + * by users.
> + */
> if (amountpipekva > maxpipekva / 2)
> - error = pipespace_new(pipe, SMALL_PIPE_SIZE);
> + (void)pipespace_new(pipe, SMALL_PIPE_SIZE);
> else
> - error = pipespace_new(pipe, PIPE_SIZE);
> - } else {
> - /* If we're not backing this pipe, no need to do anything. */
> - error = 0;
> + (void)pipespace_new(pipe, PIPE_SIZE);
> }
> +
> pipe->pipe_ino = -1;
> - return (error);
> + return (0);
> }
>
Yes, this looks right. I think it does not make sense to continue
returning an error from the pipe_create() after the patch. The change
would become bigger, but the code for pipe_create() and pipe_paircreate
collapse. It seems that pipe_paircreate() can be changed to return void
as well, but the benefits would be smaller.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20140408/bb74591a/attachment.sig>
More information about the freebsd-hackers
mailing list