Skip to content
46 changes: 46 additions & 0 deletions pkg/sentry/fsimpl/proc/tasks_sys.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ func (fs *filesystem) newSysNetDir(ctx context.Context, root *auth.Credentials,
// network namespace of the calling process.
if stack := k.RootNetworkNamespace().Stack(); stack != nil {
contents = map[string]kernfs.Inode{
"ipv6": fs.newStaticDir(ctx, root, map[string]kernfs.Inode{
"conf": fs.newStaticDir(ctx, root, map[string]kernfs.Inode{
"all": fs.newStaticDir(ctx, root, map[string]kernfs.Inode{
"keep_addr_on_down": fs.newInode(ctx, root, 0644, &ipv6KeepAddrOnDown{stack: stack}),
}),
}),
}),
"ipv4": fs.newStaticDir(ctx, root, map[string]kernfs.Inode{
"ip_forward": fs.newInode(ctx, root, 0444, &ipForwarding{stack: stack}),
"ip_local_port_range": fs.newInode(ctx, root, 0644, &portRange{stack: stack}),
Expand Down Expand Up @@ -233,6 +240,45 @@ func (*uuidData) Generate(ctx context.Context, buf *bytes.Buffer) error {
return nil
}

// ipv6KeepAddrOnDown implements vfs.WritableDynamicBytesSource for
// /proc/sys/net/ipv6/conf/all/keep_addr_on_down.
//
// +stateify savable
type ipv6KeepAddrOnDown struct {
kernfs.DynamicBytesFile

stack inet.Stack `state:"wait"`
}

var _ vfs.WritableDynamicBytesSource = (*ipv6KeepAddrOnDown)(nil)

// Generate implements vfs.DynamicBytesSource.Generate.
func (d *ipv6KeepAddrOnDown) Generate(ctx context.Context, buf *bytes.Buffer) error {
val := "0\n"
if d.stack.IPv6KeepAddrOnDown() {
val = "1\n"
}
_, err := buf.WriteString(val)
return err
}

// Write implements vfs.WritableDynamicBytesSource.Write.
func (d *ipv6KeepAddrOnDown) Write(ctx context.Context, _ *vfs.FileDescription, src usermem.IOSequence, offset int64) (int64, error) {
if offset != 0 {
// No need to handle partial writes thus far.
return 0, linuxerr.EINVAL
}
buf := make([]int32, 1)
n, err := ParseInt32Vec(ctx, src, buf)
if err != nil || n == 0 {
return 0, err
}
if err := d.stack.SetIPv6KeepAddrOnDown(buf[0] != 0); err != nil {
return 0, err
}
return n, nil
}

// tcpSackData implements vfs.WritableDynamicBytesSource for
// /proc/sys/net/tcp_sack.
//
Expand Down
7 changes: 7 additions & 0 deletions pkg/sentry/inet/inet.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ type Stack interface {
// SupportsIPv6 returns true if the stack supports IPv6 connectivity.
SupportsIPv6() bool

// IPv6KeepAddrOnDown returns true if IPv6 should keep permanent, non-local
// addresses when an interface goes down.
IPv6KeepAddrOnDown() bool

// SetIPv6KeepAddrOnDown changes IPv6 keep_addr_on_down behavior.
SetIPv6KeepAddrOnDown(bool) error

// TCPReceiveBufferSize returns TCP receive buffer size settings.
TCPReceiveBufferSize() (TCPBufferSize, error)

Expand Down
30 changes: 21 additions & 9 deletions pkg/sentry/inet/test_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ var _ Stack = (*TestStack)(nil)

// TestStack is a dummy implementation of Stack for tests.
type TestStack struct {
InterfacesMap map[int32]Interface
InterfaceAddrsMap map[int32][]InterfaceAddr
RouteList []Route
SupportsIPv6Flag bool
TCPRecvBufSize TCPBufferSize
TCPSendBufSize TCPBufferSize
TCPSACKFlag bool
Recovery TCPLossRecovery
IPForwarding bool
InterfacesMap map[int32]Interface
InterfaceAddrsMap map[int32][]InterfaceAddr
RouteList []Route
SupportsIPv6Flag bool
TCPRecvBufSize TCPBufferSize
TCPSendBufSize TCPBufferSize
TCPSACKFlag bool
Recovery TCPLossRecovery
IPForwarding bool
IPv6KeepAddrOnDownFlag bool
}

// NewTestStack returns a TestStack with no network interfaces. The value of
Expand Down Expand Up @@ -114,6 +115,17 @@ func (s *TestStack) SupportsIPv6() bool {
return s.SupportsIPv6Flag
}

// IPv6KeepAddrOnDown implements Stack.
func (s *TestStack) IPv6KeepAddrOnDown() bool {
return s.IPv6KeepAddrOnDownFlag
}

// SetIPv6KeepAddrOnDown implements Stack.
func (s *TestStack) SetIPv6KeepAddrOnDown(enabled bool) error {
s.IPv6KeepAddrOnDownFlag = enabled
return nil
}

// TCPReceiveBufferSize implements Stack.
func (s *TestStack) TCPReceiveBufferSize() (TCPBufferSize, error) {
return s.TCPRecvBufSize, nil
Expand Down
23 changes: 23 additions & 0 deletions pkg/sentry/socket/hostinet/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type Stack struct {
netSNMPFile *os.File
// allowedSocketTypes is the list of allowed socket types
allowedSocketTypes []AllowedSocketType
ipv6KeepAddrOnDown bool
Comment thread
lyphyser marked this conversation as resolved.
}

// Destroy implements inet.Stack.Destroy.
Expand Down Expand Up @@ -112,6 +113,18 @@ func (s *Stack) Configure(allowRawSockets bool) error {
s.netSNMPFile = f
}

// keep_addr_on_down is >0 when enabled, and 0 (system default) or <0 when
// disabled.
if contents, err := os.ReadFile("/proc/sys/net/ipv6/conf/all/keep_addr_on_down"); err == nil {
Comment thread
manninglucas marked this conversation as resolved.
if ipv6KeepAddrOnDown, err := strconv.Atoi(strings.TrimSpace(string(contents))); err == nil {
s.ipv6KeepAddrOnDown = ipv6KeepAddrOnDown > 0
} else {
log.Warningf("Failed to parse IPv6 keep_addr_on_down, setting to false")
}
} else {
log.Warningf("Failed to read IPv6 keep_addr_on_down, setting to false")
}

s.allowedSocketTypes = AllowedSocketTypes
if allowRawSockets {
s.allowedSocketTypes = append(s.allowedSocketTypes, AllowedRawSocketTypes...)
Expand Down Expand Up @@ -248,6 +261,16 @@ func (s *Stack) SupportsIPv6() bool {
return s.supportsIPv6
}

// IPv6KeepAddrOnDown implements inet.Stack.IPv6KeepAddrOnDown.
func (s *Stack) IPv6KeepAddrOnDown() bool {
return s.ipv6KeepAddrOnDown
}

// SetIPv6KeepAddrOnDown implements inet.Stack.SetIPv6KeepAddrOnDown.
func (*Stack) SetIPv6KeepAddrOnDown(bool) error {
return linuxerr.EACCES
}

// TCPReceiveBufferSize implements inet.Stack.TCPReceiveBufferSize.
func (s *Stack) TCPReceiveBufferSize() (inet.TCPBufferSize, error) {
return s.tcpRecvBufSize, nil
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/socket/netstack/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ go_library(
":events_go_proto",
"//pkg/abi/linux",
"//pkg/abi/linux/errno",
"//pkg/atomicbitops",
"//pkg/context",
"//pkg/errors/linuxerr",
"//pkg/eventchannel",
Expand Down
Loading