From fbec65fc3f21773cbec3db4aadf27b85e8859448 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Thu, 25 Mar 2021 20:25:46 -0700 Subject: Use seqfile.SeqHandles correctly in VFS1 /proc/net/. Before this change: ``` $ docker run --runtime=runsc --rm -it -v ~/tmp:/hosttmp ubuntu:focal /hosttmp/issue5732 --bytes1=128 --bytes2=1024 #1: read(128) = 128 #2: read(1024) = EOF $ docker run --runtime=runsc-vfs2 --rm -it -v ~/tmp:/hosttmp ubuntu:focal /hosttmp/issue5732 --bytes1=128 --bytes2=1024 #1: read(128) = 128 #2: read(1024) = 256 ``` After this change: ``` $ docker run --runtime=runsc --rm -it -v ~/tmp:/hosttmp ubuntu:focal /hosttmp/issue5732 --bytes1=128 --bytes2=1024 #1: read(128) = 128 #2: read(1024) = 256 $ docker run --runtime=runsc-vfs2 --rm -it -v ~/tmp:/hosttmp ubuntu:focal /hosttmp/issue5732 --bytes1=128 --bytes2=1024 #1: read(128) = 128 #2: read(1024) = 256 ``` Fixes #5732 PiperOrigin-RevId: 365178386 --- pkg/sentry/fs/proc/net.go | 132 +++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 55 deletions(-) (limited to 'pkg') diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index 03127f816..203cfa061 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -128,13 +128,17 @@ func (*ifinet6) NeedsUpdate(generation int64) bool { // ReadSeqFileData implements seqfile.SeqSource.ReadSeqFileData. func (n *ifinet6) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]seqfile.SeqData, int64) { + contents := n.contents() + minI := 0 if h != nil { - return nil, 0 + minI = h.(int) + 1 + if minI > len(contents) { + minI = len(contents) + } } - var data []seqfile.SeqData - for _, l := range n.contents() { - data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: (*ifinet6)(nil)}) + for i, l := range contents[minI:] { + data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: i + minI}) } return data, 0 @@ -155,10 +159,6 @@ func (n *netDev) NeedsUpdate(generation int64) bool { // ReadSeqFileData implements seqfile.SeqSource.ReadSeqFileData. See Linux's // net/core/net-procfs.c:dev_seq_show. func (n *netDev) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]seqfile.SeqData, int64) { - if h != nil { - return nil, 0 - } - interfaces := n.s.Interfaces() contents := make([]string, 2, 2+len(interfaces)) // Add the table header. From net/core/net-procfs.c:dev_seq_show. @@ -197,9 +197,16 @@ func (n *netDev) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se contents = append(contents, l) } + minI := 0 + if h != nil { + minI = h.(int) + 1 + if minI > len(contents) { + minI = len(contents) + } + } var data []seqfile.SeqData - for _, l := range contents { - data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: (*netDev)(nil)}) + for i, l := range contents[minI:] { + data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: i + minI}) } return data, 0 @@ -264,10 +271,6 @@ func sprintSlice(s []uint64) string { // ReadSeqFileData implements seqfile.SeqSource.ReadSeqFileData. See Linux's // net/core/net-procfs.c:dev_seq_show. func (n *netSnmp) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]seqfile.SeqData, int64) { - if h != nil { - return nil, 0 - } - contents := make([]string, 0, len(snmp)*2) types := []interface{}{ &inet.StatSNMPIP{}, @@ -309,9 +312,16 @@ func (n *netSnmp) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]s ) } + minI := 0 + if h != nil { + minI = h.(int) + 1 + if minI > len(contents) { + minI = len(contents) + } + } data := make([]seqfile.SeqData, 0, len(snmp)*2) - for _, l := range contents { - data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: (*netSnmp)(nil)}) + for i, l := range contents[minI:] { + data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: i + minI}) } return data, 0 @@ -332,10 +342,6 @@ func (n *netRoute) NeedsUpdate(generation int64) bool { // ReadSeqFileData implements seqfile.SeqSource.ReadSeqFileData. // See Linux's net/ipv4/fib_trie.c:fib_route_seq_show. func (n *netRoute) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]seqfile.SeqData, int64) { - if h != nil { - return nil, 0 - } - interfaces := n.s.Interfaces() contents := []string{"Iface\tDestination\tGateway\tFlags\tRefCnt\tUse\tMetric\tMask\tMTU\tWindow\tIRTT"} for _, rt := range n.s.RouteTable() { @@ -383,10 +389,17 @@ func (n *netRoute) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([] contents = append(contents, l) } + minI := 0 + if h != nil { + minI = h.(int) + 1 + if minI > len(contents) { + minI = len(contents) + } + } var data []seqfile.SeqData - for _, l := range contents { + for i, l := range contents[minI:] { l = fmt.Sprintf("%-127s\n", l) - data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: (*netRoute)(nil)}) + data = append(data, seqfile.SeqData{Buf: []byte(l), Handle: i + minI}) } return data, 0 @@ -406,10 +419,6 @@ func (*netUnix) NeedsUpdate(generation int64) bool { // ReadSeqFileData implements seqfile.SeqSource.ReadSeqFileData. func (n *netUnix) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]seqfile.SeqData, int64) { - if h != nil { - return []seqfile.SeqData{}, 0 - } - var buf bytes.Buffer for _, se := range n.k.ListSockets() { s := se.Sock.Get() @@ -482,15 +491,22 @@ func (n *netUnix) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]s s.DecRef(ctx) } - data := []seqfile.SeqData{ - { + minI := 0 + if h != nil { + minI = h.(int) + 1 + } + var data []seqfile.SeqData + if minI <= 0 { + data = append(data, seqfile.SeqData{ Buf: []byte("Num RefCount Protocol Flags Type St Inode Path\n"), - Handle: n, - }, - { + Handle: 0, + }) + } + if minI <= 1 { + data = append(data, seqfile.SeqData{ Buf: buf.Bytes(), - Handle: n, - }, + Handle: 1, + }) } return data, 0 } @@ -557,10 +573,6 @@ func commonReadSeqFileDataTCP(ctx context.Context, n seqfile.SeqHandle, k *kerne // degrade gracefully and retrieve what we can. t := kernel.TaskFromContext(ctx) - if h != nil { - return nil, 0 - } - var buf bytes.Buffer for _, se := range k.ListSockets() { s := se.Sock.Get() @@ -667,15 +679,22 @@ func commonReadSeqFileDataTCP(ctx context.Context, n seqfile.SeqHandle, k *kerne s.DecRef(ctx) } - data := []seqfile.SeqData{ - { + minI := 0 + if h != nil { + minI = h.(int) + 1 + } + var data []seqfile.SeqData + if minI <= 0 { + data = append(data, seqfile.SeqData{ Buf: header, - Handle: n, - }, - { + Handle: 0, + }) + } + if minI <= 1 { + data = append(data, seqfile.SeqData{ Buf: buf.Bytes(), - Handle: n, - }, + Handle: 1, + }) } return data, 0 } @@ -735,10 +754,6 @@ func (n *netUDP) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se // degrade gracefully and retrieve what we can. t := kernel.TaskFromContext(ctx) - if h != nil { - return nil, 0 - } - var buf bytes.Buffer for _, se := range n.k.ListSockets() { s := se.Sock.Get() @@ -825,15 +840,22 @@ func (n *netUDP) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se s.DecRef(ctx) } - data := []seqfile.SeqData{ - { + minI := 0 + if h != nil { + minI = h.(int) + 1 + } + var data []seqfile.SeqData + if minI <= 0 { + data = append(data, seqfile.SeqData{ Buf: []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops \n"), - Handle: n, - }, - { + Handle: 0, + }) + } + if minI <= 1 { + data = append(data, seqfile.SeqData{ Buf: buf.Bytes(), - Handle: n, - }, + Handle: 1, + }) } return data, 0 } -- cgit v1.2.3