Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

path/filepath: endless loop in EvalSymlinks because it resolves a link to the same path it asked for #40176

Closed
ericwj opened this issue Jul 12, 2020 · 14 comments
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Milestone

Comments

@ericwj
Copy link

ericwj commented Jul 12, 2020

What version of Go are you using (go version)?

1.14.4

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

Windows

What did you do?

$vhd = New-VHD -Path Test.vhdx -SizeBytes 3MB -Fixed
$vhd | Mount-VHD
$vhd = Get-VHD Test.vhdx # refresh IsAttached etc
$vhd | Get-Disk | Initialize-Disk -PartitionStyle GPT
$part = $vhd | Get-Disk | New-Partition -UseMaximumSize -AssignDriveLetter:$false
$vol = $part | Format-Volume -FileSystem NTFS
mkdir Test
$part | Add-PartitionAccessPath -AccessPath "$PWD\Test"
package main

import ("path/filepath"; "fmt")

func main() {
   p, err := filepath.EvalSymlinks("Test")
   if err != nil { panic(err) }
   fmt.Println(p)
}

What did you expect to see?

"$PWD\Test"

What did you see instead?

EvalSymlinks: too many links

@ericwj
Copy link
Author

ericwj commented Jul 12, 2020

#39786

The code path also is not using go API surface or private internal code paths that public go API surface uses to do path math and gets it wrong.

@andybons andybons added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 13, 2020
@andybons andybons added this to the Unplanned milestone Jul 13, 2020
@networkimprov
Copy link

@gopherbot add OS-Windows

cc @alexbrainman

@alexbrainman
Copy link
Member

@ericwj thank you for creating this issue. I think this issue is a duplicate of #39786. Same reproduction steps as per @networkimprov (see #39786 (comment)). No?

Alex

@ericwj
Copy link
Author

ericwj commented Jul 19, 2020

Not really, the code paths are different. This one fails for links to a target volume that does have a DOS device name (C:\EmptyDir) while the other one only fails for links to a target volume that doesn't (\\?\Volume{guid}).

I think the confusion is that the other issue was filed with the error that occurs here, while in the description it sais that the situation had been that there was no DOS device name. But then you don't get the 'too many links' error.

@alexbrainman
Copy link
Member

Not really,

If this is not a dup of #39786. I am happy to investigate this separately. But I cannot run your steps. See #39786 (comment) for details.

Alex

@qmuntal
Copy link
Contributor

qmuntal commented Nov 29, 2022

This failure mode can be reproduced without Hyper-V with the code snippet down below. In fact, it reproduces on all OSes, not only on Windows. Note that my reproducer is quite stupid and probably not something that someone would do, @ericwj's one interesting to demonstrate a real use case.

package main

import (
	"fmt"
	"os"
	"path/filepath"
)

func main() {
	err := os.Symlink("./self", "./self")
	if err != nil {
		panic(err)
	}
	p, err := filepath.EvalSymlinks("./self")
	if err != nil {
		panic(err)
	}
	fmt.Println(p)
}

@gopherbot
Copy link

Change https://go.dev/cl/453915 mentions this issue: path/filepath: EvalSymlinks should detect cycle to itself

@neild
Copy link
Contributor

neild commented Nov 30, 2022

In the example of ln -s self self (producing a symlink from self to itself), the current behavior is correct: The target of the link cannot be resolved, because there is an infinite cycle of links. We can see this without involving Go at all:

$ ln self self
$ ls -l self
lrwxr-xr-x  1 dneil  wheel  4 Nov 30 10:15 self -> self
$ cat self
cat: self: Too many levels of symbolic links

I'm not familiar with the Windows filesystem operations in the original example in this issue, so I'm not certain what the correct behavior there is.

@qmuntal
Copy link
Contributor

qmuntal commented Nov 30, 2022

@neild in your example, ls -l self can resolve the link, the last column contains self -> self. cat can't print its content, but that's expected. If ls was to use Go's filepath.EvalSymlinks, it would report an error instead of resolving the link.

@neild
Copy link
Contributor

neild commented Nov 30, 2022

The equivalent to what ls -l self is doing is os.Lstat.

filepath.EvalSymlinks evaluates all symlinks within a path, returning an equivalent path that contains no symlinks. In the case of a link cycle, there is no such path and EvalSymlinks returns an error.

@qmuntal
Copy link
Contributor

qmuntal commented Dec 1, 2022

filepath.EvalSymlinks evaluates all symlinks within a path, returning an equivalent path that contains no symlinks. In the case of a link cycle, there is no such path and EvalSymlinks returns an error.

My bad, I thought EvalSymlinks was another thing. Then I don't know how to reproduce this issue without using a virtual hard drive.

@gopherbot
Copy link

Change https://go.dev/cl/516695 mentions this issue: filepath: EvalSymlinks to not follow mount points on Windows

@gopherbot
Copy link

Change https://go.dev/cl/536655 mentions this issue: os,path/filepath: treat all non-symlink reparse points as irregular files

@gopherbot
Copy link

Change https://go.dev/cl/565136 mentions this issue: os: don't treat mount points as symbolic links

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Mar 5, 2024
@dmitshur dmitshur modified the milestones: Unplanned, Go1.23 Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Projects
None yet
Development

No branches or pull requests

8 participants