[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: and _PC_PIPE_BUF..

From: Niels Möller
Subject: Re: and _PC_PIPE_BUF..
Date: 24 Apr 2003 10:06:05 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Robert Millan <> writes:

> i'd better show an example, this is fixed code from gs. does it seem
> correct to you? (considering the file descriptor is expected to be
> a socket, if pipe_buf is -1 then something weird happened)

> /* Get packet from the server. */
> private int hpijs_get_pk(PK * pk, int fd)
> {
> #ifdef PIPE_BUF
>    return read(fd, pk, PIPE_BUF - 1);
> #else
>    long int pipe_buf = fpathconf(fd, _PC_PIPE_BUF);
>    if (pipe_buf == -1)
>      /* no pipe_buf, so we fail */
>      return -1;
>    else
>      return read(fd, pk, pipe_buf - 1);
> #endif
> }

To me, the code looks utterly broken. What is the allocated size for
pk? If PIPE_BUF is larger than that size, and the other end of the
pipe writes lots of data, you will get a buffer overflow, and
depending on context, that can turn out to be a security hole big
enough to drive a truck through it. The size argument to read must
*never* be larger than the size of the buffer passed to read.

Furthermore, I'm not sure what the code tries to use PIPE_BUF for. The
only use of PIPE_BUF I have seen is when *writing* to a pipe, where
you have a single process reading the pipe and multiple processes
writing to it. Using PIPE_BUF when reading sounds like something that
might make sense if you have a single writer and multiple readers on a
pipe. Does gs do that? Such pipe usage seems pretty obscure to me.

I would have expected some code like

  return read(fd, pk, sizeof(*pk))

or, if it really depends on PIPE_BUF semantics,

  long int pipe_buf;
  pipe_buf = PIPE_BUF;
  pipe_buf = fpathconf(fd, _PC_PIPE_BUF);
  if (pipe_buf < sizeof(*pk))
    /* pipe_buf too small (or not existing), so we fail */
    return -1;
    return read(fd, pk, sizeof(*pk))

And at last, the "-1" part of "PIPE_BUF - 1" also seems strange. The
special PIPE_BUF semantics happen for request of size up to *or equal*
to PIPE_BUF. Quoting the glibc manual:

:    Reading or writing pipe data is "atomic" if the size of data written
: is not greater than `PIPE_BUF'.  This means that the data transfer
: seems to be an instantaneous unit, in that nothing else in the system
: can observe a state in which it is partially complete.  Atomic I/O may
: not begin right away (it may need to wait for buffer space or for data),
: but once it does begin it finishes immediately.

Sorry if this isn't of much help, but I don't understand how that code
is supposed to work.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]