util/linuxfw: fix nil pointer panic in connmark rules without IPv6 (#18946)

When IPv6 is unavailable on a system, AddConnmarkSaveRule() and
DelConnmarkSaveRule() would panic with a nil pointer dereference.
Both methods directly iterated over []iptablesInterface{i.ipt4, i.ipt6}
without checking if ipt6 was nil.

Use `getTables()` instead to properly retrieve the available tables
on a given system

Fixes #3310

Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This commit is contained in:
Mike O'Driscoll
2026-03-10 15:19:15 -04:00
committed by GitHub
parent 525f7a1e47
commit 021de2e1bc
3 changed files with 154 additions and 12 deletions
+4 -4
View File
@@ -533,7 +533,7 @@ func (i *iptablesRunner) DelStatefulRule(tunname string) error {
// proper routing table lookups for exit nodes and subnet routers.
func (i *iptablesRunner) AddConnmarkSaveRule() error {
// Check if rules already exist (idempotency)
for _, ipt := range []iptablesInterface{i.ipt4, i.ipt6} {
for _, ipt := range i.getTables() {
rules, err := ipt.List("mangle", "PREROUTING")
if err != nil {
continue
@@ -551,7 +551,7 @@ func (i *iptablesRunner) AddConnmarkSaveRule() error {
// mangle/PREROUTING: Restore mark from conntrack for ESTABLISHED/RELATED connections
// This runs BEFORE routing decision and rp_filter check
for _, ipt := range []iptablesInterface{i.ipt4, i.ipt6} {
for _, ipt := range i.getTables() {
args := []string{
"-m", "conntrack",
"--ctstate", "ESTABLISHED,RELATED",
@@ -566,7 +566,7 @@ func (i *iptablesRunner) AddConnmarkSaveRule() error {
}
// mangle/OUTPUT: Save mark to conntrack for NEW connections with non-zero marks
for _, ipt := range []iptablesInterface{i.ipt4, i.ipt6} {
for _, ipt := range i.getTables() {
args := []string{
"-m", "conntrack",
"--ctstate", "NEW",
@@ -587,7 +587,7 @@ func (i *iptablesRunner) AddConnmarkSaveRule() error {
// DelConnmarkSaveRule removes conntrack marking rules added by AddConnmarkSaveRule.
func (i *iptablesRunner) DelConnmarkSaveRule() error {
for _, ipt := range []iptablesInterface{i.ipt4, i.ipt6} {
for _, ipt := range i.getTables() {
// Delete PREROUTING rule
args := []string{
"-m", "conntrack",