logpolicy: fix nil pointer dereference with invalid TS_LOG_TARGET
When TS_LOG_TARGET is set to an invalid URL, url.Parse returns an error and nil pointer, which caused a panic when accessing u.Host. Now we check the error from url.Parse and log a helpful message while falling back to the default log host. Fixes #17792 Signed-off-by: Andrew Dunham <andrew@tailscale.com>
This commit is contained in:
committed by
Andrew Dunham
parent
052602752f
commit
208a32af5b
+10
-4
@@ -640,10 +640,16 @@ func (opts Options) init(disableLogging bool) (*logtail.Config, *Policy) {
|
|||||||
|
|
||||||
logHost := logtail.DefaultHost
|
logHost := logtail.DefaultHost
|
||||||
if val := getLogTarget(); val != "" {
|
if val := getLogTarget(); val != "" {
|
||||||
opts.Logf("You have enabled a non-default log target. Doing without being told to by Tailscale staff or your network administrator will make getting support difficult.")
|
u, err := url.Parse(val)
|
||||||
conf.BaseURL = val
|
if err != nil {
|
||||||
u, _ := url.Parse(val)
|
opts.Logf("logpolicy: invalid TS_LOG_TARGET %q: %v; using default log host", val, err)
|
||||||
logHost = u.Host
|
} else if u.Host == "" {
|
||||||
|
opts.Logf("logpolicy: invalid TS_LOG_TARGET %q: missing host; using default log host", val)
|
||||||
|
} else {
|
||||||
|
opts.Logf("You have enabled a non-default log target. Doing without being told to by Tailscale staff or your network administrator will make getting support difficult.")
|
||||||
|
conf.BaseURL = val
|
||||||
|
logHost = u.Host
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.HTTPC == nil {
|
if conf.HTTPC == nil {
|
||||||
|
|||||||
@@ -84,3 +84,47 @@ func TestOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestInvalidLogTarget is a test for #17792
|
||||||
|
func TestInvalidLogTarget(t *testing.T) {
|
||||||
|
defer resetLogTarget()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
logTarget string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "invalid_url_no_scheme",
|
||||||
|
logTarget: "not a url at all",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "malformed_url",
|
||||||
|
logTarget: "ht!tp://invalid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
resetLogTarget()
|
||||||
|
os.Setenv("TS_LOG_TARGET", tt.logTarget)
|
||||||
|
|
||||||
|
opts := Options{
|
||||||
|
Collection: "test.log.tailscale.io",
|
||||||
|
Logf: t.Logf,
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not panic even with invalid log target
|
||||||
|
config, policy := opts.init(false)
|
||||||
|
if policy == nil {
|
||||||
|
t.Fatal("expected non-nil policy")
|
||||||
|
}
|
||||||
|
defer policy.Close()
|
||||||
|
|
||||||
|
// When log target is invalid, it should fall back to the invalid value
|
||||||
|
// but not crash. BaseURL should remain empty
|
||||||
|
if config.BaseURL != "" {
|
||||||
|
t.Errorf("got BaseURL=%q, want empty", config.BaseURL)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user