From 37a330ea8c788db312c4fbfe03ce5f1f7d53bd7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Mon, 17 May 2021 15:39:13 +0300 Subject: [PATCH] Improved the consistency checks of standard information Make sure the standard information attribute has a valid size. --- libntfs-3g/inode.c | 20 +++++++++++++------- libntfs-3g/volume.c | 7 +++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/libntfs-3g/inode.c b/libntfs-3g/inode.c index b25f4051..fe57efaa 100644 --- a/libntfs-3g/inode.c +++ b/libntfs-3g/inode.c @@ -189,6 +189,13 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref) " %lld", (long long)MREF(mref)); goto put_err_out; } + lthle = ctx->attr->value_length; + if (le32_to_cpu(lthle) < offsetof(STANDARD_INFORMATION, owner_id)) { + ntfs_log_error("Corrupt STANDARD_INFORMATION in base" + " record %lld\n", + (long long)MREF(mref)); + goto put_err_out; + } std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr + le16_to_cpu(ctx->attr->value_offset)); ni->flags = std_info->file_attributes; @@ -196,10 +203,9 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref) ni->last_data_change_time = std_info->last_data_change_time; ni->last_mft_change_time = std_info->last_mft_change_time; ni->last_access_time = std_info->last_access_time; - /* JPA insert v3 extensions if present */ - /* length may be seen as 72 (v1.x) or 96 (v3.x) */ - lthle = ctx->attr->length; - if (le32_to_cpu(lthle) > sizeof(STANDARD_INFORMATION)) { + /* Insert v3 extensions if present */ + /* length may be seen as 48 (v1.x) or 72 (v3.x) */ + if (le32_to_cpu(lthle) >= offsetof(STANDARD_INFORMATION, v3_end)) { set_nino_flag(ni, v3_Extensions); ni->owner_id = std_info->owner_id; ni->security_id = std_info->security_id; @@ -760,13 +766,13 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni) /* JPA update v3.x extensions, ensuring consistency */ - lthle = ctx->attr->length; + lthle = ctx->attr->value_length; lth = le32_to_cpu(lthle); if (test_nino_flag(ni, v3_Extensions) - && (lth <= sizeof(STANDARD_INFORMATION))) + && (lth < offsetof(STANDARD_INFORMATION, v3_end))) ntfs_log_error("bad sync of standard information\n"); - if (lth > sizeof(STANDARD_INFORMATION)) { + if (lth >= offsetof(STANDARD_INFORMATION, v3_end)) { std_info->owner_id = ni->owner_id; std_info->security_id = ni->security_id; std_info->quota_charged = ni->quota_charged; diff --git a/libntfs-3g/volume.c b/libntfs-3g/volume.c index c6356563..e1c93236 100644 --- a/libntfs-3g/volume.c +++ b/libntfs-3g/volume.c @@ -224,10 +224,13 @@ static int __ntfs_volume_release(ntfs_volume *v) static void ntfs_attr_setup_flag(ntfs_inode *ni) { STANDARD_INFORMATION *si; + s64 lth; - si = ntfs_attr_readall(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0, NULL); + si = (STANDARD_INFORMATION*)ntfs_attr_readall(ni, + AT_STANDARD_INFORMATION, AT_UNNAMED, 0, <h); if (si) { - ni->flags = si->file_attributes; + if ((u64)lth >= offsetof(STANDARD_INFORMATION, owner_id)) + ni->flags = si->file_attributes; free(si); } }