[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnu-arch-users] [BUG] Something fishy in vfdbuf_write
From: |
Andrew Suffield |
Subject: |
[Gnu-arch-users] [BUG] Something fishy in vfdbuf_write |
Date: |
Wed, 28 Jul 2004 03:26:47 +0100 |
User-agent: |
Mutt/1.5.6+20040523i |
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/ |
`. `' |
`- -><- |
signature.asc
Description: Digital signature
- [Gnu-arch-users] [BUG] Something fishy in vfdbuf_write,
Andrew Suffield <=