mirror of
https://github.com/containers/podman.git
synced 2025-08-26 03:01:31 +08:00
Safer use of filepath.EvalSymlinks()
on Windows
The behavior of function `path/filepath.EvalSymlinks()` has changed in Go v1.23: - https://go-review.googlesource.com/c/go/+/565136 - https://go.dev/doc/go1.23#minor_library_changes - https://tip.golang.org/doc/godebug As a consequences, starting with Podman 5.3.0, when installing on Windows (WSL) using scoop, Podman fails to start because it fails to find helper binaries. Scoop copies Podman binaries in a folder of type Junction and `EvalSymlinks` returns an error. The problem is described in #24557. To address this problem we are checking if a path is a `Symlink` before calling `EvalSymlinks` and, if it's not (hardlinks, mount points or canonical files), we are calling `path/filepath.Clean` for consistency. In fact `path/filepath.EvalSymlinks`, after evaluating a symlink target, calls `Clean` too. Signed-off-by: Mario Loriedo <mario.loriedo@gmail.com>
This commit is contained in:
@ -251,7 +251,7 @@ func FindExecutablePeer(name string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
exe, err = filepath.EvalSymlinks(exe)
|
||||
exe, err = EvalSymlinksOrClean(exe)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -259,6 +259,28 @@ func FindExecutablePeer(name string) (string, error) {
|
||||
return filepath.Join(filepath.Dir(exe), name), nil
|
||||
}
|
||||
|
||||
func EvalSymlinksOrClean(filePath string) (string, error) {
|
||||
fileInfo, err := os.Lstat(filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if fileInfo.Mode()&fs.ModeSymlink != 0 {
|
||||
// Only call filepath.EvalSymlinks if it is a symlink.
|
||||
// Starting with v1.23, EvalSymlinks returns an error for mount points.
|
||||
// See https://go-review.googlesource.com/c/go/+/565136 for reference.
|
||||
filePath, err = filepath.EvalSymlinks(filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
// Call filepath.Clean when filePath is not a symlink. That's for
|
||||
// consistency with the symlink case (filepath.EvalSymlinks calls
|
||||
// Clean after evaluating filePath).
|
||||
filePath = filepath.Clean(filePath)
|
||||
}
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
func GetWinProxyStateDir(name string, vmtype define.VMType) (string, error) {
|
||||
dir, err := env.GetDataDir(vmtype)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user