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

Discussion: Set Drvfs metadata support from user mode #6

Closed
Biswa96 opened this issue Apr 21, 2018 · 12 comments
Closed

Discussion: Set Drvfs metadata support from user mode #6

Biswa96 opened this issue Apr 21, 2018 · 12 comments

Comments

@Biswa96
Copy link

Biswa96 commented Apr 21, 2018

Continuing discussion from commit 025e881 :

I've found thoose extended attributes (EA) in LxCore.sys driver. Those are configured with ZwSetEaFile() but the buffer length is 84 bytes. Here is a screenshot of LxCore driver in IDA:

extended_attributes

I mount D:\ drive with mount -o metadata,uid=1000,gid=1000 but I can't get those EA in ZwQueryEaFile(). Can you provide some details about how can I get/query those EA with ZwQueryEaFile() with STATUS_SUCCESS?

@0xbadfca11
Copy link
Owner

I don't know WSL internals. I didn't looking disassemble of WSL.

This test done with Build 17134.
image
image
(NTFS Stream Explorer)

Even though metadata mount option is added, the reason why you do not see those EAs is may using a filesystem that does not support EA.
WSL silently ignore even use -o metadata with filesystem that does not support EA.
If so, the output of mount command or /proc/mounts has no metadata.
Other than that, I do not know the reason.

@Biswa96
Copy link
Author

Biswa96 commented Apr 22, 2018

One naive question, why do you allocate maximum memory of UCHAR/USHORT in MAXIMUM_LENGTH_OF_EA_NAME and MAXIMUM_LENGTH_OF_EA_VALUE? NtQueryEaFile() can query those EA values with smaller required memory as follows:

size_t Length = sizeof(FILE_FULL_EA_INFORMATION) + strlen(eaName) + eaValueLength;
FILE_FULL_EA_INFORMATION* Buffer = (FILE_FULL_EA_INFORMATION*)malloc(Length);

size_t EaListLength = sizeof(FILE_GET_EA_INFORMATION) + strlen(eaName);
FILE_GET_EA_INFORMATION* EaList = (FILE_GET_EA_INFORMATION*)malloc(EaListLength);
    
//Copy attributes

NtQueryEaFile(handle, &IoStatusBlock, Buffer, Length, FALSE, EaList, EaListLength, NULL, TRUE);

I've tried to apply those EA ($LXUID, $LXGID) with NtSetEaFile() but it shows error 0x8000014. I'll try again. And there is another FOSS tool to view EA FileTest. Helpful for @DDoSolitary DDoSolitary/LxRunOffline#36

@0xbadfca11
Copy link
Owner

There is no particularly important reason. In the future, I thought that it would be troublesome if the required buffer size changed. I'm lazy.

@0xbadfca11
Copy link
Owner

I've tried to apply those EA ($LXUID, $LXGID) with NtSetEaFile() but it shows error 0x8000014.

Did you include the buffer size for the null-terminated character?
Your code snippet does not contains 1 byte of buffer for null terminator.

https://msdn.microsoft.com/en-us/library/cc232069.aspx

EaNameLength (1 byte): An 8-bit unsigned integer that contains the length, in bytes, of the extended attribute name in the EaName field. This value MUST NOT include the terminating null character to EaName.

EaName (variable): An array of 8-bit ASCII characters that contains the extended attribute name followed by a single terminating null character byte. The EaName MUST be less than 255 characters and MUST NOT contain any of the following characters:

And MAXIMUM_LENGTH_OF_EA_NAME of my code is not enough when using all 255 characters. I have to fix it.

@Biswa96
Copy link
Author

Biswa96 commented Apr 24, 2018

That one byte is not a problem during NtSetEaFile(). But I've found some interesting fact with your provided link and NTFS Stream Explorer program.

NtQueryEaFile() can provides all the EA without iterating all the EA values (like in lxsstat.cpp). I've just set RestartScan =TRUE and ReturnSingle = FALSE in that function and Buffer spits out all three EaName and EaValue. Also EaLength can be known from NtQueryFileInformation() and allocated dynamically.

After mount -o metadata command, I found that LxCore.sys sets those three EA simultaneously without chmod and chown commands. Did you find the $LXDEV attribute in any file?

@0xbadfca11
Copy link
Owner

0xbadfca11 commented Apr 25, 2018

$LXDEV is added to the device file created by mknod command or mkfifo command.

That one byte is not a problem during NtSetEaFile().

Oh, it was my mistake in seeing.

sizeof(FILE_FULL_EA_INFORMATION) + strlen(eaName) + eaValueLength  // Enough, include EaName[1]
offsetof(FILE_FULL_EA_INFORMATION, EaName) + strlen(eaName) + eaValueLength // Not enough

@Biswa96
Copy link
Author

Biswa96 commented Apr 26, 2018

Is there any security mechanism in kernel that restricts any arbritary extended attributes to be added with a file?

@0xbadfca11
Copy link
Owner

I only know deny FILE_WRITE_EA of NTFS ACL.
I have never heard of a policy to deny permission by the name of EA or to enforce per-process.

@Biswa96
Copy link
Author

Biswa96 commented Apr 27, 2018

I've successfully ad those three metadata from user mode with NtSetEaFile(). Closing this discussion..... Thank You!

@Biswa96 Biswa96 closed this as completed Apr 27, 2018
@Biswa96
Copy link
Author

Biswa96 commented May 1, 2018

Is there any relation with $MFT file and Extended Attributes? I add LXATTRB and other three EAs with NtSetEaFile() in a VHD file. Then I unmount that VHD, extract $MFT with 7ZIP and open that file in HxD HexEditor. The screenshot is as follow:

mft_lxattrb

@0xbadfca11
Copy link
Owner

Have you heard that NTFS stores very small data directly in the MFT?
This is not limited to user data, it also applies to all metadata including extended attributes.

@0xbadfca11
Copy link
Owner

I don't know.

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

2 participants