gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/socket/netlink/provider.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 netlink 16 17 import ( 18 "fmt" 19 20 "gvisor.dev/gvisor/pkg/abi/linux" 21 "gvisor.dev/gvisor/pkg/context" 22 "gvisor.dev/gvisor/pkg/sentry/fsimpl/sockfs" 23 "gvisor.dev/gvisor/pkg/sentry/kernel" 24 "gvisor.dev/gvisor/pkg/sentry/socket" 25 "gvisor.dev/gvisor/pkg/sentry/socket/netlink/nlmsg" 26 "gvisor.dev/gvisor/pkg/sentry/vfs" 27 "gvisor.dev/gvisor/pkg/syserr" 28 ) 29 30 // Protocol is the implementation of a netlink socket protocol. 31 type Protocol interface { 32 // Protocol returns the Linux netlink protocol value. 33 Protocol() int 34 35 // CanSend returns true if this protocol may ever send messages. 36 // 37 // TODO(gvisor.dev/issue/1119): This is a workaround to allow 38 // advertising support for otherwise unimplemented features on sockets 39 // that will never send messages, thus making those features no-ops. 40 CanSend() bool 41 42 // ProcessMessage processes a single message from userspace. 43 // 44 // If err == nil, any messages added to ms will be sent back to the 45 // other end of the socket. Setting ms.Multi will cause an NLMSG_DONE 46 // message to be sent even if ms contains no messages. 47 ProcessMessage(ctx context.Context, msg *nlmsg.Message, ms *nlmsg.MessageSet) *syserr.Error 48 } 49 50 // Provider is a function that creates a new Protocol for a specific netlink 51 // protocol. 52 // 53 // Note that this is distinct from socket.Provider, which is used for all 54 // socket families. 55 type Provider func(t *kernel.Task) (Protocol, *syserr.Error) 56 57 // protocols holds a map of all known address protocols and their provider. 58 var protocols = make(map[int]Provider) 59 60 // RegisterProvider registers the provider of a given address protocol so that 61 // netlink sockets of that type can be created via socket(2). 62 // 63 // Preconditions: May only be called before any netlink sockets are created. 64 func RegisterProvider(protocol int, provider Provider) { 65 if p, ok := protocols[protocol]; ok { 66 panic(fmt.Sprintf("Netlink protocol %d already provided by %+v", protocol, p)) 67 } 68 69 protocols[protocol] = provider 70 } 71 72 // socketProvider implements socket.Provider. 73 type socketProvider struct { 74 } 75 76 // Socket implements socket.Provider.Socket. 77 func (*socketProvider) Socket(t *kernel.Task, stype linux.SockType, protocol int) (*vfs.FileDescription, *syserr.Error) { 78 // Netlink sockets must be specified as datagram or raw, but they 79 // behave the same regardless of type. 80 if stype != linux.SOCK_DGRAM && stype != linux.SOCK_RAW { 81 return nil, syserr.ErrSocketNotSupported 82 } 83 84 provider, ok := protocols[protocol] 85 if !ok { 86 return nil, syserr.ErrProtocolNotSupported 87 } 88 89 p, err := provider(t) 90 if err != nil { 91 return nil, err 92 } 93 94 s, err := New(t, stype, p) 95 if err != nil { 96 return nil, err 97 } 98 99 vfsfd := &s.vfsfd 100 mnt := t.Kernel().SocketMount() 101 d := sockfs.NewDentry(t, mnt) 102 defer d.DecRef(t) 103 if err := vfsfd.Init(s, linux.O_RDWR, mnt, d, &vfs.FileDescriptionOptions{ 104 DenyPRead: true, 105 DenyPWrite: true, 106 UseDentryMetadata: true, 107 }); err != nil { 108 return nil, syserr.FromError(err) 109 } 110 return vfsfd, nil 111 } 112 113 // Pair implements socket.Provider.Pair by returning an error. 114 func (*socketProvider) Pair(*kernel.Task, linux.SockType, int) (*vfs.FileDescription, *vfs.FileDescription, *syserr.Error) { 115 // Netlink sockets never supports creating socket pairs. 116 return nil, nil, syserr.ErrNotSupported 117 } 118 119 // init registers the socket provider. 120 func init() { 121 socket.RegisterProvider(linux.AF_NETLINK, &socketProvider{}) 122 }