Merge pull request #3051 from greatroar/sanitize-env

Sanitize environment before starting backend processes (rclone, ssh)
This commit is contained in:
Alexander Neumann 2020-11-02 21:18:57 +01:00 committed by GitHub
commit 9a88fb253b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 12 deletions

View file

@ -0,0 +1,26 @@
package backend
import (
"os"
"os/exec"
"strings"
)
// StartForeground runs cmd in the foreground, by temporarily switching to the
// new process group created for cmd. The returned function `bg` switches back
// to the previous process group.
//
// The command's environment has all RESTIC_* variables removed.
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
env := os.Environ() // Returns a copy that we can modify.
cmd.Env = env[:0]
for _, kv := range env {
if strings.HasPrefix(kv, "RESTIC_") {
continue
}
cmd.Env = append(cmd.Env, kv)
}
return startForeground(cmd)
}

View file

@ -7,10 +7,7 @@ import (
"github.com/restic/restic/internal/errors"
)
// StartForeground runs cmd in the foreground, by temporarily switching to the
// new process group created for cmd. The returned function `bg` switches back
// to the previous process group.
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
// run the command in it's own process group so that SIGINT
// is not sent to it.
cmd.SysProcAttr = &syscall.SysProcAttr{

View file

@ -0,0 +1,38 @@
// +build !windows
package backend_test
import (
"bufio"
"os"
"os/exec"
"strings"
"testing"
"github.com/restic/restic/internal/backend"
rtest "github.com/restic/restic/internal/test"
)
func TestForeground(t *testing.T) {
err := os.Setenv("RESTIC_PASSWORD", "supersecret")
rtest.OK(t, err)
cmd := exec.Command("env")
stdout, err := cmd.StdoutPipe()
rtest.OK(t, err)
bg, err := backend.StartForeground(cmd)
rtest.OK(t, err)
defer cmd.Wait()
err = bg()
rtest.OK(t, err)
sc := bufio.NewScanner(stdout)
for sc.Scan() {
if strings.HasPrefix(sc.Text(), "RESTIC_PASSWORD=") {
t.Error("subprocess got to see the password")
}
}
rtest.OK(t, err)
}

View file

@ -24,10 +24,7 @@ func tcsetpgrp(fd int, pid int) error {
return errno
}
// StartForeground runs cmd in the foreground, by temporarily switching to the
// new process group created for cmd. The returned function `bg` switches back
// to the previous process group.
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
// open the TTY, we need the file descriptor
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {

View file

@ -6,10 +6,7 @@ import (
"github.com/restic/restic/internal/errors"
)
// StartForeground runs cmd in the foreground, by temporarily switching to the
// new process group created for cmd. The returned function `bg` switches back
// to the previous process group.
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
// just start the process and hope for the best
err = cmd.Start()
if err != nil {