bug-gnulib
[Top][All Lists]
Advanced

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

Re: af_alg: Fix state of stream after sendfile() succeeds


From: Pádraig Brady
Subject: Re: af_alg: Fix state of stream after sendfile() succeeds
Date: Sun, 24 Jun 2018 18:36:01 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0

On 24/06/18 17:58, Bruno Haible wrote:
> afalg_stream is documented as "Read from the current position to the
> end of STREAM." However, the current behaviour after sendfile() succeeds
> is that the stream is in an unusable state (except for fclose): It still
> has buffers allocated, but the underlying file descriptors is at a
> different position that what would be consistent with the buffers.
> You can see that by doing a getc() call afterwards.
> 
> Should we change af_alg.h, md5.h, sha1.h etc. to all say "The only valid
> operation on STREAM afterwards is to close it."? I don't think this would
> be good: it would be a restriction that could too easily trigger bugs in
> the calling programs.
> 
> So it's better to make sure STREAM is in a consistent state afterwards.
> 
> This patch does it. In particular, it restores the fflush() call that Paul
> had eliminated on 2018-05-10.
> 
> 
> 2018-06-24  Bruno Haible  <address@hidden>
> 
>       af_alg: Fix state of stream after sendfile() succeeds.
>       * lib/af_alg.c (afalg_stream): Invoke fflush and lseek, to ensure that
>       the stream is correctly positioned afterwards.
>       * modules/crypto/af_alg (Depends-on): Add fflush.
>       * tests/test-digest.h (test_digest_on_files): Verify that after the
>       operation the stream is positioned at end of file.
> 
> diff --git a/lib/af_alg.c b/lib/af_alg.c
> index 555eb2b..2753ab9 100644
> --- a/lib/af_alg.c
> +++ b/lib/af_alg.c
> @@ -113,18 +113,47 @@ afalg_stream (FILE *stream, const char *alg,
>    int fd = fileno (stream);
>    int result;
>    struct stat st;
> -  off_t nseek = 0; /* Number of bytes to seek (backwards) in case of error.  
> */
>    off_t off = ftello (stream);
>    if (0 <= off && fstat (fd, &st) == 0
>        && (S_ISREG (st.st_mode) || S_TYPEISSHM (&st) || S_TYPEISTMO (&st))
>        && off < st.st_size && st.st_size - off < SYS_BUFSIZE_MAX)
>      {
> -      off_t nbytes = st.st_size - off;
> -      result = sendfile (ofd, fd, &off, nbytes) == nbytes ? 0 : 
> -EAFNOSUPPORT;
> +      /* Make sure the offset of fileno (stream) reflects how many bytes
> +         have been read from stream before this function got invoked.
> +         Note: fflush on an input stream after ungetc does not work as 
> expected
> +         on some platforms.  Therefore this situation is not supported here. 
>  */
> +      if (fflush (stream))
> +        result = -EIO;

Might it be valid to return -EAFNOSUPPORT here instead,
so that the stream was processed with the non af_alg loop?

The fflush() makes sense to drop any stream buffers which
won't be used and will be invalid anyway
when we reset the file offset with lseek.

> +      else
> +        {
> +          off_t nbytes = st.st_size - off;
> +          if (sendfile (ofd, fd, &off, nbytes) == nbytes)
> +            {
> +              if (read (ofd, resblock, hashlen) == hashlen)
> +                {
> +                  /* The input buffers of stream are no longer valid.  */
> +                  if (lseek (fd, off, SEEK_SET) != (off_t)-1)
> +                    result = 0;

Should we be using fseek (as well) to set the stream position accordingly?

thanks,
Pádraig



reply via email to

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