fix mount/driver hangs/misbehaviours when the some attribute flags were corrupt
parent
7705fc3fdf
commit
6a024394c6
|
@ -376,10 +376,9 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
|
|||
ntfs_attr_search_ctx *ctx;
|
||||
ntfs_attr *na;
|
||||
ATTR_RECORD *a;
|
||||
int err;
|
||||
BOOL cs;
|
||||
|
||||
ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
|
||||
ntfs_log_trace("Entering for inode %lld, attr 0x%x.\n",
|
||||
(unsigned long long)ni->mft_no, type);
|
||||
if (!ni || !ni->vol || !ni->mrec) {
|
||||
errno = EINVAL;
|
||||
|
@ -397,16 +396,29 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
|
|||
}
|
||||
|
||||
ctx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
if (!ctx) {
|
||||
err = errno;
|
||||
if (!ctx)
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_lookup(type, name, name_len, 0, 0, NULL, 0, ctx)) {
|
||||
err = errno;
|
||||
|
||||
if (ntfs_attr_lookup(type, name, name_len, 0, 0, NULL, 0, ctx))
|
||||
goto put_err_out;
|
||||
}
|
||||
|
||||
a = ctx->attr;
|
||||
|
||||
if (!name) {
|
||||
if (a->name_length) {
|
||||
name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
|
||||
a->name_offset)), a->name_length);
|
||||
if (!name)
|
||||
goto put_err_out;
|
||||
name_len = a->name_length;
|
||||
} else {
|
||||
name = AT_UNNAMED;
|
||||
name_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__ntfs_attr_init(na, ni, type, name, name_len);
|
||||
|
||||
/*
|
||||
* Wipe the flags in case they are not zero for an attribute list
|
||||
* attribute. Windows does not complain about invalid flags and chkdsk
|
||||
|
@ -414,22 +426,27 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
|
|||
*/
|
||||
if (type == AT_ATTRIBUTE_LIST)
|
||||
a->flags = 0;
|
||||
|
||||
cs = a->flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE);
|
||||
if (!name) {
|
||||
if (a->name_length) {
|
||||
name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
|
||||
a->name_offset)), a->name_length);
|
||||
if (!name) {
|
||||
err = errno;
|
||||
goto put_err_out;
|
||||
}
|
||||
name_len = a->name_length;
|
||||
} else {
|
||||
name = AT_UNNAMED;
|
||||
name_len = 0;
|
||||
}
|
||||
|
||||
if ((!(a->flags & ATTR_IS_COMPRESSED) != !NAttrCompressed(na)) ||
|
||||
(!(a->flags & ATTR_IS_SPARSE) != !NAttrSparse(na)) ||
|
||||
(!(a->flags & ATTR_IS_ENCRYPTED) != !NAttrEncrypted(na))) {
|
||||
errno = EIO;
|
||||
ntfs_log_perror("Inode %lld attr 0x%x has corrupt flags "
|
||||
"(0x%x <> 0x%x)", (unsigned long long)ni->mft_no,
|
||||
type, a->flags, na->ni->flags);
|
||||
goto put_err_out;
|
||||
}
|
||||
__ntfs_attr_init(na, ni, type, name, name_len);
|
||||
|
||||
if ((NAttrCompressed(na) || NAttrSparse(na)) && !a->compression_unit) {
|
||||
errno = EIO;
|
||||
ntfs_log_perror("Compressed inode %lld attr 0x%x has no "
|
||||
"compression unit",
|
||||
(unsigned long long)ni->mft_no, type);
|
||||
goto put_err_out;
|
||||
}
|
||||
|
||||
if (a->non_resident) {
|
||||
ntfs_attr_init(na, TRUE, a->flags & ATTR_IS_COMPRESSED,
|
||||
a->flags & ATTR_IS_ENCRYPTED,
|
||||
|
@ -452,7 +469,6 @@ put_err_out:
|
|||
ntfs_attr_put_search_ctx(ctx);
|
||||
err_out:
|
||||
free(na);
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -791,8 +807,8 @@ s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b)
|
|||
}
|
||||
|
||||
ntfs_log_trace("Entering for inode %lld attr 0x%x pos %lld count "
|
||||
"%lld\n", (unsigned long long)na->ni->mft_no,
|
||||
na->type, (long long)pos, (long long)count);
|
||||
"%lld flags: 0x%x\n", (unsigned long long)na->ni->mft_no,
|
||||
na->type, (long long)pos, (long long)count, na->ni->flags);
|
||||
|
||||
/*
|
||||
* If this is a compressed attribute it needs special treatment, but
|
||||
|
|
Loading…
Reference in New Issue