gnu-arch-users
[Top][All Lists]
Advanced

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

Re: [Gnu-arch-users] [BUG] Something fishy in vfdbuf_write


From: Bug Goo
Subject: Re: [Gnu-arch-users] [BUG] Something fishy in vfdbuf_write
Date: Sat, 31 Jul 2004 21:50:03 +0000

Created as bug 176

On Wed Jul 28 02:27:35 2004, Andrew Suffield wrote:

[Your message is attached]
This is based on a preliminary examination of a bug via IRC.

Not entirely sure how much of this analysis is right, but certainly
there's something wrong in vfdbuf_write(). It can leave the buffer in
a state such that it is a write-only pipe, and fd_offset !=
buffer_offset, which fails an invariant, as best I can tell.

      while (count > bufs.vfd[fd].bufsize)
        {
          ssize_t wrote;
          wrote = bufs.vfd[fd].sub_handler.vtable->write (errn,
                                                      fd,
                                                      buf,
                                                      bufs.vfd[fd].bufsize,
                                                      
bufs.vfd[fd].sub_handler.closure);
          if (wrote < 0)
            return -1;

I believe this is the broken code path. When we exit here the buffer is 
inconsistant.

          bufs.vfd[fd].fd_offset += wrote;

That'll be how they get inconsistent. Presumably we just did a short
write. I know that the next path around the loop returns EAGAIN.

          buf += wrote;
          count -= wrote;
          if (wrote < bufs.vfd[fd].bufsize)
            {
              check_buffer_invariants (fd);
              return orig_count - count;
            }
        }
      mem_move (bufs.vfd[fd].buf, buf, count);
      bufs.vfd[fd].buffer_offset = bufs.vfd[fd].fd_offset;

Here's the line that we should have run before returning and didn't.

      bufs.vfd[fd].read_write_pos = count;
      bufs.vfd[fd].buffered = count;
      check_buffer_invariants (fd);
      return orig_count;


It's far too late at night for me to chase this further or guess at a fix.

On a related note, panic() cheerfully assumes that write() to stderr
does not fail with EAGAIN/EINTR. That means we just lost the message
telling us which invariant failed. That's probably not a good idea.

-- 
  .''`.  ** Debian GNU/Linux ** | Andrew Suffield
 : :' :  http://www.debian.org/ |
 `. `'                          |
   `-             -><-          |

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Gnu-arch-users mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/gnu-arch-users

GNU arch home page:
http://savannah.gnu.org/projects/gnu-arch/

reply via email to

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