Skip to content

Commit

Permalink
scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses
Browse files Browse the repository at this point in the history
Sanitize possible addl_desc_ptr out-of-bounds accesses in
ses_enclosure_data_process().

Link: https://lore.kernel.org/r/20230202162451.15346-3-thenzl@redhat.com
Cc: stable@vger.kernel.org
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Tomas Henzl authored and Martin K. Petersen committed Feb 21, 2023
1 parent 9b4f502 commit db95d4d
Showing 1 changed file with 26 additions and 9 deletions.
35 changes: 26 additions & 9 deletions drivers/scsi/ses.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,8 @@ int ses_match_host(struct enclosure_device *edev, void *data)
}
#endif /* 0 */

static void ses_process_descriptor(struct enclosure_component *ecomp,
unsigned char *desc)
static int ses_process_descriptor(struct enclosure_component *ecomp,
unsigned char *desc, int max_desc_len)
{
int eip = desc[0] & 0x10;
int invalid = desc[0] & 0x80;
Expand All @@ -451,22 +451,32 @@ static void ses_process_descriptor(struct enclosure_component *ecomp,
unsigned char *d;

if (invalid)
return;
return 0;

switch (proto) {
case SCSI_PROTOCOL_FCP:
if (eip) {
if (max_desc_len <= 7)
return 1;
d = desc + 4;
slot = d[3];
}
break;
case SCSI_PROTOCOL_SAS:

if (eip) {
if (max_desc_len <= 27)
return 1;
d = desc + 4;
slot = d[3];
d = desc + 8;
} else
} else {
if (max_desc_len <= 23)
return 1;
d = desc + 4;
}


/* only take the phy0 addr */
addr = (u64)d[12] << 56 |
(u64)d[13] << 48 |
Expand All @@ -483,6 +493,8 @@ static void ses_process_descriptor(struct enclosure_component *ecomp,
}
ecomp->slot = slot;
scomp->addr = addr;

return 0;
}

struct efd {
Expand Down Expand Up @@ -555,14 +567,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
/* skip past overall descriptor */
desc_ptr += len + 4;
}
if (ses_dev->page10)
if (ses_dev->page10 && ses_dev->page10_len > 9)
addl_desc_ptr = ses_dev->page10 + 8;
type_ptr = ses_dev->page1_types;
components = 0;
for (i = 0; i < types; i++, type_ptr += 4) {
for (j = 0; j < type_ptr[1]; j++) {
char *name = NULL;
struct enclosure_component *ecomp;
int max_desc_len;

if (desc_ptr) {
if (desc_ptr >= buf + page7_len) {
Expand All @@ -589,10 +602,14 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
ecomp = &edev->component[components++];

if (!IS_ERR(ecomp)) {
if (addl_desc_ptr)
ses_process_descriptor(
ecomp,
addl_desc_ptr);
if (addl_desc_ptr) {
max_desc_len = ses_dev->page10_len -
(addl_desc_ptr - ses_dev->page10);
if (ses_process_descriptor(ecomp,
addl_desc_ptr,
max_desc_len))
addl_desc_ptr = NULL;
}
if (create)
enclosure_component_register(
ecomp);
Expand Down

0 comments on commit db95d4d

Please sign in to comment.