Windows为何无法识别WSL符号链接?深入解析LX符号链接机制

本文深入探讨了Windows系统无法识别WSL创建的Linux符号链接的技术原因,通过实际测试展示了LX符号链接与Windows原生符号链接的差异,并分析了NTFS重解析点处理机制的技术细节。

Windows为何无法识别WSL符号链接?- The Trail of Bits博客

Yarden Shafir
2024年2月12日
linux, windows

你是否知道通过Windows Subsystem for Linux(WSL)创建的符号链接(symlinks)无法被Windows系统识别?

最近几个月我在日常工作中使用WSL时遇到了这个令人沮丧的问题。毫无疑问其他人也注意到了这个问题,因此我决定记录下来,为寻找答案的人提供参考。

问题实例演示

我使用WSL2的Ubuntu作为Linux客户端,在相同目录下创建文件并生成符号链接(通过ln -s命令):

1
2
echo "this is a symlink test" > test_symlink.txt
ln -s test_symlink.txt targetfile.txt

在WSL环境中,我可以正常读取原始文件(test_symlink.txt)和符号链接(targetfile.txt)。但当我尝试通过Windows文件资源管理器打开符号链接时,会出现错误:

Windows文件资源管理器错误

从命令行访问targetfile.txt时也会出现相同错误:

命令行错误

查看目录时,可以看到目标文件,但其显示大小为0 KB:

目录中大小为0 KB的符号链接

运行dir命令时,Windows将targetfile.txt识别为NTFS交接点(junction),但无法像处理原生Windows符号链接那样找到链接指向的位置:

Windows无法找到链接指向位置

技术根源分析

当我在Twitter上询问这个行为时,Bill Demirkapi给出了答案——WSL创建的链接是"LX符号链接",Windows无法识别这种类型。这是因为Linux和Windows的符号链接实现机制不同:

  • 在Windows上,符号链接是由内核实现和解释的对象
  • 在Linux上,符号链接只是一个带有特殊标志的文件,其内容是指向目标位置的路径(该路径甚至不需要有效!)

使用FileTest工具,我们可以轻松验证这是一个Linux符号链接,而不是Windows链接。仔细查看甚至可以在文件的DataBuffer中看到目标文件的路径:

FileTest验证为Linux符号链接

FileTest还能提供更具体的文件打开失败错误信息:

FileTest的文件打开失败错误信息

事实证明,使用NtCreateFile尝试打开此文件会失败,并返回STATUS_IO_REPARSE_TAG_NOT_HANDLED错误。这意味着Windows将此文件识别为重解析点,但无法识别LX符号链接标签,因此无法跟踪它。正如微软解释的那样,Windows知道如何处理Linux文件系统的某些部分,但这不包括Linux符号链接格式。

双向兼容性测试

回到WSL环境,符号链接工作正常——系统可以看到符号链接目标并按预期打开文件:

符号链接在WSL中正常工作

有趣的是,在Windows上创建的符号链接在WSL中正常工作。我可以在同一目录中创建新文件,并使用Windows命令行(cmd.exe)为其创建符号链接:

1
2
echo "this is a test for windows symlink" > test_win_symlink.txt
mklink win_targetfile.txt test_win_symlink.txt

现在Windows将其视为可以识别和跟踪的常规符号链接:

Windows可以跟踪在Windows上创建的符号链接

而如果我们从WSL内部访问,Windows符号链接同样正常工作:

Windows符号链接也可以从WSL访问

如果我们使用Windows命令行创建文件交接点并尝试用WSL打开,也会得到相同的结果:

1
2
echo "this is a test for windows junctions" > test_win_junction.txt
mklink /J junction_targetfile.txt test_win_junction.txt

这是从Windows角度查看的目录:

从Windows角度查看的目录

这是从WSL角度查看的目录:

从WSL角度查看的目录

WSL创建的硬链接在Windows上正常工作,因此此问题仅适用于符号链接。

总结

Windows只能处理使用其标准标签由Windows创建的符号链接,无法处理"LX符号链接"类型的WSL符号链接。然而,WSL可以无问题地处理两种类型的符号链接。如果你同时使用Windows和WSL访问相同文件,需要注意符号链接的创建方式,以避免遇到我遇到的相同问题。

最后需要指出的是,当Bill Demirkapi测试此行为时,他注意到Windows可以跟踪使用相对路径创建的WSL符号链接,但不能跟踪使用绝对路径创建的符号链接。在我测试的所有系统上,Windows都无法跟踪任何由WSL创建的符号链接。因此,这里仍然存在一些需要进一步调查的谜团。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计