summaryrefslogtreecommitdiffhomepage
path: root/pkg/buffer
diff options
context:
space:
mode:
authorAyush Ranjan <ayushranjan@google.com>2021-08-11 20:15:34 -0700
committergVisor bot <gvisor-bot@google.com>2021-08-11 20:18:19 -0700
commit6d0b40b1d159a96ba96a26f8095b9b94f3eb2dc0 (patch)
tree2383ff01af68fbb1ea7b904ff7db27db7e91325d /pkg/buffer
parent4249ba85068e7a398187af6c87daca2172ed25e5 (diff)
[op] Make PacketBuffer Clone() do a deeper copy.
Earlier PacketBuffer.Clone() would do a shallow top level copy of the packet buffer - which involved sharing the *buffer.Buffer between packets. Reading or writing to the buffer in one packet would impact the other. This caused modifications in one packet to affect the other's pkt.Views() which is not desired. Change the clone to do a deeper copy of the underlying buffer list and buffer pointers. The payload buffers (which are immutable) are still shared. This change makes the Clone() operation more expensive as we now need to allocate the entire buffer list. Added unit test to test integrity of packet data after cloning. Reported-by: syzbot+7ffff9a82a227b8f2e31@syzkaller.appspotmail.com Reported-by: syzbot+7d241de0d9072b2b6075@syzkaller.appspotmail.com Reported-by: syzbot+212bc4d75802fa461521@syzkaller.appspotmail.com PiperOrigin-RevId: 390277713
Diffstat (limited to 'pkg/buffer')
-rw-r--r--pkg/buffer/view.go14
1 files changed, 14 insertions, 0 deletions
diff --git a/pkg/buffer/view.go b/pkg/buffer/view.go
index 7bcfcd543..a4610f977 100644
--- a/pkg/buffer/view.go
+++ b/pkg/buffer/view.go
@@ -378,6 +378,20 @@ func (v *View) Copy() (other View) {
return
}
+// Clone makes a more shallow copy compared to Copy. The underlying payload
+// slice (buffer.data) is shared but the buffers themselves are copied.
+func (v *View) Clone() *View {
+ other := &View{
+ size: v.size,
+ }
+ for buf := v.data.Front(); buf != nil; buf = buf.Next() {
+ newBuf := other.pool.getNoInit()
+ *newBuf = *buf
+ other.data.PushBack(newBuf)
+ }
+ return other
+}
+
// Apply applies the given function across all valid data.
func (v *View) Apply(fn func([]byte)) {
for buf := v.data.Front(); buf != nil; buf = buf.Next() {