Set Setpgid on child git processes (#19865) (#19881)

This commit is contained in:
zeripath 2022-06-04 04:39:15 +01:00 committed by GitHub
parent daf14b275a
commit 736b7b25a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 50 additions and 4 deletions

View File

@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/pprof" "code.gitea.io/gitea/modules/pprof"
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/lfs" "code.gitea.io/gitea/services/lfs"
@ -247,7 +248,7 @@ func runServ(c *cli.Context) error {
os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID)) os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
os.Setenv(models.EnvAppURL, setting.AppURL) os.Setenv(models.EnvAppURL, setting.AppURL)
//LFS token authentication // LFS token authentication
if verb == lfsAuthenticateVerb { if verb == lfsAuthenticateVerb {
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName)) url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
@ -306,6 +307,7 @@ func runServ(c *cli.Context) error {
} }
} }
process.SetSysProcAttribute(gitcmd)
gitcmd.Dir = setting.RepoRootPath gitcmd.Dir = setting.RepoRootPath
gitcmd.Stdout = os.Stdout gitcmd.Stdout = os.Stdout
gitcmd.Stdin = os.Stdin gitcmd.Stdin = os.Stdin

View File

@ -130,6 +130,7 @@ func createBlameReader(ctx context.Context, dir string, command ...string) (*Bla
cmd := exec.CommandContext(ctx, command[0], command[1:]...) cmd := exec.CommandContext(ctx, command[0], command[1:]...)
cmd.Dir = dir cmd.Dir = dir
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
process.SetSysProcAttribute(cmd)
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
if err != nil { if err != nil {

View File

@ -188,6 +188,7 @@ func (c *Command) RunWithContext(rc *RunContext) error {
if goVersionLessThan115 { if goVersionLessThan115 {
cmd.Env = append(cmd.Env, "GODEBUG=asyncpreemptoff=1") cmd.Env = append(cmd.Env, "GODEBUG=asyncpreemptoff=1")
} }
process.SetSysProcAttribute(cmd)
cmd.Dir = rc.Dir cmd.Dir = rc.Dir
cmd.Stdout = rc.Stdout cmd.Stdout = rc.Stdout
cmd.Stderr = rc.Stderr cmd.Stderr = rc.Stderr

View File

@ -119,6 +119,8 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
cmd.Stdin = input cmd.Stdin = input
} }
cmd.Stdout = output cmd.Stdout = output
process.SetSysProcAttribute(cmd)
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
return fmt.Errorf("%s render run command %s %v failed: %v", p.Name(), commands[0], args, err) return fmt.Errorf("%s render run command %s %v failed: %v", p.Name(), commands[0], args, err)
} }

View File

@ -254,13 +254,13 @@ func (pm *Manager) ExecDirEnvStdIn(timeout time.Duration, dir, desc string, env
if stdIn != nil { if stdIn != nil {
cmd.Stdin = stdIn cmd.Stdin = stdIn
} }
SetSysProcAttribute(cmd)
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
return "", "", err return "", "", err
} }
err := cmd.Wait() err := cmd.Wait()
if err != nil { if err != nil {
err = &Error{ err = &Error{
PID: GetPID(ctx), PID: GetPID(ctx),

View File

@ -0,0 +1,19 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build !windows
// +build !windows
package process
import (
"os/exec"
"syscall"
)
// SetSysProcAttribute sets the common SysProcAttrs for commands
func SetSysProcAttribute(cmd *exec.Cmd) {
// When Gitea runs SubProcessA -> SubProcessB and SubProcessA gets killed by context timeout, use setpgid to make sure the sub processes can be reaped instead of leaving defunct(zombie) processes.
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
}

View File

@ -0,0 +1,17 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
package process
import (
"os/exec"
)
// SetSysProcAttribute sets the common SysProcAttrs for commands
func SetSysProcAttribute(cmd *exec.Cmd) {
// Do nothing
}

View File

@ -24,6 +24,7 @@ import (
asymkey_model "code.gitea.io/gitea/models/asymkey" asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -100,6 +101,8 @@ func sessionHandler(session ssh.Session) {
} }
defer stdin.Close() defer stdin.Close()
process.SetSysProcAttribute(cmd)
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
wg.Add(2) wg.Add(2)
@ -330,7 +333,7 @@ func GenKeyPair(keyPath string) error {
} }
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)} privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
f, err := os.OpenFile(keyPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) f, err := os.OpenFile(keyPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
if err != nil { if err != nil {
return err return err
} }
@ -351,7 +354,7 @@ func GenKeyPair(keyPath string) error {
} }
public := gossh.MarshalAuthorizedKey(pub) public := gossh.MarshalAuthorizedKey(pub)
p, err := os.OpenFile(keyPath+".pub", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) p, err := os.OpenFile(keyPath+".pub", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
if err != nil { if err != nil {
return err return err
} }

View File

@ -284,6 +284,7 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
if err != nil { if err != nil {
return err return err
} }
process.SetSysProcAttribute(cmd)
if err = cmd.Start(); err != nil { if err = cmd.Start(); err != nil {
_ = pipe.Close() _ = pipe.Close()