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

Differing views of the filesystem depending on whether the session was opened elevated or not. #9182

Closed
1 of 2 tasks
Hashbrown777 opened this issue Nov 21, 2022 · 4 comments
Closed
1 of 2 tasks
Assignees

Comments

@Hashbrown777
Copy link

Hashbrown777 commented Nov 21, 2022

Version

10.0.19045.2311

WSL Version

  • WSL 2
  • WSL 1

Kernel Version

5.15.74.2-microsoft-standard-WSL2

Distro Version

Debian

Other Software

No response

Repro Steps

  1. Open two terminal windows, one administrator, the other not (but note you're the same user with $env:USERNAME), and open wsl in each.
    Or simply open wsl directly if you have a startmenu option to; one normally, one via right-click run-as-admin.
    Note you're the same user with echo $USER
  2. In either terminal create a fake device to mount if you do not have anything to mount for the next step.
    E.g. fallocate -l 1G ~/test.img; mkfs.btrfs -f ~/test.img
  3. In either terminal mount the "device" to '/mnt' and create a file there (making sure you have permissions to).
    E.g. sudo mkdir /mnt/test; sudo mount -o ssd ~/test.img /mnt/test; sudo chown $USER:$USER /mnt/test/; echo bob >/mnt/test/test.txt
  4. Try to read the file from the both terminals cat /mnt/test/test.txt.
    Show the contents of the directory in both terminals ls /mnt/test.
    See the mount points in both df -hT.
  5. Unmount the device in the original terminal. E.g. sudo umount /mnt/test.
    Mount the device again but in the opposite terminal to step 3. E.g. sudo mount -o ssd ~/test.img /mnt/test
    NB you do not recreate the file, it was successfully saved to the mounted "device".
    Perform step 4 again.
  6. Cleanup, unmount and remove files. E.g. sudo umount /mnt/test; rmdir /mnt/test; rm ~/test.img

Expected Behavior

The outputs in both terminals should be identical for step 4.
I know from outside wsl Windows has some weirdness when viewing the filesystem via P9, but this is within the linux vm, and you're logged in as the exact same user taboot.
Mounting into /mnt/wsl (instead of /mnt) gets rid of the issue; but why?

Actual Behavior

The mounted directory is always empty in the terminal that did not mount it.
Even if you weren't logged into the same user (as mentioned in "Expected Behaviour", in linux you would still see the same filesystem, just your permissions would evaluate differently.

Also, for the non-admin-mount variant, if you exit and run wsl again, your mount is sometimes gone (whereas the admin-mount seems to persist). If you open two non-admin wsl's and mount in one, you can exit that one and the other can still read the mounted directory; I imagine it has something to do with when the wsl instance gets suspended (but then how does that work when the admin-wsl was open the whole time?).

Mounts to /mnt/wsl seem to persist regardless: but I'd like direct confirmation on this.

Diagnostic Logs

No response

@Hashbrown777
Copy link
Author

I made a script to make testing this quicker

image

It doesn't do anything but set up variables when dot-sourcing, but then you can run these commands roughly matching the repro steps which run all the commands for you (and notably don't require you to input a password for sudo).
Step 2 & 3 = TestCreate
Mounting = TestMount
Step 4 = Test
Step 5 = TestRemove
Step 6 = TestDestroy

$test = [PSCustomObject]@{
	#name of distribution you want to run in, leave blank for Default
	wsl = ''
	#name of .img fake device made in home directory, and /mnt subfolder to create
	name = 'test'
	
	#auto variables
	mount  = $NULL
	device = $NULL
	user   = $NULL
	group  = $NULL
	unc    = $NULL
}

if (!$test.wsl) {
	$test.wsl = wsl -l `
	| %{ $_ -replace '\x00','' } `
	| ?{ $_ -match '^.+(?=\s+\(Default\)$)' } `
	| %{ $Matches.Values }
}
$test.mount  = "/mnt/$($test.name)"
#!$test.mount  = "/mnt/wsl/$($test.name)"
$test.unc    = "\\wsl`$\$($test.wsl)$($test.mount -replace '/','\')"
$test.device = wsl `
	--distribution $test.wsl `
	-- realpath "~/$($test.name).img"
$test.user = wsl `
	--distribution $test.wsl `
	-- id -un
$test.group = wsl `
	--distribution $test.wsl `
	-- id -gn

$test

Filter RunWSL {
	$use = ($test.user,'root')[$_ -is [array]]
	$_ `
	| %{
		"$(('$','#')[$use -eq 'root']) $_" `
		| write-host `
			-BackgroundColor DarkGreen `
			-ForegroundColor Black
		wsl `
			--distribution $test.wsl `
			--user $use `
			-- bash -c $_
		if (!$?) {
			throw ''
		}
	}
}

#creates the image file and adds the folder & file
Function TestCreate {
	(
		"fallocate -l 1G '$($test.device)'",
		,@("mkfs.btrfs -f '$($test.device)'")
	) | RunWSL
	TestMount
	(
		,@("chown '$($test.user):$($test.group)' '$($test.mount)/'"),
		"echo bob >'$($test.mount)/test.txt'"
	) | RunWSL
	TestRemove
}
Function TestDestroy {
	try {
		TestMounted | Out-Null
	}
	catch {}
	finally {
		if ($?) {
			TestRemove
		}
	}
	"rm '$($test.device)'" | RunWSL
}

#mounts the test filesystem
Function TestMount {
	,@(
		"mkdir $($test.mount)",
		"mount -o ssd '$($test.device)' '$($test.mount)'"
	) | RunWSL
	TestMounted
}
Function TestRemove {
	,@(
		"umount '$($test.mount)'",
		"rmdir '$($test.mount)'"
	) | RunWSL
}
Function TestMounted {
	"df -T | grep '$([regex]::Escape($test.mount))'" | RunWSL
}

#sees if the mount worked
Function Test {
#!	explorer $test.unc
#!	notepad "$($test.unc)/test.txt"
	(
		"ls -la '$($test.mount)/'",
		"cat '$($test.mount)/test.txt'"
	) | RunWSL
}

@OneBlue OneBlue self-assigned this Nov 22, 2022
@jrruethe
Copy link

jrruethe commented Dec 6, 2022

I ran into this too, its very confusing. In my case, I was using wsl -- sudo mount /dev/mapper/external /media/external from an elevated powershell to mount a drive. The command completes successfully, and I can see the contents if I do wsl -- ls /media/external. However, if I open a normal WSL terminal, that directory is empty.

Even the output of mount from a WSL terminal and wsl -- mount from an elevated powershell is different. It is extremely confusing.

Is there a workaround?

I'm on Windows 10 22H2 Build 19045.2311, and my WSL is Ubuntu

@Hashbrown777
Copy link
Author

Hashbrown777 commented Dec 6, 2022

@jrruethe the workaround for you would be to instead mount to /mnt/wsl/external; anything mounted in /mnt/wsl is shared (including with Windows itself via \\wsl$\Ubuntu\mnt\wsl\external).

Alternatively you can simply not use an admin shell to perform the mount, Windows admin is completely independent of linux sudo, so long as anything that's trying to access the mount point is ran from a non-elevated Windows session (but then you might run into the mount point disappearing as per paragraph 2 of Actual Behaviour).

@Hashbrown777
Copy link
Author

It looks like this might be a deliberate use of linux [mount-]namespaces

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants