Changeset 63635 in vbox
- Timestamp:
- Aug 25, 2016 1:44:59 PM (8 years ago)
- Location:
- trunk/src/VBox/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/Parallels.cpp
r63567 r63635 198 198 if (RT_FAILURE(rc)) 199 199 goto out; 200 AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n")); 200 if (pImage->cbFileCurrent % 512 != 0) 201 { 202 rc = VERR_VD_PARALLELS_INVALID_HEADER; 203 goto out; 204 } 201 205 202 206 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, -
trunk/src/VBox/Storage/QCOW.cpp
r63567 r63635 1029 1029 1030 1030 /** 1031 * Validates the header. 1032 * 1033 * @returns VBox status code. 1034 * @param pImage Image backend instance data. 1035 * @param pHdr The header to validate. 1036 * @param cbFile The image file size in bytes. 1037 */ 1038 static int qcowHdrValidate(PQCOWIMAGE pImage, PQCowHeader pHdr, uint64_t cbFile) 1039 { 1040 if (pHdr->u32Version == 1) 1041 { 1042 /* Check that the backing filename is contained in the file. */ 1043 if (pHdr->Version.v1.u64BackingFileOffset + pHdr->Version.v1.u32BackingFileSize > cbFile) 1044 return vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1045 N_("QCOW: Backing file offset and size exceed size of image '%s' (%u vs %u)"), 1046 pImage->pszFilename, pHdr->Version.v1.u64BackingFileOffset + pHdr->Version.v1.u32BackingFileSize, 1047 cbFile); 1048 1049 /* Check that the cluster bits indicate at least a 512byte sector size. */ 1050 if (RT_BIT_32(pHdr->Version.v1.u8ClusterBits) < 512) 1051 return vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1052 N_("QCOW: Cluster size is too small for image '%s' (%u vs %u)"), 1053 pImage->pszFilename, RT_BIT_32(pHdr->Version.v1.u8ClusterBits), 512); 1054 1055 /* 1056 * Check for possible overflow when multiplying cluster size and L2 entry count because it is used 1057 * to calculate the number of L1 table entries later on. 1058 */ 1059 if (RT_BIT_32(pHdr->Version.v1.u8L2Bits) * RT_BIT_32(pHdr->Version.v1.u8ClusterBits) == 0) 1060 return vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1061 N_("QCOW: Overflow during L1 table size calculation for image '%s'"), 1062 pImage->pszFilename); 1063 } 1064 else if (pHdr->u32Version == 2) 1065 { 1066 /* Check that the backing filename is contained in the file. */ 1067 if (pHdr->Version.v2.u64BackingFileOffset + pHdr->Version.v2.u32BackingFileSize > cbFile) 1068 return vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1069 N_("QCOW: Backing file offset and size exceed size of image '%s' (%u vs %u)"), 1070 pImage->pszFilename, pHdr->Version.v2.u64BackingFileOffset + pHdr->Version.v2.u32BackingFileSize, 1071 cbFile); 1072 1073 /* Check that the cluster bits indicate at least a 512byte sector size. */ 1074 if (RT_BIT_32(pHdr->Version.v2.u32ClusterBits) < 512) 1075 return vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1076 N_("QCOW: Cluster size is too small for image '%s' (%u vs %u)"), 1077 pImage->pszFilename, RT_BIT_32(pHdr->Version.v2.u32ClusterBits), 512); 1078 } 1079 else 1080 return vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1081 N_("QCOW: Version %u in image '%s' is not supported"), 1082 pHdr->u32Version, pImage->pszFilename); 1083 1084 return VINF_SUCCESS; 1085 } 1086 1087 /** 1031 1088 * Internal: Open an image, constructing all necessary data structures. 1032 1089 */ … … 1072 1129 Assert(pImage->offNextCluster >= cbFile); 1073 1130 1074 if (Header.u32Version == 1) 1131 rc = qcowHdrValidate(pImage, &Header, cbFile); 1132 if (RT_SUCCESS(rc)) 1075 1133 { 1076 if ( !Header.Version.v1.u32CryptMethod)1134 if (Header.u32Version == 1) 1077 1135 { 1078 pImage->uVersion = 1; 1079 pImage->offBackingFilename = Header.Version.v1.u64BackingFileOffset; 1080 pImage->cbBackingFilename = Header.Version.v1.u32BackingFileSize; 1081 pImage->MTime = Header.Version.v1.u32MTime; 1082 pImage->cbSize = Header.Version.v1.u64Size; 1083 pImage->cbCluster = RT_BIT_32(Header.Version.v1.u8ClusterBits); 1084 pImage->cL2TableEntries = RT_BIT_32(Header.Version.v1.u8L2Bits); 1085 pImage->cbL2Table = RT_ALIGN_64(pImage->cL2TableEntries * sizeof(uint64_t), pImage->cbCluster); 1086 pImage->offL1Table = Header.Version.v1.u64L1TableOffset; 1087 pImage->cL1TableEntries = pImage->cbSize / (pImage->cbCluster * pImage->cL2TableEntries); 1088 if (pImage->cbSize % (pImage->cbCluster * pImage->cL2TableEntries)) 1089 pImage->cL1TableEntries++; 1090 pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster); 1136 if (!Header.Version.v1.u32CryptMethod) 1137 { 1138 pImage->uVersion = 1; 1139 pImage->offBackingFilename = Header.Version.v1.u64BackingFileOffset; 1140 pImage->cbBackingFilename = Header.Version.v1.u32BackingFileSize; 1141 pImage->MTime = Header.Version.v1.u32MTime; 1142 pImage->cbSize = Header.Version.v1.u64Size; 1143 pImage->cbCluster = RT_BIT_32(Header.Version.v1.u8ClusterBits); 1144 pImage->cL2TableEntries = RT_BIT_32(Header.Version.v1.u8L2Bits); 1145 pImage->cbL2Table = RT_ALIGN_64(pImage->cL2TableEntries * sizeof(uint64_t), pImage->cbCluster); 1146 pImage->offL1Table = Header.Version.v1.u64L1TableOffset; 1147 pImage->cL1TableEntries = pImage->cbSize / (pImage->cbCluster * pImage->cL2TableEntries); 1148 if (pImage->cbSize % (pImage->cbCluster * pImage->cL2TableEntries)) 1149 pImage->cL1TableEntries++; 1150 } 1151 else 1152 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1153 N_("QCow: Encrypted image '%s' is not supported"), 1154 pImage->pszFilename); 1155 } 1156 else if (Header.u32Version == 2) 1157 { 1158 if (Header.Version.v2.u32CryptMethod) 1159 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1160 N_("QCow: Encrypted image '%s' is not supported"), 1161 pImage->pszFilename); 1162 else if (Header.Version.v2.u32NbSnapshots) 1163 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1164 N_("QCow: Image '%s' contains snapshots which is not supported"), 1165 pImage->pszFilename); 1166 else 1167 { 1168 pImage->uVersion = 2; 1169 pImage->offBackingFilename = Header.Version.v2.u64BackingFileOffset; 1170 pImage->cbBackingFilename = Header.Version.v2.u32BackingFileSize; 1171 pImage->cbSize = Header.Version.v2.u64Size; 1172 pImage->cbCluster = RT_BIT_32(Header.Version.v2.u32ClusterBits); 1173 pImage->cL2TableEntries = pImage->cbCluster / sizeof(uint64_t); 1174 pImage->cbL2Table = pImage->cbCluster; 1175 pImage->offL1Table = Header.Version.v2.u64L1TableOffset; 1176 pImage->cL1TableEntries = Header.Version.v2.u32L1Size; 1177 pImage->offRefcountTable = Header.Version.v2.u64RefcountTableOffset; 1178 pImage->cbRefcountTable = qcowCluster2Byte(pImage, Header.Version.v2.u32RefcountTableClusters); 1179 pImage->cRefcountTableEntries = pImage->cbRefcountTable / sizeof(uint64_t); 1180 } 1091 1181 } 1092 1182 else 1093 1183 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1094 N_("QCow: Encrypted image '%s' is not supported"), 1184 N_("QCow: Image '%s' uses version %u which is not supported"), 1185 pImage->pszFilename, Header.u32Version); 1186 1187 pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster); 1188 if ((uint64_t)pImage->cbL1Table != RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster)) 1189 rc = vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1190 N_("QCOW: L1 table size overflow in image '%s'"), 1095 1191 pImage->pszFilename); 1096 1192 } 1097 else if (Header.u32Version == 2)1098 {1099 if (Header.Version.v2.u32CryptMethod)1100 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,1101 N_("QCow: Encrypted image '%s' is not supported"),1102 pImage->pszFilename);1103 else if (Header.Version.v2.u32NbSnapshots)1104 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,1105 N_("QCow: Image '%s' contains snapshots which is not supported"),1106 pImage->pszFilename);1107 else1108 {1109 pImage->uVersion = 2;1110 pImage->offBackingFilename = Header.Version.v2.u64BackingFileOffset;1111 pImage->cbBackingFilename = Header.Version.v2.u32BackingFileSize;1112 pImage->cbSize = Header.Version.v2.u64Size;1113 pImage->cbCluster = RT_BIT_32(Header.Version.v2.u32ClusterBits);1114 pImage->cL2TableEntries = pImage->cbCluster / sizeof(uint64_t);1115 pImage->cbL2Table = pImage->cbCluster;1116 pImage->offL1Table = Header.Version.v2.u64L1TableOffset;1117 pImage->cL1TableEntries = Header.Version.v2.u32L1Size;1118 pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster);1119 pImage->offRefcountTable = Header.Version.v2.u64RefcountTableOffset;1120 pImage->cbRefcountTable = qcowCluster2Byte(pImage, Header.Version.v2.u32RefcountTableClusters);1121 pImage->cRefcountTableEntries = pImage->cbRefcountTable / sizeof(uint64_t);1122 }1123 }1124 else1125 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,1126 N_("QCow: Image '%s' uses version %u which is not supported"),1127 pImage->pszFilename, Header.u32Version);1128 1193 1129 1194 /** @todo Check that there are no compressed clusters in the image
Note:
See TracChangeset
for help on using the changeset viewer.