mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Make {Un}Marshal{Bytes/Unsafe} return remaining buffer.
Change marshal.Marshallable method signatures to return the remaining buffer. This makes it easier to implement these method manually. Without this, we would have to manually do buffer shifting which is error prone. tools/go_marshal/test:benchmark test does not show change in performance. Additionally fixed some marshalling bugs in fsimpl/fuse. Updated multiple callpoints to get rid of redundant slice indexing work and simplified code using this new signature. Updates #6450 PiperOrigin-RevId: 407857019
This commit is contained in:
+60
-51
@@ -352,6 +352,22 @@ type FUSEEntryOut struct {
|
||||
Attr FUSEAttr
|
||||
}
|
||||
|
||||
// CString represents a null terminated string which can be marshalled.
|
||||
type CString string
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (s *CString) MarshalBytes(buf []byte) []byte {
|
||||
copy(buf, *s)
|
||||
buf[len(*s)] = 0 // null char
|
||||
return buf[s.SizeBytes():]
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (s *CString) SizeBytes() int {
|
||||
// 1 extra byte for null-terminated string.
|
||||
return len(*s) + 1
|
||||
}
|
||||
|
||||
// FUSELookupIn is the request sent by the kernel to the daemon
|
||||
// to look up a file name.
|
||||
//
|
||||
@@ -360,18 +376,17 @@ type FUSELookupIn struct {
|
||||
marshal.StubMarshallable
|
||||
|
||||
// Name is a file name to be looked up.
|
||||
Name string
|
||||
Name CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.name to the dst buffer.
|
||||
func (r *FUSELookupIn) MarshalBytes(buf []byte) {
|
||||
copy(buf, r.Name)
|
||||
func (r *FUSELookupIn) MarshalBytes(buf []byte) []byte {
|
||||
return r.Name.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSELookupIn.
|
||||
// 1 extra byte for null-terminated string.
|
||||
func (r *FUSELookupIn) SizeBytes() int {
|
||||
return len(r.Name) + 1
|
||||
return r.Name.SizeBytes()
|
||||
}
|
||||
|
||||
// MAX_NON_LFS indicates the maximum offset without large file support.
|
||||
@@ -530,19 +545,18 @@ type FUSECreateIn struct {
|
||||
CreateMeta FUSECreateMeta
|
||||
|
||||
// Name is the name of the node to create.
|
||||
Name string
|
||||
Name CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.CreateMeta and r.Name to the dst buffer.
|
||||
func (r *FUSECreateIn) MarshalBytes(buf []byte) {
|
||||
r.CreateMeta.MarshalBytes(buf[:r.CreateMeta.SizeBytes()])
|
||||
copy(buf[r.CreateMeta.SizeBytes():], r.Name)
|
||||
func (r *FUSECreateIn) MarshalBytes(buf []byte) []byte {
|
||||
buf = r.CreateMeta.MarshalBytes(buf)
|
||||
return r.Name.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSECreateIn.
|
||||
// 1 extra byte for null-terminated string.
|
||||
func (r *FUSECreateIn) SizeBytes() int {
|
||||
return r.CreateMeta.SizeBytes() + len(r.Name) + 1
|
||||
return r.CreateMeta.SizeBytes() + r.Name.SizeBytes()
|
||||
}
|
||||
|
||||
// FUSEMknodMeta contains all the static fields of FUSEMknodIn,
|
||||
@@ -573,19 +587,18 @@ type FUSEMknodIn struct {
|
||||
MknodMeta FUSEMknodMeta
|
||||
|
||||
// Name is the name of the node to create.
|
||||
Name string
|
||||
Name CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.MknodMeta and r.Name to the dst buffer.
|
||||
func (r *FUSEMknodIn) MarshalBytes(buf []byte) {
|
||||
r.MknodMeta.MarshalBytes(buf[:r.MknodMeta.SizeBytes()])
|
||||
copy(buf[r.MknodMeta.SizeBytes():], r.Name)
|
||||
func (r *FUSEMknodIn) MarshalBytes(buf []byte) []byte {
|
||||
buf = r.MknodMeta.MarshalBytes(buf)
|
||||
return r.Name.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSEMknodIn.
|
||||
// 1 extra byte for null-terminated string.
|
||||
func (r *FUSEMknodIn) SizeBytes() int {
|
||||
return r.MknodMeta.SizeBytes() + len(r.Name) + 1
|
||||
return r.MknodMeta.SizeBytes() + r.Name.SizeBytes()
|
||||
}
|
||||
|
||||
// FUSESymLinkIn is the request sent by the kernel to the daemon,
|
||||
@@ -596,30 +609,30 @@ type FUSESymLinkIn struct {
|
||||
marshal.StubMarshallable
|
||||
|
||||
// Name of symlink to create.
|
||||
Name string
|
||||
Name CString
|
||||
|
||||
// Target of the symlink.
|
||||
Target string
|
||||
Target CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.Name and r.Target to the dst buffer.
|
||||
// Left null-termination at end of r.Name and r.Target.
|
||||
func (r *FUSESymLinkIn) MarshalBytes(buf []byte) {
|
||||
copy(buf, r.Name)
|
||||
copy(buf[len(r.Name)+1:], r.Target)
|
||||
func (r *FUSESymLinkIn) MarshalBytes(buf []byte) []byte {
|
||||
buf = r.Name.MarshalBytes(buf)
|
||||
return r.Target.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSESymLinkIn.
|
||||
// 2 extra bytes for null-terminated string.
|
||||
func (r *FUSESymLinkIn) SizeBytes() int {
|
||||
return len(r.Name) + len(r.Target) + 2
|
||||
return r.Name.SizeBytes() + r.Target.SizeBytes()
|
||||
}
|
||||
|
||||
// FUSEEmptyIn is used by operations without request body.
|
||||
type FUSEEmptyIn struct{ marshal.StubMarshallable }
|
||||
|
||||
// MarshalBytes do nothing for marshal.
|
||||
func (r *FUSEEmptyIn) MarshalBytes(buf []byte) {}
|
||||
func (r *FUSEEmptyIn) MarshalBytes(buf []byte) []byte {
|
||||
return buf
|
||||
}
|
||||
|
||||
// SizeBytes is 0 for empty request.
|
||||
func (r *FUSEEmptyIn) SizeBytes() int {
|
||||
@@ -649,19 +662,18 @@ type FUSEMkdirIn struct {
|
||||
MkdirMeta FUSEMkdirMeta
|
||||
|
||||
// Name of the directory to create.
|
||||
Name string
|
||||
Name CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.MkdirMeta and r.Name to the dst buffer.
|
||||
func (r *FUSEMkdirIn) MarshalBytes(buf []byte) {
|
||||
r.MkdirMeta.MarshalBytes(buf[:r.MkdirMeta.SizeBytes()])
|
||||
copy(buf[r.MkdirMeta.SizeBytes():], r.Name)
|
||||
func (r *FUSEMkdirIn) MarshalBytes(buf []byte) []byte {
|
||||
buf = r.MkdirMeta.MarshalBytes(buf)
|
||||
return r.Name.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSEMkdirIn.
|
||||
// 1 extra byte for null-terminated Name string.
|
||||
func (r *FUSEMkdirIn) SizeBytes() int {
|
||||
return r.MkdirMeta.SizeBytes() + len(r.Name) + 1
|
||||
return r.MkdirMeta.SizeBytes() + r.Name.SizeBytes()
|
||||
}
|
||||
|
||||
// FUSERmDirIn is the request sent by the kernel to the daemon
|
||||
@@ -672,17 +684,17 @@ type FUSERmDirIn struct {
|
||||
marshal.StubMarshallable
|
||||
|
||||
// Name is a directory name to be removed.
|
||||
Name string
|
||||
Name CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.name to the dst buffer.
|
||||
func (r *FUSERmDirIn) MarshalBytes(buf []byte) {
|
||||
copy(buf, r.Name)
|
||||
func (r *FUSERmDirIn) MarshalBytes(buf []byte) []byte {
|
||||
return r.Name.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSERmDirIn.
|
||||
func (r *FUSERmDirIn) SizeBytes() int {
|
||||
return len(r.Name) + 1
|
||||
return r.Name.SizeBytes()
|
||||
}
|
||||
|
||||
// FUSEDirents is a list of Dirents received from the FUSE daemon server.
|
||||
@@ -738,7 +750,7 @@ func (r *FUSEDirents) SizeBytes() int {
|
||||
}
|
||||
|
||||
// UnmarshalBytes deserializes FUSEDirents from the src buffer.
|
||||
func (r *FUSEDirents) UnmarshalBytes(src []byte) {
|
||||
func (r *FUSEDirents) UnmarshalBytes(src []byte) []byte {
|
||||
for {
|
||||
if len(src) <= (*FUSEDirentMeta)(nil).SizeBytes() {
|
||||
break
|
||||
@@ -754,11 +766,10 @@ func (r *FUSEDirents) UnmarshalBytes(src []byte) {
|
||||
// to do this. Linux allocates 1 page to store all the dirents and then
|
||||
// simply reads them from the page.
|
||||
var dirent FUSEDirent
|
||||
dirent.UnmarshalBytes(src)
|
||||
src = dirent.UnmarshalBytes(src)
|
||||
r.Dirents = append(r.Dirents, &dirent)
|
||||
|
||||
src = src[dirent.SizeBytes():]
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSEDirent.
|
||||
@@ -772,20 +783,20 @@ func (r *FUSEDirent) SizeBytes() int {
|
||||
}
|
||||
|
||||
// UnmarshalBytes deserializes FUSEDirent from the src buffer.
|
||||
func (r *FUSEDirent) UnmarshalBytes(src []byte) {
|
||||
r.Meta.UnmarshalBytes(src)
|
||||
src = src[r.Meta.SizeBytes():]
|
||||
func (r *FUSEDirent) UnmarshalBytes(src []byte) []byte {
|
||||
src = r.Meta.UnmarshalBytes(src)
|
||||
|
||||
if r.Meta.NameLen > FUSE_NAME_MAX {
|
||||
// The name is too long and therefore invalid. We don't
|
||||
// need to unmarshal the name since it'll be thrown away.
|
||||
return
|
||||
return src
|
||||
}
|
||||
|
||||
buf := make([]byte, r.Meta.NameLen)
|
||||
name := primitive.ByteSlice(buf)
|
||||
name.UnmarshalBytes(src[:r.Meta.NameLen])
|
||||
r.Name = string(name)
|
||||
return src[r.Meta.NameLen:]
|
||||
}
|
||||
|
||||
// FATTR_* consts are the attribute flags defined in include/uapi/linux/fuse.h.
|
||||
@@ -863,17 +874,15 @@ type FUSEUnlinkIn struct {
|
||||
marshal.StubMarshallable
|
||||
|
||||
// Name of the node to unlink.
|
||||
Name string
|
||||
Name CString
|
||||
}
|
||||
|
||||
// MarshalBytes serializes r.name to the dst buffer, which should
|
||||
// have size len(r.Name) + 1 and last byte set to 0.
|
||||
func (r *FUSEUnlinkIn) MarshalBytes(buf []byte) {
|
||||
copy(buf, r.Name)
|
||||
// MarshalBytes serializes r.name to the dst buffer.
|
||||
func (r *FUSEUnlinkIn) MarshalBytes(buf []byte) []byte {
|
||||
return r.Name.MarshalBytes(buf)
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the memory representation of FUSEUnlinkIn.
|
||||
// 1 extra byte for null-terminated Name string.
|
||||
func (r *FUSEUnlinkIn) SizeBytes() int {
|
||||
return len(r.Name) + 1
|
||||
return r.Name.SizeBytes()
|
||||
}
|
||||
|
||||
@@ -82,15 +82,15 @@ func (b *MsgBuf) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (b *MsgBuf) MarshalBytes(dst []byte) {
|
||||
b.Type.MarshalUnsafe(dst)
|
||||
b.Text.MarshalBytes(dst[b.Type.SizeBytes():])
|
||||
func (b *MsgBuf) MarshalBytes(dst []byte) []byte {
|
||||
dst = b.Type.MarshalUnsafe(dst)
|
||||
return b.Text.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (b *MsgBuf) UnmarshalBytes(src []byte) {
|
||||
b.Type.UnmarshalUnsafe(src)
|
||||
b.Text.UnmarshalBytes(src[b.Type.SizeBytes():])
|
||||
func (b *MsgBuf) UnmarshalBytes(src []byte) []byte {
|
||||
src = b.Type.UnmarshalUnsafe(src)
|
||||
return b.Text.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// MsgInfo is equivelant to struct msginfo. Source: include/uapi/linux/msg.h
|
||||
|
||||
+14
-16
@@ -144,15 +144,15 @@ func (ke *KernelIPTEntry) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIPTEntry) MarshalBytes(dst []byte) {
|
||||
ke.Entry.MarshalUnsafe(dst)
|
||||
ke.Elems.MarshalBytes(dst[ke.Entry.SizeBytes():])
|
||||
func (ke *KernelIPTEntry) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.Entry.MarshalUnsafe(dst)
|
||||
return ke.Elems.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIPTEntry) UnmarshalBytes(src []byte) {
|
||||
ke.Entry.UnmarshalUnsafe(src)
|
||||
ke.Elems.UnmarshalBytes(src[ke.Entry.SizeBytes():])
|
||||
func (ke *KernelIPTEntry) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.Entry.UnmarshalUnsafe(src)
|
||||
return ke.Elems.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIPTEntry)(nil)
|
||||
@@ -455,23 +455,21 @@ func (ke *KernelIPTGetEntries) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIPTGetEntries) MarshalBytes(dst []byte) {
|
||||
ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||
marshalledUntil := ke.IPTGetEntries.SizeBytes()
|
||||
func (ke *KernelIPTGetEntries) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||
for i := range ke.Entrytable {
|
||||
ke.Entrytable[i].MarshalBytes(dst[marshalledUntil:])
|
||||
marshalledUntil += ke.Entrytable[i].SizeBytes()
|
||||
dst = ke.Entrytable[i].MarshalBytes(dst)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIPTGetEntries) UnmarshalBytes(src []byte) {
|
||||
ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||
unmarshalledUntil := ke.IPTGetEntries.SizeBytes()
|
||||
func (ke *KernelIPTGetEntries) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||
for i := range ke.Entrytable {
|
||||
ke.Entrytable[i].UnmarshalBytes(src[unmarshalledUntil:])
|
||||
unmarshalledUntil += ke.Entrytable[i].SizeBytes()
|
||||
src = ke.Entrytable[i].UnmarshalBytes(src)
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIPTGetEntries)(nil)
|
||||
|
||||
@@ -84,23 +84,21 @@ func (ke *KernelIP6TGetEntries) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIP6TGetEntries) MarshalBytes(dst []byte) {
|
||||
ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||
marshalledUntil := ke.IPTGetEntries.SizeBytes()
|
||||
func (ke *KernelIP6TGetEntries) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||
for i := range ke.Entrytable {
|
||||
ke.Entrytable[i].MarshalBytes(dst[marshalledUntil:])
|
||||
marshalledUntil += ke.Entrytable[i].SizeBytes()
|
||||
dst = ke.Entrytable[i].MarshalBytes(dst)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIP6TGetEntries) UnmarshalBytes(src []byte) {
|
||||
ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||
unmarshalledUntil := ke.IPTGetEntries.SizeBytes()
|
||||
func (ke *KernelIP6TGetEntries) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||
for i := range ke.Entrytable {
|
||||
ke.Entrytable[i].UnmarshalBytes(src[unmarshalledUntil:])
|
||||
unmarshalledUntil += ke.Entrytable[i].SizeBytes()
|
||||
src = ke.Entrytable[i].UnmarshalBytes(src)
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIP6TGetEntries)(nil)
|
||||
@@ -166,17 +164,19 @@ func (ke *KernelIP6TEntry) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (ke *KernelIP6TEntry) MarshalBytes(dst []byte) {
|
||||
ke.Entry.MarshalUnsafe(dst)
|
||||
ke.Elems.MarshalBytes(dst[ke.Entry.SizeBytes():])
|
||||
func (ke *KernelIP6TEntry) MarshalBytes(dst []byte) []byte {
|
||||
dst = ke.Entry.MarshalUnsafe(dst)
|
||||
return ke.Elems.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (ke *KernelIP6TEntry) UnmarshalBytes(src []byte) {
|
||||
ke.Entry.UnmarshalUnsafe(src)
|
||||
ke.Elems.UnmarshalBytes(src[ke.Entry.SizeBytes():])
|
||||
func (ke *KernelIP6TEntry) UnmarshalBytes(src []byte) []byte {
|
||||
src = ke.Entry.UnmarshalUnsafe(src)
|
||||
return ke.Elems.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
var _ marshal.Marshallable = (*KernelIP6TEntry)(nil)
|
||||
|
||||
// IP6TIP contains information for matching a packet's IP header.
|
||||
// It corresponds to struct ip6t_ip6 in
|
||||
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||
|
||||
@@ -555,9 +555,6 @@ type ControlMessageIPv6PacketInfo struct {
|
||||
// ControlMessageCredentials struct.
|
||||
var SizeOfControlMessageCredentials = (*ControlMessageCredentials)(nil).SizeBytes()
|
||||
|
||||
// A ControlMessageRights is an SCM_RIGHTS socket control message.
|
||||
type ControlMessageRights []int32
|
||||
|
||||
// SizeOfControlMessageRight is the size of a single element in
|
||||
// ControlMessageRights.
|
||||
const SizeOfControlMessageRight = 4
|
||||
|
||||
@@ -313,7 +313,7 @@ func (c *Client) SyncFDs(ctx context.Context, fds []FDID) error {
|
||||
// implicit conversion to an interface leads to an allocation.
|
||||
//
|
||||
// Precondition: reqMarshal and respUnmarshal must be non-nil.
|
||||
func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal func(dst []byte), respUnmarshal func(src []byte), respFDs []int) error {
|
||||
func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal func(dst []byte) []byte, respUnmarshal func(src []byte) []byte, respFDs []int) error {
|
||||
if !c.IsSupported(m) {
|
||||
return unix.EOPNOTSUPP
|
||||
}
|
||||
|
||||
+230
-281
File diff suppressed because it is too large
Load Diff
@@ -53,18 +53,24 @@ func (m *MsgDynamic) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (m *MsgDynamic) MarshalBytes(dst []byte) {
|
||||
m.N.MarshalUnsafe(dst)
|
||||
dst = dst[m.N.SizeBytes():]
|
||||
MarshalUnsafeMsg1Slice(m.Arr, dst)
|
||||
func (m *MsgDynamic) MarshalBytes(dst []byte) []byte {
|
||||
dst = m.N.MarshalUnsafe(dst)
|
||||
n, err := MarshalUnsafeMsg1Slice(m.Arr, dst)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return dst[n:]
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (m *MsgDynamic) UnmarshalBytes(src []byte) {
|
||||
m.N.UnmarshalUnsafe(src)
|
||||
src = src[m.N.SizeBytes():]
|
||||
func (m *MsgDynamic) UnmarshalBytes(src []byte) []byte {
|
||||
src = m.N.UnmarshalUnsafe(src)
|
||||
m.Arr = make([]MsgSimple, m.N)
|
||||
UnmarshalUnsafeMsg1Slice(m.Arr, src)
|
||||
n, err := UnmarshalUnsafeMsg1Slice(m.Arr, src)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return src[n:]
|
||||
}
|
||||
|
||||
// Randomize randomizes the contents of m.
|
||||
@@ -90,21 +96,18 @@ func (v *P9Version) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (v *P9Version) MarshalBytes(dst []byte) {
|
||||
v.MSize.MarshalUnsafe(dst)
|
||||
dst = dst[v.MSize.SizeBytes():]
|
||||
func (v *P9Version) MarshalBytes(dst []byte) []byte {
|
||||
dst = v.MSize.MarshalUnsafe(dst)
|
||||
versionLen := primitive.Uint16(len(v.Version))
|
||||
versionLen.MarshalUnsafe(dst)
|
||||
dst = dst[versionLen.SizeBytes():]
|
||||
copy(dst, v.Version)
|
||||
dst = versionLen.MarshalUnsafe(dst)
|
||||
return dst[copy(dst, v.Version):]
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (v *P9Version) UnmarshalBytes(src []byte) {
|
||||
v.MSize.UnmarshalUnsafe(src)
|
||||
src = src[v.MSize.SizeBytes():]
|
||||
func (v *P9Version) UnmarshalBytes(src []byte) []byte {
|
||||
src = v.MSize.UnmarshalUnsafe(src)
|
||||
var versionLen primitive.Uint16
|
||||
versionLen.UnmarshalUnsafe(src)
|
||||
src = src[versionLen.SizeBytes():]
|
||||
src = versionLen.UnmarshalUnsafe(src)
|
||||
v.Version = string(src[:versionLen])
|
||||
return src[versionLen:]
|
||||
}
|
||||
|
||||
@@ -59,13 +59,15 @@ type Marshallable interface {
|
||||
// likely make use of the type of these fields).
|
||||
SizeBytes() int
|
||||
|
||||
// MarshalBytes serializes a copy of a type to dst.
|
||||
// MarshalBytes serializes a copy of a type to dst and returns the remaining
|
||||
// buffer.
|
||||
// Precondition: dst must be at least SizeBytes() in length.
|
||||
MarshalBytes(dst []byte)
|
||||
MarshalBytes(dst []byte) []byte
|
||||
|
||||
// UnmarshalBytes deserializes a type from src.
|
||||
// UnmarshalBytes deserializes a type from src and returns the remaining
|
||||
// buffer.
|
||||
// Precondition: src must be at least SizeBytes() in length.
|
||||
UnmarshalBytes(src []byte)
|
||||
UnmarshalBytes(src []byte) []byte
|
||||
|
||||
// Packed returns true if the marshalled size of the type is the same as the
|
||||
// size it occupies in memory. This happens when the type has no fields
|
||||
@@ -86,7 +88,7 @@ type Marshallable interface {
|
||||
// return false, MarshalUnsafe should fall back to the safer but slower
|
||||
// MarshalBytes.
|
||||
// Precondition: dst must be at least SizeBytes() in length.
|
||||
MarshalUnsafe(dst []byte)
|
||||
MarshalUnsafe(dst []byte) []byte
|
||||
|
||||
// UnmarshalUnsafe deserializes a type by directly copying to the underlying
|
||||
// memory allocated for the object by the runtime.
|
||||
@@ -96,7 +98,7 @@ type Marshallable interface {
|
||||
// UnmarshalUnsafe should fall back to the safer but slower unmarshal
|
||||
// mechanism implemented in UnmarshalBytes.
|
||||
// Precondition: src must be at least SizeBytes() in length.
|
||||
UnmarshalUnsafe(src []byte)
|
||||
UnmarshalUnsafe(src []byte) []byte
|
||||
|
||||
// CopyIn deserializes a Marshallable type from a task's memory. This may
|
||||
// only be called from a task goroutine. This is more efficient than calling
|
||||
|
||||
@@ -38,12 +38,12 @@ func (StubMarshallable) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements Marshallable.MarshalBytes.
|
||||
func (StubMarshallable) MarshalBytes(dst []byte) {
|
||||
func (StubMarshallable) MarshalBytes(dst []byte) []byte {
|
||||
panic("Please implement your own MarshalBytes function")
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements Marshallable.UnmarshalBytes.
|
||||
func (StubMarshallable) UnmarshalBytes(src []byte) {
|
||||
func (StubMarshallable) UnmarshalBytes(src []byte) []byte {
|
||||
panic("Please implement your own UnmarshalBytes function")
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ func (StubMarshallable) Packed() bool {
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements Marshallable.MarshalUnsafe.
|
||||
func (StubMarshallable) MarshalUnsafe(dst []byte) {
|
||||
func (StubMarshallable) MarshalUnsafe(dst []byte) []byte {
|
||||
panic("Please implement your own MarshalUnsafe function")
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements Marshallable.UnmarshalUnsafe.
|
||||
func (StubMarshallable) UnmarshalUnsafe(src []byte) {
|
||||
func (StubMarshallable) UnmarshalUnsafe(src []byte) []byte {
|
||||
panic("Please implement your own UnmarshalUnsafe function")
|
||||
}
|
||||
|
||||
|
||||
@@ -76,13 +76,13 @@ func (b *ByteSlice) SizeBytes() int {
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (b *ByteSlice) MarshalBytes(dst []byte) {
|
||||
copy(dst, *b)
|
||||
func (b *ByteSlice) MarshalBytes(dst []byte) []byte {
|
||||
return dst[copy(dst, *b):]
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (b *ByteSlice) UnmarshalBytes(src []byte) {
|
||||
copy(*b, src)
|
||||
func (b *ByteSlice) UnmarshalBytes(src []byte) []byte {
|
||||
return src[copy(*b, src):]
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
@@ -91,13 +91,13 @@ func (b *ByteSlice) Packed() bool {
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (b *ByteSlice) MarshalUnsafe(dst []byte) {
|
||||
b.MarshalBytes(dst)
|
||||
func (b *ByteSlice) MarshalUnsafe(dst []byte) []byte {
|
||||
return b.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (b *ByteSlice) UnmarshalUnsafe(src []byte) {
|
||||
b.UnmarshalBytes(src)
|
||||
func (b *ByteSlice) UnmarshalUnsafe(src []byte) []byte {
|
||||
return b.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
|
||||
@@ -77,8 +77,7 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/errors/linuxerr",
|
||||
"//pkg/hostarch",
|
||||
"//pkg/marshal",
|
||||
"//pkg/marshal/primitive",
|
||||
"//pkg/sentry/fsimpl/testutil",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
)
|
||||
@@ -69,14 +70,10 @@ func TestConnectionAbort(t *testing.T) {
|
||||
t.Fatalf("newTestConnection: %v", err)
|
||||
}
|
||||
|
||||
testObj := &testPayload{
|
||||
data: rand.Uint32(),
|
||||
}
|
||||
|
||||
var futNormal []*futureResponse
|
||||
|
||||
testObj := primitive.Uint32(rand.Uint32())
|
||||
for i := 0; i < int(numRequests); i++ {
|
||||
req := conn.NewRequest(creds, uint32(i), uint64(i), 0, testObj)
|
||||
req := conn.NewRequest(creds, uint32(i), uint64(i), 0, &testObj)
|
||||
fut, err := conn.callFutureLocked(task, req)
|
||||
if err != nil {
|
||||
t.Fatalf("callFutureLocked failed: %v", err)
|
||||
@@ -102,7 +99,7 @@ func TestConnectionAbort(t *testing.T) {
|
||||
}
|
||||
|
||||
// After abort, Call() should return directly with ENOTCONN.
|
||||
req := conn.NewRequest(creds, 0, 0, 0, testObj)
|
||||
req := conn.NewRequest(creds, 0, 0, 0, &testObj)
|
||||
_, err = conn.Call(task, req)
|
||||
if !linuxerr.Equals(linuxerr.ENOTCONN, err) {
|
||||
t.Fatalf("Incorrect error code received for Call() after connection aborted")
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/testutil"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
@@ -215,11 +216,9 @@ func fuseClientRun(t *testing.T, s *testutil.System, k *kernel.Kernel, conn *con
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testObj := &testPayload{
|
||||
data: rand.Uint32(),
|
||||
}
|
||||
|
||||
req := conn.NewRequest(creds, pid, inode, echoTestOpcode, testObj)
|
||||
testObj := primitive.Uint32(rand.Uint32())
|
||||
req := conn.NewRequest(creds, pid, inode, echoTestOpcode, &testObj)
|
||||
|
||||
// Queue up a request.
|
||||
// Analogous to Call except it doesn't block on the task.
|
||||
@@ -232,7 +231,7 @@ func fuseClientRun(t *testing.T, s *testutil.System, k *kernel.Kernel, conn *con
|
||||
t.Fatalf("Server responded with an error: %v", err)
|
||||
}
|
||||
|
||||
var respTestPayload testPayload
|
||||
var respTestPayload primitive.Uint32
|
||||
if err := resp.UnmarshalPayload(&respTestPayload); err != nil {
|
||||
t.Fatalf("Unmarshalling payload error: %v", err)
|
||||
}
|
||||
@@ -242,8 +241,8 @@ func fuseClientRun(t *testing.T, s *testutil.System, k *kernel.Kernel, conn *con
|
||||
req.hdr.Unique, resp.hdr.Unique)
|
||||
}
|
||||
|
||||
if respTestPayload.data != testObj.data {
|
||||
t.Fatalf("read incorrect data. Data expected: %v, but got %v", testObj.data, respTestPayload.data)
|
||||
if respTestPayload != testObj {
|
||||
t.Fatalf("read incorrect data. Data expected: %d, but got %d", testObj, respTestPayload)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -256,8 +255,8 @@ func fuseServerRun(t *testing.T, s *testutil.System, k *kernel.Kernel, fd *vfs.F
|
||||
|
||||
// Create the tasks that the server will be using.
|
||||
tc := k.NewThreadGroup(nil, k.RootPIDNamespace(), kernel.NewSignalHandlers(), linux.SIGCHLD, k.GlobalInit().Limits())
|
||||
var readPayload testPayload
|
||||
|
||||
var readPayload primitive.Uint32
|
||||
serverTask, err := testutil.CreateTask(s.Ctx, "fuse-server", tc, s.MntNs, s.Root, s.Root)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -291,8 +290,8 @@ func fuseServerRun(t *testing.T, s *testutil.System, k *kernel.Kernel, fd *vfs.F
|
||||
}
|
||||
|
||||
var readFUSEHeaderIn linux.FUSEHeaderIn
|
||||
readFUSEHeaderIn.UnmarshalUnsafe(inBuf[:inHdrLen])
|
||||
readPayload.UnmarshalUnsafe(inBuf[inHdrLen : inHdrLen+payloadLen])
|
||||
inBuf = readFUSEHeaderIn.UnmarshalUnsafe(inBuf)
|
||||
readPayload.UnmarshalUnsafe(inBuf)
|
||||
|
||||
if readFUSEHeaderIn.Opcode != echoTestOpcode {
|
||||
t.Fatalf("read incorrect data. Header: %v, Payload: %v", readFUSEHeaderIn, readPayload)
|
||||
|
||||
@@ -489,7 +489,7 @@ func (i *inode) Open(ctx context.Context, rp *vfs.ResolvingPath, d *kernfs.Dentr
|
||||
|
||||
// Lookup implements kernfs.Inode.Lookup.
|
||||
func (i *inode) Lookup(ctx context.Context, name string) (kernfs.Inode, error) {
|
||||
in := linux.FUSELookupIn{Name: name}
|
||||
in := linux.FUSELookupIn{Name: linux.CString(name)}
|
||||
return i.newEntry(ctx, name, 0, linux.FUSE_LOOKUP, &in)
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions)
|
||||
Mode: uint32(opts.Mode) | linux.S_IFREG,
|
||||
Umask: uint32(kernelTask.FSContext().Umask()),
|
||||
},
|
||||
Name: name,
|
||||
Name: linux.CString(name),
|
||||
}
|
||||
return i.newEntry(ctx, name, linux.S_IFREG, linux.FUSE_CREATE, &in)
|
||||
}
|
||||
@@ -533,7 +533,7 @@ func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions)
|
||||
Rdev: linux.MakeDeviceID(uint16(opts.DevMajor), opts.DevMinor),
|
||||
Umask: uint32(kernel.TaskFromContext(ctx).FSContext().Umask()),
|
||||
},
|
||||
Name: name,
|
||||
Name: linux.CString(name),
|
||||
}
|
||||
return i.newEntry(ctx, name, opts.Mode.FileType(), linux.FUSE_MKNOD, &in)
|
||||
}
|
||||
@@ -541,8 +541,8 @@ func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions)
|
||||
// NewSymlink implements kernfs.Inode.NewSymlink.
|
||||
func (i *inode) NewSymlink(ctx context.Context, name, target string) (kernfs.Inode, error) {
|
||||
in := linux.FUSESymLinkIn{
|
||||
Name: name,
|
||||
Target: target,
|
||||
Name: linux.CString(name),
|
||||
Target: linux.CString(target),
|
||||
}
|
||||
return i.newEntry(ctx, name, linux.S_IFLNK, linux.FUSE_SYMLINK, &in)
|
||||
}
|
||||
@@ -554,7 +554,7 @@ func (i *inode) Unlink(ctx context.Context, name string, child kernfs.Inode) err
|
||||
log.Warningf("fusefs.Inode.newEntry: couldn't get kernel task from context", i.nodeID)
|
||||
return linuxerr.EINVAL
|
||||
}
|
||||
in := linux.FUSEUnlinkIn{Name: name}
|
||||
in := linux.FUSEUnlinkIn{Name: linux.CString(name)}
|
||||
req := i.fs.conn.NewRequest(auth.CredentialsFromContext(ctx), uint32(kernelTask.ThreadID()), i.nodeID, linux.FUSE_UNLINK, &in)
|
||||
res, err := i.fs.conn.Call(kernelTask, req)
|
||||
if err != nil {
|
||||
@@ -571,7 +571,7 @@ func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions)
|
||||
Mode: uint32(opts.Mode),
|
||||
Umask: uint32(kernel.TaskFromContext(ctx).FSContext().Umask()),
|
||||
},
|
||||
Name: name,
|
||||
Name: linux.CString(name),
|
||||
}
|
||||
return i.newEntry(ctx, name, linux.S_IFDIR, linux.FUSE_MKDIR, &in)
|
||||
}
|
||||
@@ -581,7 +581,7 @@ func (i *inode) RmDir(ctx context.Context, name string, child kernfs.Inode) erro
|
||||
fusefs := i.fs
|
||||
task, creds := kernel.TaskFromContext(ctx), auth.CredentialsFromContext(ctx)
|
||||
|
||||
in := linux.FUSERmDirIn{Name: name}
|
||||
in := linux.FUSERmDirIn{Name: linux.CString(name)}
|
||||
req := fusefs.conn.NewRequest(creds, uint32(task.ThreadID()), i.nodeID, linux.FUSE_RMDIR, &in)
|
||||
res, err := i.fs.conn.Call(task, req)
|
||||
if err != nil {
|
||||
|
||||
@@ -41,7 +41,7 @@ type fuseInitRes struct {
|
||||
}
|
||||
|
||||
// UnmarshalBytes deserializes src to the initOut attribute in a fuseInitRes.
|
||||
func (r *fuseInitRes) UnmarshalBytes(src []byte) {
|
||||
func (r *fuseInitRes) UnmarshalBytes(src []byte) []byte {
|
||||
out := &r.initOut
|
||||
|
||||
// Introduced before FUSE kernel version 7.13.
|
||||
@@ -70,7 +70,7 @@ func (r *fuseInitRes) UnmarshalBytes(src []byte) {
|
||||
out.MaxPages = uint16(hostarch.ByteOrder.Uint16(src[:2]))
|
||||
src = src[2:]
|
||||
}
|
||||
_ = src // Remove unused warning.
|
||||
return src
|
||||
}
|
||||
|
||||
// SizeBytes is the size of the payload of the FUSE_INIT response.
|
||||
|
||||
@@ -15,17 +15,13 @@
|
||||
package fuse
|
||||
|
||||
import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/testutil"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
)
|
||||
|
||||
func setup(t *testing.T) *testutil.System {
|
||||
@@ -70,58 +66,3 @@ func newTestConnection(system *testutil.System, k *kernel.Kernel, maxActiveReque
|
||||
}
|
||||
return fs.conn, &fuseDev.vfsfd, nil
|
||||
}
|
||||
|
||||
type testPayload struct {
|
||||
marshal.StubMarshallable
|
||||
data uint32
|
||||
}
|
||||
|
||||
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||
func (t *testPayload) SizeBytes() int {
|
||||
return 4
|
||||
}
|
||||
|
||||
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||
func (t *testPayload) MarshalBytes(dst []byte) {
|
||||
hostarch.ByteOrder.PutUint32(dst[:4], t.data)
|
||||
}
|
||||
|
||||
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||
func (t *testPayload) UnmarshalBytes(src []byte) {
|
||||
*t = testPayload{data: hostarch.ByteOrder.Uint32(src[:4])}
|
||||
}
|
||||
|
||||
// Packed implements marshal.Marshallable.Packed.
|
||||
func (t *testPayload) Packed() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||
func (t *testPayload) MarshalUnsafe(dst []byte) {
|
||||
t.MarshalBytes(dst)
|
||||
}
|
||||
|
||||
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||
func (t *testPayload) UnmarshalUnsafe(src []byte) {
|
||||
t.UnmarshalBytes(src)
|
||||
}
|
||||
|
||||
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||
func (t *testPayload) CopyOutN(task marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||
func (t *testPayload) CopyOut(task marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||
func (t *testPayload) CopyIn(task marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.WriteTo.
|
||||
func (t *testPayload) WriteTo(w io.Writer) (int64, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
@@ -212,8 +212,7 @@ func parseHeader(ctx context.Context, f fullReader) (elfInfo, error) {
|
||||
phdrs := make([]elf.ProgHeader, hdr.Phnum)
|
||||
for i := range phdrs {
|
||||
var prog64 linux.ElfProg64
|
||||
prog64.UnmarshalUnsafe(phdrBuf[:prog64Size])
|
||||
phdrBuf = phdrBuf[prog64Size:]
|
||||
phdrBuf = prog64.UnmarshalUnsafe(phdrBuf)
|
||||
phdrs[i] = elf.ProgHeader{
|
||||
Type: elf.ProgType(prog64.Type),
|
||||
Flags: elf.ProgFlag(prog64.Flags),
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
@@ -29,7 +31,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SCMCredentials represents a SCM_CREDENTIALS socket control message.
|
||||
@@ -63,10 +64,10 @@ type RightsFiles []*fs.File
|
||||
|
||||
// NewSCMRights creates a new SCM_RIGHTS socket control message representation
|
||||
// using local sentry FDs.
|
||||
func NewSCMRights(t *kernel.Task, fds []int32) (SCMRights, error) {
|
||||
func NewSCMRights(t *kernel.Task, fds []primitive.Int32) (SCMRights, error) {
|
||||
files := make(RightsFiles, 0, len(fds))
|
||||
for _, fd := range fds {
|
||||
file := t.GetFile(fd)
|
||||
file := t.GetFile(int32(fd))
|
||||
if file == nil {
|
||||
files.Release(t)
|
||||
return nil, linuxerr.EBADF
|
||||
@@ -486,27 +487,26 @@ func CmsgsSpace(t *kernel.Task, cmsgs socket.ControlMessages) int {
|
||||
func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint) (socket.ControlMessages, error) {
|
||||
var (
|
||||
cmsgs socket.ControlMessages
|
||||
fds linux.ControlMessageRights
|
||||
fds []primitive.Int32
|
||||
)
|
||||
|
||||
for i := 0; i < len(buf); {
|
||||
if i+linux.SizeOfControlMessageHeader > len(buf) {
|
||||
for len(buf) > 0 {
|
||||
if linux.SizeOfControlMessageHeader > len(buf) {
|
||||
return cmsgs, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
var h linux.ControlMessageHeader
|
||||
h.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageHeader])
|
||||
buf = h.UnmarshalUnsafe(buf)
|
||||
|
||||
if h.Length < uint64(linux.SizeOfControlMessageHeader) {
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
if h.Length > uint64(len(buf)-i) {
|
||||
|
||||
length := int(h.Length) - linux.SizeOfControlMessageHeader
|
||||
if length > len(buf) {
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
i += linux.SizeOfControlMessageHeader
|
||||
length := int(h.Length) - linux.SizeOfControlMessageHeader
|
||||
|
||||
switch h.Level {
|
||||
case linux.SOL_SOCKET:
|
||||
switch h.Type {
|
||||
@@ -518,11 +518,9 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
for j := i; j < i+rightsSize; j += linux.SizeOfControlMessageRight {
|
||||
fds = append(fds, int32(hostarch.ByteOrder.Uint32(buf[j:j+linux.SizeOfControlMessageRight])))
|
||||
}
|
||||
|
||||
i += bits.AlignUp(length, width)
|
||||
curFDs := make([]primitive.Int32, numRights)
|
||||
primitive.UnmarshalUnsafeInt32Slice(curFDs, buf[:rightsSize])
|
||||
fds = append(fds, curFDs...)
|
||||
|
||||
case linux.SCM_CREDENTIALS:
|
||||
if length < linux.SizeOfControlMessageCredentials {
|
||||
@@ -530,23 +528,21 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
}
|
||||
|
||||
var creds linux.ControlMessageCredentials
|
||||
creds.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageCredentials])
|
||||
creds.UnmarshalUnsafe(buf)
|
||||
scmCreds, err := NewSCMCredentials(t, creds)
|
||||
if err != nil {
|
||||
return socket.ControlMessages{}, err
|
||||
}
|
||||
cmsgs.Unix.Credentials = scmCreds
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.SO_TIMESTAMP:
|
||||
if length < linux.SizeOfTimeval {
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
var ts linux.Timeval
|
||||
ts.UnmarshalUnsafe(buf[i : i+linux.SizeOfTimeval])
|
||||
ts.UnmarshalUnsafe(buf)
|
||||
cmsgs.IP.Timestamp = ts.ToTime()
|
||||
cmsgs.IP.HasTimestamp = true
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
default:
|
||||
// Unknown message type.
|
||||
@@ -560,9 +556,8 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
}
|
||||
cmsgs.IP.HasTOS = true
|
||||
var tos primitive.Uint8
|
||||
tos.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageTOS])
|
||||
tos.UnmarshalUnsafe(buf)
|
||||
cmsgs.IP.TOS = uint8(tos)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IP_PKTINFO:
|
||||
if length < linux.SizeOfControlMessageIPPacketInfo {
|
||||
@@ -571,19 +566,16 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
|
||||
cmsgs.IP.HasIPPacketInfo = true
|
||||
var packetInfo linux.ControlMessageIPPacketInfo
|
||||
packetInfo.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageIPPacketInfo])
|
||||
|
||||
packetInfo.UnmarshalUnsafe(buf)
|
||||
cmsgs.IP.PacketInfo = packetInfo
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IP_RECVORIGDSTADDR:
|
||||
var addr linux.SockAddrInet
|
||||
if length < addr.SizeBytes() {
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
addr.UnmarshalUnsafe(buf[i : i+addr.SizeBytes()])
|
||||
addr.UnmarshalUnsafe(buf)
|
||||
cmsgs.IP.OriginalDstAddress = &addr
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IP_RECVERR:
|
||||
var errCmsg linux.SockErrCMsgIPv4
|
||||
@@ -591,9 +583,8 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
errCmsg.UnmarshalBytes(buf[i : i+errCmsg.SizeBytes()])
|
||||
errCmsg.UnmarshalBytes(buf)
|
||||
cmsgs.IP.SockErr = &errCmsg
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
default:
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
@@ -606,18 +597,16 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
}
|
||||
cmsgs.IP.HasTClass = true
|
||||
var tclass primitive.Uint32
|
||||
tclass.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageTClass])
|
||||
tclass.UnmarshalUnsafe(buf)
|
||||
cmsgs.IP.TClass = uint32(tclass)
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IPV6_RECVORIGDSTADDR:
|
||||
var addr linux.SockAddrInet6
|
||||
if length < addr.SizeBytes() {
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
addr.UnmarshalUnsafe(buf[i : i+addr.SizeBytes()])
|
||||
addr.UnmarshalUnsafe(buf)
|
||||
cmsgs.IP.OriginalDstAddress = &addr
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
case linux.IPV6_RECVERR:
|
||||
var errCmsg linux.SockErrCMsgIPv6
|
||||
@@ -625,9 +614,8 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
errCmsg.UnmarshalBytes(buf[i : i+errCmsg.SizeBytes()])
|
||||
errCmsg.UnmarshalBytes(buf)
|
||||
cmsgs.IP.SockErr = &errCmsg
|
||||
i += bits.AlignUp(length, width)
|
||||
|
||||
default:
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
@@ -635,6 +623,11 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint)
|
||||
default:
|
||||
return socket.ControlMessages{}, linuxerr.EINVAL
|
||||
}
|
||||
if shift := bits.AlignUp(length, width); shift > len(buf) {
|
||||
buf = buf[:0]
|
||||
} else {
|
||||
buf = buf[shift:]
|
||||
}
|
||||
}
|
||||
|
||||
if cmsgs.Unix.Credentials == nil {
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
@@ -45,10 +46,10 @@ type RightsFilesVFS2 []*vfs.FileDescription
|
||||
|
||||
// NewSCMRightsVFS2 creates a new SCM_RIGHTS socket control message
|
||||
// representation using local sentry FDs.
|
||||
func NewSCMRightsVFS2(t *kernel.Task, fds []int32) (SCMRightsVFS2, error) {
|
||||
func NewSCMRightsVFS2(t *kernel.Task, fds []primitive.Int32) (SCMRightsVFS2, error) {
|
||||
files := make(RightsFilesVFS2, 0, len(fds))
|
||||
for _, fd := range fds {
|
||||
file := t.GetFileVFS2(fd)
|
||||
file := t.GetFileVFS2(int32(fd))
|
||||
if file == nil {
|
||||
files.Release(t)
|
||||
return nil, linuxerr.EBADF
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user