зеркало из https://github.com/mozilla/mig.git
[medium] prevent agentdestroy module from removing executable in use
This commit is contained in:
Родитель
4665b20349
Коммит
ddbf9745ee
|
@ -5,12 +5,12 @@
|
||||||
// Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]
|
// Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]
|
||||||
|
|
||||||
// agentdestroy is a module used in the upgrade protocol to kill an agent
|
// agentdestroy is a module used in the upgrade protocol to kill an agent
|
||||||
// that has been upgraded, and remove its binary from the file system.
|
// that has been upgraded. This module will refuse to suicide, meaning that
|
||||||
// The only sanity check it does, aside from validating the parameters, is
|
// an agent will not run this module against itself
|
||||||
// refusing to suicide. Meaning an agent will not run this module against itself.
|
|
||||||
package agentdestroy
|
package agentdestroy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bitbucket.org/kardianos/osext"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"mig"
|
"mig"
|
||||||
|
@ -77,35 +77,50 @@ func (r Runner) Run(Args []byte) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the path of the agent's executable
|
// get the path of the agent's executable
|
||||||
var binary string
|
var targetExecutable string
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "linux", "darwin", "freebsd", "openbsd", "netbsd":
|
case "linux", "darwin", "freebsd", "openbsd", "netbsd":
|
||||||
binary, err = os.Readlink(fmt.Sprintf("/proc/%d/exe", r.Parameters.PID))
|
targetExecutable, err = os.Readlink(fmt.Sprintf("/proc/%d/exe", r.Parameters.PID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Binary path of PID '%d' not found: '%v'", r.Parameters.PID, err))
|
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Executable path of PID '%d' not found: '%v'", r.Parameters.PID, err))
|
||||||
return r.buildResults()
|
return r.buildResults()
|
||||||
}
|
}
|
||||||
case "windows":
|
case "windows":
|
||||||
binary = fmt.Sprintf("C:/Windows/mig-agent-%s.exe", r.Parameters.Version)
|
targetExecutable = fmt.Sprintf("C:/Windows/mig-agent-%s.exe", r.Parameters.Version)
|
||||||
default:
|
default:
|
||||||
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("'%s' isn't a supported OS", runtime.GOOS))
|
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("'%s' isn't a supported OS", runtime.GOOS))
|
||||||
return r.buildResults()
|
return r.buildResults()
|
||||||
}
|
}
|
||||||
|
// verify that the executable we're removing isn't in use by the current agent
|
||||||
|
// this can happen when two agents are running of the same executable
|
||||||
|
// in which case, do not remove the executable, and only kill the process
|
||||||
|
myExecutable, err := osext.Executable()
|
||||||
|
if err != nil {
|
||||||
|
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Failed to retrieve my executable location: '%v'", err))
|
||||||
|
return r.buildResults()
|
||||||
|
}
|
||||||
|
removeExecutable := true
|
||||||
|
if myExecutable == targetExecutable {
|
||||||
|
r.Results.Errors = append(r.Results.Errors, "Executable not removed because current agent uses it as well")
|
||||||
|
removeExecutable = false
|
||||||
|
}
|
||||||
|
|
||||||
// check that the binary we're removing has the right version
|
if removeExecutable {
|
||||||
version, err := getAgentVersion(binary)
|
// check that the binary we're removing has the right version
|
||||||
if err != nil {
|
version, err := getAgentVersion(targetExecutable)
|
||||||
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Failed to check agent version: '%v'", err))
|
if err != nil {
|
||||||
return r.buildResults()
|
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Failed to check agent version: '%v'", err))
|
||||||
}
|
return r.buildResults()
|
||||||
if version != r.Parameters.Version {
|
}
|
||||||
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Version mismatch. Expected '%s', found '%s'", r.Parameters.Version, version))
|
if version != r.Parameters.Version {
|
||||||
return r.buildResults()
|
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Version mismatch. Expected '%s', found '%s'", r.Parameters.Version, version))
|
||||||
}
|
return r.buildResults()
|
||||||
err = os.Remove(binary)
|
}
|
||||||
if err != nil {
|
err = os.Remove(targetExecutable)
|
||||||
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Failed to remove binary '%s': '%v'", binary, err))
|
if err != nil {
|
||||||
return r.buildResults()
|
r.Results.Errors = append(r.Results.Errors, fmt.Sprintf("Failed to remove executable '%s': '%v'", targetExecutable, err))
|
||||||
|
return r.buildResults()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then kill the PID
|
// Then kill the PID
|
||||||
|
|
Загрузка…
Ссылка в новой задаче