Fixed reparse data check for non-Microsoft tags

Windows requires non-Microsoft reparse points (identified by having bit
31 of the reparse tag clear) to have a 16-byte GUID following the regular
reparse point header.  This GUID is not, and cannot, be included in the
"reparse data length" field.

(Contributed by Eric Biggers)
This commit is contained in:
Jean-Pierre André 2015-11-09 16:14:31 +01:00
parent 37bd6661d4
commit 34d29fe0b0

View File

@ -422,8 +422,10 @@ static int ntfs_drive_letter(ntfs_volume *vol, ntfschar letter)
/* /*
* Do some sanity checks on reparse data * Do some sanity checks on reparse data
* *
* The only general check is about the size (at least the tag must * Microsoft reparse points have an 8-byte header whereas
* be present) * non-Microsoft reparse points have a 24-byte header. In each case,
* 'reparse_data_length' must equal the number of non-header bytes.
*
* If the reparse data looks like a junction point or symbolic * If the reparse data looks like a junction point or symbolic
* link, more checks can be done. * link, more checks can be done.
* *
@ -441,7 +443,9 @@ static BOOL valid_reparse_data(ntfs_inode *ni,
ok = ni && reparse_attr ok = ni && reparse_attr
&& (size >= sizeof(REPARSE_POINT)) && (size >= sizeof(REPARSE_POINT))
&& (((size_t)le16_to_cpu(reparse_attr->reparse_data_length) && (((size_t)le16_to_cpu(reparse_attr->reparse_data_length)
+ sizeof(REPARSE_POINT)) == size); + sizeof(REPARSE_POINT)
+ ((reparse_attr->reparse_tag &
IO_REPARSE_TAG_IS_MICROSOFT) ? 0 : sizeof(GUID))) == size);
if (ok) { if (ok) {
switch (reparse_attr->reparse_tag) { switch (reparse_attr->reparse_tag) {
case IO_REPARSE_TAG_MOUNT_POINT : case IO_REPARSE_TAG_MOUNT_POINT :