Guard against accidental io.EOFs

This commit is contained in:
Cassondra Foesch 2021-04-13 10:10:27 +00:00
parent bc27e0c607
commit aee72c4006
2 changed files with 21 additions and 2 deletions

View File

@ -944,7 +944,7 @@ func (f *File) Read(b []byte) (int, error) {
// readChunkAt attempts to read the whole entire length of the buffer from the file starting at the offset. // readChunkAt attempts to read the whole entire length of the buffer from the file starting at the offset.
// It will continue progressively reading into the buffer until it fills the whole buffer, or an error occurs. // It will continue progressively reading into the buffer until it fills the whole buffer, or an error occurs.
func (f *File) readChunkAt(ch chan result, b []byte, off int64) (n int, err error) { func (f *File) readChunkAt(ch chan result, b []byte, off int64) (n int, err error) {
for err == nil && n < len(b) { for n < len(b) {
id := f.c.nextID() id := f.c.nextID()
typ, data, err := f.c.sendPacket(ch, &sshFxpReadPacket{ typ, data, err := f.c.sendPacket(ch, &sshFxpReadPacket{
ID: id, ID: id,
@ -953,6 +953,12 @@ func (f *File) readChunkAt(ch chan result, b []byte, off int64) (n int, err erro
Len: uint32(len(b) - n), Len: uint32(len(b) - n),
}) })
if err != nil { if err != nil {
if errors.Is(err, io.EOF) {
// sendPacket should never return io.EOF.
// Proper client EOFs are always from SSH_FX_EOF packets handled below.
return n, ErrSSHFxConnectionLost
}
return n, err return n, err
} }
@ -974,7 +980,7 @@ func (f *File) readChunkAt(ch chan result, b []byte, off int64) (n int, err erro
} }
} }
return return len(b), nil
} }
func (f *File) readAtSequential(b []byte, off int64) (read int, err error) { func (f *File) readAtSequential(b []byte, off int64) (read int, err error) {
@ -1782,7 +1788,13 @@ func normaliseError(err error) error {
default: default:
return err return err
} }
default: default:
// io.EOF should only ever come from an SSH_FX_EOF packet as handled above.
if errors.Is(err, io.EOF) {
return ErrSSHFxConnectionLost
}
return err return err
} }
} }

View File

@ -142,6 +142,13 @@ func (c *clientConn) sendPacket(ch chan result, p idmarshaler) (byte, []byte, er
c.dispatchRequest(ch, p) c.dispatchRequest(ch, p)
s := <-ch s := <-ch
if errors.Is(s.err, io.EOF) {
// This function should never return io.EOF.
// Proper client EOFs are always from SSH_FX_EOF packets.
return s.typ, s.data, ErrSSHFxConnectionLost
}
return s.typ, s.data, s.err return s.typ, s.data, s.err
} }