github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/sentry/socket/unix/io.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package unix 16 17 import ( 18 "github.com/nicocha30/gvisor-ligolo/pkg/context" 19 "github.com/nicocha30/gvisor-ligolo/pkg/safemem" 20 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/socket/unix/transport" 21 ) 22 23 // EndpointWriter implements safemem.Writer that writes to a transport.Endpoint. 24 // 25 // EndpointWriter is not thread-safe. 26 type EndpointWriter struct { 27 Ctx context.Context 28 29 // Endpoint is the transport.Endpoint to write to. 30 Endpoint transport.Endpoint 31 32 // Control is the control messages to send. 33 Control transport.ControlMessages 34 35 // To is the endpoint to send to. May be nil. 36 To transport.BoundEndpoint 37 38 // Notify is the receiver.SendNotify notification callback that is set 39 // by WriteFromBlocks and should be called without mm.activeMu held 40 // (i.e. after CopyOut completes). 41 Notify func() 42 } 43 44 // WriteFromBlocks implements safemem.Writer.WriteFromBlocks. 45 func (w *EndpointWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, error) { 46 return safemem.FromVecWriterFunc{func(bufs [][]byte) (int64, error) { 47 n, notify, err := w.Endpoint.SendMsg(w.Ctx, bufs, w.Control, w.To) 48 w.Notify = notify 49 if err != nil { 50 return int64(n), err.ToError() 51 } 52 return int64(n), nil 53 }}.WriteFromBlocks(srcs) 54 } 55 56 // EndpointReader implements safemem.Reader that reads from a 57 // transport.Endpoint. 58 // 59 // EndpointReader is not thread-safe. 60 type EndpointReader struct { 61 Ctx context.Context 62 63 // Endpoint is the transport.Endpoint to read from. 64 Endpoint transport.Endpoint 65 66 // Creds indicates if credential control messages are requested. 67 Creds bool 68 69 // NumRights is the number of SCM_RIGHTS FDs requested. 70 NumRights int 71 72 // Peek indicates that the data should not be consumed from the 73 // endpoint. 74 Peek bool 75 76 // MsgSize is the size of the message that was read from. For stream 77 // sockets, it is the amount read. 78 MsgSize int64 79 80 // From, if not nil, will be set with the address read from. 81 From *transport.Address 82 83 // Control contains the received control messages. 84 Control transport.ControlMessages 85 86 // ControlTrunc indicates that SCM_RIGHTS FDs were discarded based on 87 // the value of NumRights. 88 ControlTrunc bool 89 90 // Notify is the ConnectedEndpoint.RecvNotify callback that is set by 91 // ReadToBlocks and should be called without mm.activeMu held (i.e. 92 // after CopyIn completes). 93 Notify func() 94 } 95 96 // Truncate calls RecvMsg on the endpoint without writing to a destination. 97 func (r *EndpointReader) Truncate() error { 98 // Ignore bytes read since it will always be zero. 99 _, ms, c, ct, notify, err := r.Endpoint.RecvMsg(r.Ctx, [][]byte{}, r.Creds, r.NumRights, r.Peek, r.From) 100 r.Control = c 101 r.ControlTrunc = ct 102 r.MsgSize = ms 103 if notify != nil { 104 notify() 105 } 106 if err != nil { 107 return err.ToError() 108 } 109 return nil 110 } 111 112 // ReadToBlocks implements safemem.Reader.ReadToBlocks. 113 func (r *EndpointReader) ReadToBlocks(dsts safemem.BlockSeq) (uint64, error) { 114 return safemem.FromVecReaderFunc{func(bufs [][]byte) (int64, error) { 115 n, ms, c, ct, notify, err := r.Endpoint.RecvMsg(r.Ctx, bufs, r.Creds, r.NumRights, r.Peek, r.From) 116 r.Control = c 117 r.ControlTrunc = ct 118 r.MsgSize = ms 119 r.Notify = notify 120 if err != nil { 121 return int64(n), err.ToError() 122 } 123 return int64(n), nil 124 }}.ReadToBlocks(dsts) 125 }