net/netutil: confine ipForwardingEnabledLinux read with os.OpenInRoot

Signed-off-by: basavaraj-sm05 <basavaraj@digiscrypt.com>
This commit is contained in:
basavaraj-sm05
2026-07-22 16:23:58 +05:30
committed by Brad Fitzpatrick
parent 5384d23690
commit 840c6e3d3d

View File

@@ -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 {