mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #17851 from Microsoft/10662-ArgumentEscaping
Prevent double escaping of Dockerfile commands on Windows
This commit is contained in:
commit
ad8a66573c
9 changed files with 51 additions and 31 deletions
|
@ -104,6 +104,8 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.ArgsEscaped = false
|
||||||
|
|
||||||
if !*flDetach {
|
if !*flDetach {
|
||||||
if err := cli.CheckTtyInput(config.AttachStdin, config.Tty); err != nil {
|
if err := cli.CheckTtyInput(config.AttachStdin, config.Tty); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -389,6 +389,8 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
|
||||||
b.runConfig.Cmd = config.Cmd
|
b.runConfig.Cmd = config.Cmd
|
||||||
// set build-time environment for 'run'.
|
// set build-time environment for 'run'.
|
||||||
b.runConfig.Env = append(b.runConfig.Env, cmdBuildEnv...)
|
b.runConfig.Env = append(b.runConfig.Env, cmdBuildEnv...)
|
||||||
|
// set config as already being escaped, this prevents double escaping on windows
|
||||||
|
b.runConfig.ArgsEscaped = true
|
||||||
|
|
||||||
logrus.Debugf("[BUILDER] Command to be executed: %v", b.runConfig.Cmd)
|
logrus.Debugf("[BUILDER] Command to be executed: %v", b.runConfig.Cmd)
|
||||||
|
|
||||||
|
@ -479,7 +481,7 @@ func entrypoint(b *Builder, args []string, attributes map[string]bool, original
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
b.runConfig.Entrypoint = stringutils.NewStrSlice("/bin/sh", "-c", parsed[0])
|
b.runConfig.Entrypoint = stringutils.NewStrSlice("/bin/sh", "-c", parsed[0])
|
||||||
} else {
|
} else {
|
||||||
b.runConfig.Entrypoint = stringutils.NewStrSlice("cmd", "/S /C", parsed[0])
|
b.runConfig.Entrypoint = stringutils.NewStrSlice("cmd", "/S", "/C", parsed[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
b.runConfig.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
|
b.runConfig.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
|
||||||
} else {
|
} else {
|
||||||
b.runConfig.Cmd = stringutils.NewStrSlice("cmd", "/S /C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
|
b.runConfig.Cmd = stringutils.NewStrSlice("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
|
||||||
}
|
}
|
||||||
defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
|
||||||
LayerPaths: layerPaths,
|
LayerPaths: layerPaths,
|
||||||
Hostname: c.Config.Hostname,
|
Hostname: c.Config.Hostname,
|
||||||
Isolation: c.hostConfig.Isolation,
|
Isolation: c.hostConfig.Isolation,
|
||||||
|
ArgsEscaped: c.Config.ArgsEscaped,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -57,6 +57,7 @@ type Command struct {
|
||||||
LayerFolder string `json:"layer_folder"` // Layer folder for a command
|
LayerFolder string `json:"layer_folder"` // Layer folder for a command
|
||||||
LayerPaths []string `json:"layer_paths"` // Layer paths for a command
|
LayerPaths []string `json:"layer_paths"` // Layer paths for a command
|
||||||
Isolation runconfig.IsolationLevel `json:"isolation"` // Isolation level for the container
|
Isolation runconfig.IsolationLevel `json:"isolation"` // Isolation level for the container
|
||||||
|
ArgsEscaped bool `json:"args_escaped"` // True if args are already escaped
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExitStatus provides exit reasons for a container.
|
// ExitStatus provides exit reasons for a container.
|
||||||
|
|
36
daemon/execdriver/windows/commandlinebuilder.go
Normal file
36
daemon/execdriver/windows/commandlinebuilder.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//+build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/daemon/execdriver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// createCommandLine creates a command line from the Entrypoint and args
|
||||||
|
// of the ProcessConfig. It escapes the arguments if they are not already
|
||||||
|
// escaped
|
||||||
|
func createCommandLine(processConfig *execdriver.ProcessConfig, alreadyEscaped bool) (commandLine string, err error) {
|
||||||
|
// While this should get caught earlier, just in case, validate that we
|
||||||
|
// have something to run.
|
||||||
|
if processConfig.Entrypoint == "" {
|
||||||
|
return "", errors.New("No entrypoint specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the command line of the process
|
||||||
|
commandLine = processConfig.Entrypoint
|
||||||
|
logrus.Debugf("Entrypoint: %s", processConfig.Entrypoint)
|
||||||
|
for _, arg := range processConfig.Arguments {
|
||||||
|
logrus.Debugf("appending %s", arg)
|
||||||
|
if !alreadyEscaped {
|
||||||
|
arg = syscall.EscapeArg(arg)
|
||||||
|
}
|
||||||
|
commandLine += " " + arg
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("commandLine: %s", commandLine)
|
||||||
|
return commandLine, nil
|
||||||
|
}
|
|
@ -3,7 +3,6 @@
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
@ -34,22 +33,12 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
|
||||||
// Configure the environment for the process // Note NOT c.ProcessConfig.Tty
|
// Configure the environment for the process // Note NOT c.ProcessConfig.Tty
|
||||||
createProcessParms.Environment = setupEnvironmentVariables(processConfig.Env)
|
createProcessParms.Environment = setupEnvironmentVariables(processConfig.Env)
|
||||||
|
|
||||||
// While this should get caught earlier, just in case, validate that we
|
createProcessParms.CommandLine, err = createCommandLine(&c.ProcessConfig, c.ArgsEscaped)
|
||||||
// have something to run.
|
|
||||||
if processConfig.Entrypoint == "" {
|
if err != nil {
|
||||||
err = errors.New("No entrypoint specified")
|
|
||||||
logrus.Error(err)
|
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the command line of the process
|
|
||||||
createProcessParms.CommandLine = processConfig.Entrypoint
|
|
||||||
for _, arg := range processConfig.Arguments {
|
|
||||||
logrus.Debugln("appending ", arg)
|
|
||||||
createProcessParms.CommandLine += " " + arg
|
|
||||||
}
|
|
||||||
logrus.Debugln("commandLine: ", createProcessParms.CommandLine)
|
|
||||||
|
|
||||||
// Start the command running in the container.
|
// Start the command running in the container.
|
||||||
pid, stdin, stdout, stderr, rc, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms)
|
pid, stdin, stdout, stderr, rc, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,13 +4,11 @@ package windows
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/daemon/execdriver"
|
"github.com/docker/docker/daemon/execdriver"
|
||||||
|
@ -273,22 +271,12 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||||
// Configure the environment for the process
|
// Configure the environment for the process
|
||||||
createProcessParms.Environment = setupEnvironmentVariables(c.ProcessConfig.Env)
|
createProcessParms.Environment = setupEnvironmentVariables(c.ProcessConfig.Env)
|
||||||
|
|
||||||
// This should get caught earlier, but just in case - validate that we
|
createProcessParms.CommandLine, err = createCommandLine(&c.ProcessConfig, c.ArgsEscaped)
|
||||||
// have something to run
|
|
||||||
if c.ProcessConfig.Entrypoint == "" {
|
if err != nil {
|
||||||
err = errors.New("No entrypoint specified")
|
|
||||||
logrus.Error(err)
|
|
||||||
return execdriver.ExitStatus{ExitCode: -1}, err
|
return execdriver.ExitStatus{ExitCode: -1}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the command line of the process
|
|
||||||
createProcessParms.CommandLine = c.ProcessConfig.Entrypoint
|
|
||||||
for _, arg := range c.ProcessConfig.Arguments {
|
|
||||||
logrus.Debugln("appending ", arg)
|
|
||||||
createProcessParms.CommandLine += " " + syscall.EscapeArg(arg)
|
|
||||||
}
|
|
||||||
logrus.Debugf("CommandLine: %s", createProcessParms.CommandLine)
|
|
||||||
|
|
||||||
// Start the command running in the container.
|
// Start the command running in the container.
|
||||||
pid, stdin, stdout, stderr, _, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !c.ProcessConfig.Tty, createProcessParms)
|
pid, stdin, stdout, stderr, _, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !c.ProcessConfig.Tty, createProcessParms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -30,6 +30,7 @@ type Config struct {
|
||||||
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
||||||
Env []string // List of environment variable to set in the container
|
Env []string // List of environment variable to set in the container
|
||||||
Cmd *stringutils.StrSlice // Command to run when starting the container
|
Cmd *stringutils.StrSlice // Command to run when starting the container
|
||||||
|
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific)
|
||||||
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
|
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
|
||||||
Volumes map[string]struct{} // List of volumes (mounts) used for the container
|
Volumes map[string]struct{} // List of volumes (mounts) used for the container
|
||||||
WorkingDir string // Current directory (PWD) in the command will be launched
|
WorkingDir string // Current directory (PWD) in the command will be launched
|
||||||
|
|
Loading…
Add table
Reference in a new issue