Skip to content

Commit

Permalink
p9: avoid sending a partial dirent when the Rreaddir response exceeds…
Browse files Browse the repository at this point in the history
… message limit

Ported from gVisor. When the Rreaddir response is too large to fit in
the 9P response message, the last dirent entry may get truncated. This
causes decode errors on 9P clients with more stringent checks such the
Linux kernel. This change sets the payload length to the exact number of
bytes used to encode all directory entries.

Signed-off-by: Chris Koch <[email protected]>
  • Loading branch information
hugelgupf committed Aug 13, 2020
1 parent 2be4390 commit f7b8ad0
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 7 deletions.
12 changes: 6 additions & 6 deletions p9/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -1593,17 +1593,17 @@ func (r *rreaddir) decode(b *buffer) {
// encode implements encoder.encode.
func (r *rreaddir) encode(b *buffer) {
entriesBuf := buffer{}
payloadSize := 0
for _, d := range r.Entries {
prev := len(entriesBuf.data)
d.encode(&entriesBuf)
if len(entriesBuf.data) >= int(r.Count) {
entriesBuf.data = entriesBuf.data[:prev]
if len(entriesBuf.data) > int(r.Count) {
break
}
payloadSize = len(entriesBuf.data)
}
r.Count = uint32(len(entriesBuf.data))
r.payload = entriesBuf.data
b.Write32(uint32(r.Count))
r.Count = uint32(payloadSize)
r.payload = entriesBuf.data[:payloadSize]
b.Write32(r.Count)
}

// typ implements message.typ.
Expand Down
2 changes: 1 addition & 1 deletion p9/messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func TestEncodeDecode(t *testing.T) {
},
&rreaddir{
// Count must be sufficient to encode a dirent.
Count: 0x40,
Count: 0x1a,
Entries: []Dirent{{QID: QID{Type: 2}}},
},
&tfsync{
Expand Down

0 comments on commit f7b8ad0

Please sign in to comment.