From 840c6e3d3d581dc2d9717a21d79b1fac8a0efee0 Mon Sep 17 00:00:00 2001 From: basavaraj-sm05 Date: Wed, 22 Jul 2026 16:23:58 +0530 Subject: [PATCH] net/netutil: confine ipForwardingEnabledLinux read with os.OpenInRoot Signed-off-by: basavaraj-sm05 --- net/netutil/ip_forward.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/netutil/ip_forward.go b/net/netutil/ip_forward.go index bc0f1961d..fd434a2d3 100644 --- a/net/netutil/ip_forward.go +++ b/net/netutil/ip_forward.go @@ -6,10 +6,10 @@ import ( "bytes" "fmt" + "io" "net/netip" "os" "os/exec" - "path/filepath" "runtime" "strconv" "strings" @@ -198,7 +198,10 @@ func ipForwardSysctlKey(format sysctlFormat, p protocol, iface string) string { // sysctl (which on Linux just reads from /proc/sys anyway). func ipForwardingEnabledLinux(p protocol, iface string) (bool, error) { k := ipForwardSysctlKey(slashFormat, p, iface) - bs, err := os.ReadFile(filepath.Join("/proc/sys", k)) + // Open k under /proc/sys with os.OpenInRoot so a ".." or symlinked + // component in the interface name can't read outside /proc/sys. It's + // openat-based, so it's also TOCTOU-resistant. See https://go.dev/blog/osroot. + f, err := os.OpenInRoot("/proc/sys", k) if err != nil { if os.IsNotExist(err) { // If IPv6 is disabled, sysctl keys like "net.ipv6.conf.all.forwarding" just don't @@ -213,6 +216,11 @@ func ipForwardingEnabledLinux(p protocol, iface string) (bool, error) { } return false, err } + defer f.Close() + bs, err := io.ReadAll(f) + if err != nil { + return false, err + } val, err := strconv.ParseInt(string(bytes.TrimSpace(bs)), 10, 32) if err != nil {