|
@@ -677,15 +677,24 @@ static bool ldm_create_data_partitions (struct parsed_partitions *pp,
|
|
|
* Return: -1 Error, the calculated offset exceeded the size of the buffer
|
|
|
* n OK, a range-checked offset into buffer
|
|
|
*/
|
|
|
-static int ldm_relative (const u8 *buffer, int buflen, int base, int offset)
|
|
|
+static int ldm_relative(const u8 *buffer, int buflen, int base, int offset)
|
|
|
{
|
|
|
|
|
|
base += offset;
|
|
|
- if ((!buffer) || (offset < 0) || (base > buflen))
|
|
|
+ if (!buffer || offset < 0 || base > buflen) {
|
|
|
+ if (!buffer)
|
|
|
+ ldm_error("!buffer");
|
|
|
+ if (offset < 0)
|
|
|
+ ldm_error("offset (%d) < 0", offset);
|
|
|
+ if (base > buflen)
|
|
|
+ ldm_error("base (%d) > buflen (%d)", base, buflen);
|
|
|
return -1;
|
|
|
- if ((base + buffer[base]) >= buflen)
|
|
|
+ }
|
|
|
+ if (base + buffer[base] >= buflen) {
|
|
|
+ ldm_error("base (%d) + buffer[base] (%d) >= buflen (%d)", base,
|
|
|
+ buffer[base], buflen);
|
|
|
return -1;
|
|
|
-
|
|
|
+ }
|
|
|
return buffer[base] + offset + 1;
|
|
|
}
|
|
|
|
|
@@ -1054,60 +1063,98 @@ static bool ldm_parse_prt3(const u8 *buffer, int buflen, struct vblk *vb)
|
|
|
* Return: 'true' @vb contains a Volume VBLK
|
|
|
* 'false' @vb contents are not defined
|
|
|
*/
|
|
|
-static bool ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb)
|
|
|
+static bool ldm_parse_vol5(const u8 *buffer, int buflen, struct vblk *vb)
|
|
|
{
|
|
|
- int r_objid, r_name, r_vtype, r_child, r_size, r_id1, r_id2, r_size2;
|
|
|
- int r_drive, len;
|
|
|
+ int r_objid, r_name, r_vtype, r_disable_drive_letter, r_child, r_size;
|
|
|
+ int r_id1, r_id2, r_size2, r_drive, len;
|
|
|
struct vblk_volu *volu;
|
|
|
|
|
|
- BUG_ON (!buffer || !vb);
|
|
|
-
|
|
|
- r_objid = ldm_relative (buffer, buflen, 0x18, 0);
|
|
|
- r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
|
|
|
- r_vtype = ldm_relative (buffer, buflen, 0x18, r_name);
|
|
|
- r_child = ldm_relative (buffer, buflen, 0x2E, r_vtype);
|
|
|
- r_size = ldm_relative (buffer, buflen, 0x3E, r_child);
|
|
|
-
|
|
|
- if (buffer[0x12] & VBLK_FLAG_VOLU_ID1)
|
|
|
- r_id1 = ldm_relative (buffer, buflen, 0x53, r_size);
|
|
|
- else
|
|
|
+ BUG_ON(!buffer || !vb);
|
|
|
+ r_objid = ldm_relative(buffer, buflen, 0x18, 0);
|
|
|
+ if (r_objid < 0) {
|
|
|
+ ldm_error("r_objid %d < 0", r_objid);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ r_name = ldm_relative(buffer, buflen, 0x18, r_objid);
|
|
|
+ if (r_name < 0) {
|
|
|
+ ldm_error("r_name %d < 0", r_name);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ r_vtype = ldm_relative(buffer, buflen, 0x18, r_name);
|
|
|
+ if (r_vtype < 0) {
|
|
|
+ ldm_error("r_vtype %d < 0", r_vtype);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ r_disable_drive_letter = ldm_relative(buffer, buflen, 0x18, r_vtype);
|
|
|
+ if (r_disable_drive_letter < 0) {
|
|
|
+ ldm_error("r_disable_drive_letter %d < 0",
|
|
|
+ r_disable_drive_letter);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ r_child = ldm_relative(buffer, buflen, 0x2D, r_disable_drive_letter);
|
|
|
+ if (r_child < 0) {
|
|
|
+ ldm_error("r_child %d < 0", r_child);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ r_size = ldm_relative(buffer, buflen, 0x3D, r_child);
|
|
|
+ if (r_size < 0) {
|
|
|
+ ldm_error("r_size %d < 0", r_size);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (buffer[0x12] & VBLK_FLAG_VOLU_ID1) {
|
|
|
+ r_id1 = ldm_relative(buffer, buflen, 0x52, r_size);
|
|
|
+ if (r_id1 < 0) {
|
|
|
+ ldm_error("r_id1 %d < 0", r_id1);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else
|
|
|
r_id1 = r_size;
|
|
|
-
|
|
|
- if (buffer[0x12] & VBLK_FLAG_VOLU_ID2)
|
|
|
- r_id2 = ldm_relative (buffer, buflen, 0x53, r_id1);
|
|
|
- else
|
|
|
+ if (buffer[0x12] & VBLK_FLAG_VOLU_ID2) {
|
|
|
+ r_id2 = ldm_relative(buffer, buflen, 0x52, r_id1);
|
|
|
+ if (r_id2 < 0) {
|
|
|
+ ldm_error("r_id2 %d < 0", r_id2);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else
|
|
|
r_id2 = r_id1;
|
|
|
-
|
|
|
- if (buffer[0x12] & VBLK_FLAG_VOLU_SIZE)
|
|
|
- r_size2 = ldm_relative (buffer, buflen, 0x53, r_id2);
|
|
|
- else
|
|
|
+ if (buffer[0x12] & VBLK_FLAG_VOLU_SIZE) {
|
|
|
+ r_size2 = ldm_relative(buffer, buflen, 0x52, r_id2);
|
|
|
+ if (r_size2 < 0) {
|
|
|
+ ldm_error("r_size2 %d < 0", r_size2);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else
|
|
|
r_size2 = r_id2;
|
|
|
-
|
|
|
- if (buffer[0x12] & VBLK_FLAG_VOLU_DRIVE)
|
|
|
- r_drive = ldm_relative (buffer, buflen, 0x53, r_size2);
|
|
|
- else
|
|
|
+ if (buffer[0x12] & VBLK_FLAG_VOLU_DRIVE) {
|
|
|
+ r_drive = ldm_relative(buffer, buflen, 0x52, r_size2);
|
|
|
+ if (r_drive < 0) {
|
|
|
+ ldm_error("r_drive %d < 0", r_drive);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else
|
|
|
r_drive = r_size2;
|
|
|
-
|
|
|
len = r_drive;
|
|
|
- if (len < 0)
|
|
|
+ if (len < 0) {
|
|
|
+ ldm_error("len %d < 0", len);
|
|
|
return false;
|
|
|
-
|
|
|
+ }
|
|
|
len += VBLK_SIZE_VOL5;
|
|
|
- if (len != BE32 (buffer + 0x14))
|
|
|
+ if (len > BE32(buffer + 0x14)) {
|
|
|
+ ldm_error("len %d > BE32(buffer + 0x14) %d", len,
|
|
|
+ BE32(buffer + 0x14));
|
|
|
return false;
|
|
|
-
|
|
|
+ }
|
|
|
volu = &vb->vblk.volu;
|
|
|
-
|
|
|
- ldm_get_vstr (buffer + 0x18 + r_name, volu->volume_type,
|
|
|
- sizeof (volu->volume_type));
|
|
|
- memcpy (volu->volume_state, buffer + 0x19 + r_vtype,
|
|
|
- sizeof (volu->volume_state));
|
|
|
- volu->size = ldm_get_vnum (buffer + 0x3E + r_child);
|
|
|
- volu->partition_type = buffer[0x42 + r_size];
|
|
|
- memcpy (volu->guid, buffer + 0x43 + r_size, sizeof (volu->guid));
|
|
|
+ ldm_get_vstr(buffer + 0x18 + r_name, volu->volume_type,
|
|
|
+ sizeof(volu->volume_type));
|
|
|
+ memcpy(volu->volume_state, buffer + 0x18 + r_disable_drive_letter,
|
|
|
+ sizeof(volu->volume_state));
|
|
|
+ volu->size = ldm_get_vnum(buffer + 0x3D + r_child);
|
|
|
+ volu->partition_type = buffer[0x41 + r_size];
|
|
|
+ memcpy(volu->guid, buffer + 0x42 + r_size, sizeof(volu->guid));
|
|
|
if (buffer[0x12] & VBLK_FLAG_VOLU_DRIVE) {
|
|
|
- ldm_get_vstr (buffer + 0x53 + r_size, volu->drive_hint,
|
|
|
- sizeof (volu->drive_hint));
|
|
|
+ ldm_get_vstr(buffer + 0x52 + r_size, volu->drive_hint,
|
|
|
+ sizeof(volu->drive_hint));
|
|
|
}
|
|
|
return true;
|
|
|
}
|