MCPcopy
hub / github.com/google/gvisor / Socket

Method Socket

pkg/sentry/socket/hostinet/socket.go:240–296  ·  view source on GitHub ↗

Socket implements socket.Provider.Socket.

(t *kernel.Task, stypeflags linux.SockType, protocol int)

Source from the content-addressed store, hash-verified

238
239// Socket implements socket.Provider.Socket.
240func (p *socketProvider) Socket(t *kernel.Task, stypeflags linux.SockType, protocol int) (*vfs.FileDescription, *syserr.Error) {
241 // Check that we are using the host network stack.
242 netCtx := t.NetworkContext()
243 if netCtx == nil {
244 return nil, nil
245 }
246 stack, ok := netCtx.(*Stack)
247 if !ok {
248 return nil, nil
249 }
250
251 stype := stypeflags & linux.SOCK_TYPE_MASK
252
253 // Raw and packet sockets require CAP_NET_RAW.
254 if stype == linux.SOCK_RAW || p.family == linux.AF_PACKET {
255 if !t.HasCapabilityIn(linux.CAP_NET_RAW, t.NetworkNamespace().UserNamespace()) {
256 return nil, syserr.ErrNotPermitted
257 }
258 }
259
260 // Convert generic IPPROTO_IP protocol to the actual protocol depending
261 // on family and type.
262 if protocol == linux.IPPROTO_IP && (p.family == linux.AF_INET || p.family == linux.AF_INET6) {
263 switch stype {
264 case linux.SOCK_STREAM:
265 protocol = linux.IPPROTO_TCP
266 case linux.SOCK_DGRAM:
267 protocol = linux.IPPROTO_UDP
268 }
269 }
270
271 // Validate the socket based on family, type, and protocol.
272 var supported bool
273 for _, allowed := range stack.allowedSocketTypes {
274 isAllowedFamily := p.family == allowed.Family
275 isAllowedType := int(stype) == allowed.Type
276 isAllowedProtocol := protocol == allowed.Protocol || allowed.Protocol == AllowAllProtocols
277 if isAllowedFamily && isAllowedType && isAllowedProtocol {
278 supported = true
279 break
280 }
281 }
282 if !supported {
283 // Return nil error here to give other socket providers a
284 // chance to create this socket.
285 return nil, nil
286 }
287
288 // Conservatively ignore all flags specified by the application and add
289 // SOCK_NONBLOCK since socketOperations requires it.
290 st := int(stype) | unix.SOCK_NONBLOCK | unix.SOCK_CLOEXEC
291 fd, err := unix.Socket(p.family, st, protocol)
292 if err != nil {
293 return nil, syserr.FromError(err)
294 }
295 return newSocket(t, p.family, stype, protocol, fd, uint32(stypeflags&unix.SOCK_NONBLOCK))
296}
297

Callers

nothing calls this directly

Calls 7

FromErrorFunction · 0.92
NetworkContextMethod · 0.80
newSocketFunction · 0.70
UserNamespaceMethod · 0.65
SocketMethod · 0.65
HasCapabilityInMethod · 0.45
NetworkNamespaceMethod · 0.45

Tested by

no test coverage detected