[PATCH] D58513: [libFuzzer][Windows] Port fork mode to Windows
Jonathan Metzman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 21 11:43:24 PST 2019
metzman marked 2 inline comments as done.
metzman added inline comments.
================
Comment at: compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp:82-83
+ // is very slow on Windows.
+ return (FileAttributes &
+ (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY)) == 0;
+}
----------------
zturner wrote:
> I mentioned this elsewhere, but reparse point does not imply that the target of the reparse point is a file. It could be a directory junction, or something else entirely. Here's all the known reparse tags:
>
> ```
> #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
> #define IO_REPARSE_TAG_HSM (0xC0000004L)
> #define IO_REPARSE_TAG_HSM2 (0x80000006L)
> #define IO_REPARSE_TAG_SIS (0x80000007L)
> #define IO_REPARSE_TAG_WIM (0x80000008L)
> #define IO_REPARSE_TAG_CSV (0x80000009L)
> #define IO_REPARSE_TAG_DFS (0x8000000AL)
> #define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
> #define IO_REPARSE_TAG_DFSR (0x80000012L)
> #define IO_REPARSE_TAG_DEDUP (0x80000013L)
> #define IO_REPARSE_TAG_NFS (0x80000014L)
> #define IO_REPARSE_TAG_FILE_PLACEHOLDER (0x80000015L)
> #define IO_REPARSE_TAG_WOF (0x80000017L)
> #define IO_REPARSE_TAG_WCI (0x80000018L)
> #define IO_REPARSE_TAG_WCI_1 (0x90001018L)
> #define IO_REPARSE_TAG_GLOBAL_REPARSE (0xA0000019L)
> #define IO_REPARSE_TAG_CLOUD (0x9000001AL)
> #define IO_REPARSE_TAG_CLOUD_1 (0x9000101AL)
> #define IO_REPARSE_TAG_CLOUD_2 (0x9000201AL)
> #define IO_REPARSE_TAG_CLOUD_3 (0x9000301AL)
> #define IO_REPARSE_TAG_CLOUD_4 (0x9000401AL)
> #define IO_REPARSE_TAG_CLOUD_5 (0x9000501AL)
> #define IO_REPARSE_TAG_CLOUD_6 (0x9000601AL)
> #define IO_REPARSE_TAG_CLOUD_7 (0x9000701AL)
> #define IO_REPARSE_TAG_CLOUD_8 (0x9000801AL)
> #define IO_REPARSE_TAG_CLOUD_9 (0x9000901AL)
> #define IO_REPARSE_TAG_CLOUD_A (0x9000A01AL)
> #define IO_REPARSE_TAG_CLOUD_B (0x9000B01AL)
> #define IO_REPARSE_TAG_CLOUD_C (0x9000C01AL)
> #define IO_REPARSE_TAG_CLOUD_D (0x9000D01AL)
> #define IO_REPARSE_TAG_CLOUD_E (0x9000E01AL)
> #define IO_REPARSE_TAG_CLOUD_F (0x9000F01AL)
> #define IO_REPARSE_TAG_CLOUD_MASK (0x0000F000L)
> #define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
> #define IO_REPARSE_TAG_PROJFS (0x9000001CL)
> #define IO_REPARSE_TAG_STORAGE_SYNC (0x8000001EL)
> #define IO_REPARSE_TAG_WCI_TOMBSTONE (0xA000001FL)
> #define IO_REPARSE_TAG_UNHANDLED (0x80000020L)
> #define IO_REPARSE_TAG_ONEDRIVE (0x80000021L)
> #define IO_REPARSE_TAG_PROJFS_TOMBSTONE (0xA0000022L)
> #define IO_REPARSE_TAG_AF_UNIX (0x80000023L)
>
> ```
See my comment below, I think I need to do this to handle the `edge-case` example.
Separately, I'm wondering if I should also handle other attributes such as `FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_OFFLINE`, `FILE_ATTRIBUTE_VIRTUAL` and `FILE_ATTRIBUTE_SYSTEM` since these don't seem like things I want libFuzzer to treat as files.
================
Comment at: compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp:212
+ continue;
+ IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);
+ } else if (IsFile(PathAttrs) || IsLink(PathAttrs)) {
----------------
zturner wrote:
> Note that this will not follow directory symlinks or junctions. Is that the desired behavior?
I just tested my code. I think it does handle symlinks and junctions correctly at least if these are to directories (I guess they have FILE_ATTRIBUTE_DIRECTORY set when they are directories)
Here's what I did to test.
Using an Administrator cmd.exe:
```
mkdir test-dir
cd test-dir
echo "contents" > file.txt
mkdir dir
:: symlink
mklink file-sym-link file.txt
:: hard link
mklink /H file-hardlink1 file.txt
:: hard link to symlink
mklink /H file-hardlink2 file-symlink
:: symlink to dir
mklink /D dir-symlink dir
:: junction to dir
mklink /J dir-junction dir
mklink dir\file-symlink2 file.txt
:: Breaks but I haven't found anything that handles this.
mklink edge-case dir
```
Then when I pass `test-dir` to `IterateDirRecursive` with print statements for DirPostCallback and DirPreCallback I get:
```
File: <PATH>\test-dir\dir\file-symlink2
Dir: <PATH>\test-dir\dir
File: <PATH>\test-dir\dir-junction\file-symlink2
Dir: <PATH>\test-dir\dir-junction
File: <PATH>\test-dir\dir-symlink\file-symlink2
Dir: <PATH>\test-dir\dir-symlink
File: <PATH>\test-dir\edge-case
File: <PATH>\test-dir\file-hardlink1
File: <PATH>\test-dir\file-hardlink2
File: <PATH>\test-dir\file-symlink
File: <PATH>\test-dir\file.txt
Dir: <PATH>\test-dir
```
Other than "File" printing for `edge-case` these results seem correct to me.
I assume it isn't possible to treat `edge-case` as a directory (no other windows software I've seen does).
I think I need to change what I consider a symbolic link to a file so that I don't tread `edge-case` as I file, what do you think?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D58513/new/
https://reviews.llvm.org/D58513
More information about the llvm-commits
mailing list