Skip to content

Commit 032dca8

Browse files
authored
Merge pull request from GHSA-6rw3-3whw-jvjj
release: v3.1.3
2 parents a2360ae + f84cccf commit 032dca8

28 files changed

+273
-60
lines changed

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# Git LFS Changelog
22

3+
## 3.1.3 (19 Apr 2022)
4+
5+
This release introduces a security fix for Windows systems, which has been
6+
assigned CVE-2022-24826.
7+
8+
On Windows, if Git LFS operates on a malicious repository with a `..exe` file as
9+
well as a file named `git.exe`, and `git.exe` is not found in PATH, the `..exe`
10+
program will be executed, permitting the attacker to execute arbitrary code.
11+
Similarly, if the malicious repository contains files named `..exe` and
12+
`cygpath.exe`, and `cygpath.exe` is not found in PATH, the `..exe` program will
13+
be executed when certain Git LFS commands are run.
14+
15+
This security problem does not affect Unix systems. This is the same issue as
16+
CVE-2020-27955 and CVE-2021-21237, but the fix for those issue was incomplete
17+
and certain options can still cause the problem to occur.
18+
19+
This occurs because on Windows, Go includes (and prefers) the current directory
20+
when the name of a command run does not contain a directory separator, and it
21+
continues to search for programs even when the specified program name is empty.
22+
This has been solved by failing if the path is empty or not found.
23+
24+
We would like to extend a special thanks to the following open-source
25+
contributors:
26+
27+
* @yuske for reporting this to us responsibly
28+
29+
### Bugs
30+
31+
* Report errors when finding executables and revise PATH search tests (@chrisd8088)
32+
33+
### Misc
34+
35+
* Update Windows signing certificate SHA hash in Makefile (@chrisd8088)
36+
337
## 3.1.2 (16 Feb 2022)
438

539
This is a bugfix release which fixes a bug in `git lfs install` and some issues

commands/command_clone.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ func postCloneSubmodules(args []string) error {
118118
// Use `git submodule foreach --recursive` to cascade into nested submodules
119119
// Also good to call a new instance of git-lfs rather than do things
120120
// inside this instance, since that way we get a clean env in that subrepo
121-
cmd := subprocess.ExecCommand("git", "submodule", "foreach", "--recursive",
121+
cmd, err := subprocess.ExecCommand("git", "submodule", "foreach", "--recursive",
122122
"git lfs pull")
123+
if err != nil {
124+
return err
125+
}
123126
cmd.Stderr = os.Stderr
124127
cmd.Stdin = os.Stdin
125128
cmd.Stdout = os.Stdout

commands/command_ls_files.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"os"
55
"strings"
66

7+
"github.com/git-lfs/git-lfs/v3/errors"
78
"github.com/git-lfs/git-lfs/v3/git"
89
"github.com/git-lfs/git-lfs/v3/lfs"
910
"github.com/git-lfs/git-lfs/v3/tools/humanize"
@@ -50,7 +51,11 @@ func lsFilesCommand(cmd *cobra.Command, args []string) {
5051
} else {
5152
fullref, err := git.CurrentRef()
5253
if err != nil {
53-
ref = git.EmptyTree()
54+
ref, err = git.EmptyTree()
55+
if err != nil {
56+
ExitWithError(errors.Wrap(
57+
err, tr.Tr.Get("Could not read empty Git tree object")))
58+
}
5459
} else {
5560
ref = fullref.Sha
5661
}

commands/command_status.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ func statusCommand(cmd *cobra.Command, args []string) {
2828
ref, _ := git.CurrentRef()
2929

3030
scanIndexAt := "HEAD"
31+
var err error
3132
if ref == nil {
32-
scanIndexAt = git.EmptyTree()
33+
scanIndexAt, err = git.EmptyTree()
34+
if err != nil {
35+
ExitWithError(err)
36+
}
3337
}
3438

3539
scanner, err := lfs.NewPointerScanner(cfg.GitEnv(), cfg.OSEnv())

commands/path_windows.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ func cleanRootPath(pattern string) string {
4848

4949
if len(winBashPrefix) < 1 {
5050
// cmd.Path is something like C:\Program Files\Git\usr\bin\pwd.exe
51-
cmd := subprocess.ExecCommand("pwd")
51+
cmd, err := subprocess.ExecCommand("pwd")
52+
if err != nil {
53+
return pattern
54+
}
5255
winBashPrefix = strings.Replace(filepath.Dir(filepath.Dir(filepath.Dir(cmd.Path))), `\`, "/", -1) + "/"
5356
}
5457

commands/pull.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,10 @@ func (i *gitIndexer) Add(path string) error {
147147

148148
if i.cmd == nil {
149149
// Fire up the update-index command
150-
cmd := git.UpdateIndexFromStdin()
150+
cmd, err := git.UpdateIndexFromStdin()
151+
if err != nil {
152+
return err
153+
}
151154
cmd.Stdout = &i.output
152155
cmd.Stderr = &i.output
153156
stdin, err := cmd.StdinPipe()

config/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var (
1313
)
1414

1515
const (
16-
Version = "3.1.2"
16+
Version = "3.1.3"
1717
)
1818

1919
func init() {

creds/creds.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,11 @@ func (a *AskPassCredentialHelper) getFromProgram(valueType credValueType, u *url
241241

242242
// 'cmd' will run the GIT_ASKPASS (or core.askpass) command prompting
243243
// for the desired valueType (`Username` or `Password`)
244-
cmd := subprocess.ExecCommand(a.Program, a.args(fmt.Sprintf("%s for %q", valueString, u))...)
244+
cmd, errVal := subprocess.ExecCommand(a.Program, a.args(fmt.Sprintf("%s for %q", valueString, u))...)
245+
if errVal != nil {
246+
tracerx.Printf("creds: failed to find GIT_ASKPASS command: %s", a.Program)
247+
return "", errVal
248+
}
245249
cmd.Stderr = &err
246250
cmd.Stdout = &value
247251

@@ -301,7 +305,10 @@ func (h *commandCredentialHelper) Approve(creds Creds) error {
301305

302306
func (h *commandCredentialHelper) exec(subcommand string, input Creds) (Creds, error) {
303307
output := new(bytes.Buffer)
304-
cmd := subprocess.ExecCommand("git", "credential", subcommand)
308+
cmd, err := subprocess.ExecCommand("git", "credential", subcommand)
309+
if err != nil {
310+
return nil, errors.New(tr.Tr.Get("failed to find `git credential %s`: %v", subcommand, err))
311+
}
305312
cmd.Stdin = bufferCreds(input)
306313
cmd.Stdout = output
307314
/*
@@ -316,7 +323,7 @@ func (h *commandCredentialHelper) exec(subcommand string, input Creds) (Creds, e
316323
*/
317324
cmd.Stderr = os.Stderr
318325

319-
err := cmd.Start()
326+
err = cmd.Start()
320327
if err == nil {
321328
err = cmd.Wait()
322329
}

debian/changelog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
git-lfs (3.1.3) stable; urgency=low
2+
3+
* New upstream version
4+
5+
-- brian m. carlson <[email protected]> Tue, 19 Apr 2022 14:29:00 -0000
6+
17
git-lfs (3.1.2) stable; urgency=low
28

39
* New upstream version

git/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,10 @@ func (c *Configuration) Source() (*ConfigurationSource, error) {
199199

200200
func (c *Configuration) gitConfig(args ...string) (string, error) {
201201
args = append([]string{"config", "--includes"}, args...)
202-
cmd := subprocess.ExecCommand("git", args...)
202+
cmd, err := subprocess.ExecCommand("git", args...)
203+
if err != nil {
204+
return "", err
205+
}
203206
if len(c.GitDir) > 0 {
204207
cmd.Dir = c.GitDir
205208
}

0 commit comments

Comments
 (0)