fix mount/driver hangs/misbehaviours when the some attribute flags were corrupt

master
szaka 2008-05-24 14:38:36 +00:00
parent 7705fc3fdf
commit 6a024394c6
1 changed files with 41 additions and 25 deletions

View File

@ -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