diff options
author | Kevin Krakauer <krakauer@google.com> | 2021-07-15 15:32:22 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-07-15 15:34:34 -0700 |
commit | cd45d7b6c893aa763cdc3ef2f4ac86444b622927 (patch) | |
tree | 64f2b18f3d9fa7ab4f0e5c0b3ac6b58b4f731b1d /pkg | |
parent | 67d9050752ca99f1194ecd31bc2dfce470a404aa (diff) |
netstack: support SO_RCVBUFFORCE
TCP is fully supported. As with SO_RCVBUF, other transport protocols perform
no-ops per DefaultSocketOptionsHandler.OnSetReceiveBufferSize.
PiperOrigin-RevId: 385023239
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/sentry/socket/netstack/netstack.go | 24 | ||||
-rw-r--r-- | pkg/sentry/socket/socket.go | 1 | ||||
-rw-r--r-- | pkg/tcpip/socketops.go | 2 |
3 files changed, 21 insertions, 6 deletions
diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index ea736e446..0f8cbe7e2 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -49,6 +49,7 @@ import ( "gvisor.dev/gvisor/pkg/sentry/fs/fsutil" "gvisor.dev/gvisor/pkg/sentry/inet" "gvisor.dev/gvisor/pkg/sentry/kernel" + "gvisor.dev/gvisor/pkg/sentry/kernel/auth" ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time" "gvisor.dev/gvisor/pkg/sentry/socket" "gvisor.dev/gvisor/pkg/sentry/socket/netfilter" @@ -1682,12 +1683,12 @@ func SetSockOpt(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, level int return nil } -func clampBufSize(newSz, min, max int64) int64 { +func clampBufSize(newSz, min, max int64, ignoreMax bool) int64 { // packetOverheadFactor is used to multiply the value provided by the user on // a setsockopt(2) for setting the send/receive buffer sizes sockets. const packetOverheadFactor = 2 - if newSz > max { + if !ignoreMax && newSz > max { newSz = max } @@ -1712,7 +1713,7 @@ func setSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam v := hostarch.ByteOrder.Uint32(optVal) min, max := ep.SocketOptions().SendBufferLimits() - clamped := clampBufSize(int64(v), min, max) + clamped := clampBufSize(int64(v), min, max, false /* ignoreMax */) ep.SocketOptions().SetSendBufferSize(clamped, true /* notify */) return nil @@ -1723,7 +1724,22 @@ func setSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam v := hostarch.ByteOrder.Uint32(optVal) min, max := ep.SocketOptions().ReceiveBufferLimits() - clamped := clampBufSize(int64(v), min, max) + clamped := clampBufSize(int64(v), min, max, false /* ignoreMax */) + ep.SocketOptions().SetReceiveBufferSize(clamped, true /* notify */) + return nil + + case linux.SO_RCVBUFFORCE: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + if creds := auth.CredentialsFromContext(t); !creds.HasCapability(linux.CAP_NET_ADMIN) { + return syserr.ErrNotPermitted + } + + v := hostarch.ByteOrder.Uint32(optVal) + min, max := ep.SocketOptions().ReceiveBufferLimits() + clamped := clampBufSize(int64(v), min, max, true /* ignoreMax */) ep.SocketOptions().SetReceiveBufferSize(clamped, true /* notify */) return nil diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index f5da3c509..658e90bb9 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -509,7 +509,6 @@ func SetSockOptEmitUnimplementedEvent(t *kernel.Task, name int) { linux.SO_ATTACH_REUSEPORT_EBPF, linux.SO_CNX_ADVICE, linux.SO_DETACH_FILTER, - linux.SO_RCVBUFFORCE, linux.SO_SNDBUFFORCE: t.Kernel().EmitUnimplementedEvent(t) diff --git a/pkg/tcpip/socketops.go b/pkg/tcpip/socketops.go index 042326a3a..5642c86f8 100644 --- a/pkg/tcpip/socketops.go +++ b/pkg/tcpip/socketops.go @@ -54,7 +54,7 @@ type SocketOptionsHandler interface { // buffer size. It also returns the newly set value. OnSetSendBufferSize(v int64) (newSz int64) - // OnSetReceiveBufferSize is invoked to set the SO_RCVBUFSIZE. + // OnSetReceiveBufferSize is invoked by SO_RCVBUF and SO_RCVBUFFORCE. OnSetReceiveBufferSize(v, oldSz int64) (newSz int64) } |