diff --git a/runconfig/opts/parse.go b/runconfig/opts/parse.go index cdd43499d0..5e287f18b3 100644 --- a/runconfig/opts/parse.go +++ b/runconfig/opts/parse.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "path" + "regexp" "strconv" "strings" @@ -248,6 +249,13 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host hostname = parts[0] domainname = parts[1] } + // Validate if the given hostname is RFC 1123 (https://tools.ietf.org/html/rfc1123) compliant. + if hostname != "" { + matched, _ := regexp.MatchString("^(([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])\\.)*([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])$", hostname) + if !matched { + return nil, nil, nil, cmd, fmt.Errorf("invalid hostname format for --hostname: %s", hostname) + } + } ports, portBindings, err := nat.ParsePortSpecs(flPublish.GetAll()) if err != nil { diff --git a/runconfig/opts/parse_test.go b/runconfig/opts/parse_test.go index 1da1deaa26..f4fbd26288 100644 --- a/runconfig/opts/parse_test.go +++ b/runconfig/opts/parse_test.go @@ -385,11 +385,30 @@ func TestParseWithMemorySwap(t *testing.T) { } func TestParseHostname(t *testing.T) { - hostname := "--hostname=hostname" + validHostnames := map[string]string{ + "hostname": "hostname", + "host-name": "host-name", + "hostname123": "hostname123", + "123hostname": "123hostname", + } + invalidHostnames := map[string]string{ + "^hostname": "invalid hostname format for --hostname: ^hostname", + "hostname%": "invalid hostname format for --hostname: hostname%", + "host&name": "invalid hostname format for --hostname: host&name", + "-hostname": "invalid hostname format for --hostname: -hostname", + "host_name": "invalid hostname format for --hostname: host_name", + } hostnameWithDomain := "--hostname=hostname.domainname" hostnameWithDomainTld := "--hostname=hostname.domainname.tld" - if config, _ := mustParse(t, hostname); config.Hostname != "hostname" && config.Domainname != "" { - t.Fatalf("Expected the config to have 'hostname' as hostname, got '%v'", config.Hostname) + for hostname, expectedHostname := range validHostnames { + if config, _ := mustParse(t, fmt.Sprintf("--hostname=%s", hostname)); config.Hostname != expectedHostname { + t.Fatalf("Expected the config to have 'hostname' as hostname, got '%v'", config.Hostname) + } + } + for hostname, expectedError := range invalidHostnames { + if _, _, err := parse(t, fmt.Sprintf("--hostname=%s", hostname)); err == nil || err.Error() != expectedError { + t.Fatalf("Expected error '%v' with '--hostname=%s', got '%s'", expectedError, hostname, err) + } } if config, _ := mustParse(t, hostnameWithDomain); config.Hostname != "hostname" && config.Domainname != "domainname" { t.Fatalf("Expected the config to have 'hostname' as hostname, got '%v'", config.Hostname)