Skip to content

Commit

Permalink
block: sed-opal: check size of shadow mbr
Browse files Browse the repository at this point in the history
Check whether the shadow mbr does fit in the provided space on the
target. Also a proper firmware should handle this case and return an
error we may prevent problems or even damage with crappy firmwares.

Signed-off-by: Jonas Rabenstein <[email protected]>
Signed-off-by: David Kozub <[email protected]>
Reviewed-by: Scott Bauer <[email protected]>
Reviewed-by: Jon Derrick <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
nonapode authored and axboe committed Jun 29, 2019
1 parent a9b25b4 commit ff91064
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
16 changes: 16 additions & 0 deletions block/opal_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum opal_uid {
OPAL_ENTERPRISE_BANDMASTER0_UID,
OPAL_ENTERPRISE_ERASEMASTER_UID,
/* tables */
OPAL_TABLE_TABLE,
OPAL_LOCKINGRANGE_GLOBAL,
OPAL_LOCKINGRANGE_ACE_RDLOCKED,
OPAL_LOCKINGRANGE_ACE_WRLOCKED,
Expand Down Expand Up @@ -152,6 +153,21 @@ enum opal_token {
OPAL_STARTCOLUMN = 0x03,
OPAL_ENDCOLUMN = 0x04,
OPAL_VALUES = 0x01,
/* table table */
OPAL_TABLE_UID = 0x00,
OPAL_TABLE_NAME = 0x01,
OPAL_TABLE_COMMON = 0x02,
OPAL_TABLE_TEMPLATE = 0x03,
OPAL_TABLE_KIND = 0x04,
OPAL_TABLE_COLUMN = 0x05,
OPAL_TABLE_COLUMNS = 0x06,
OPAL_TABLE_ROWS = 0x07,
OPAL_TABLE_ROWS_FREE = 0x08,
OPAL_TABLE_ROW_BYTES = 0x09,
OPAL_TABLE_LASTID = 0x0A,
OPAL_TABLE_MIN = 0x0B,
OPAL_TABLE_MAX = 0x0C,

/* authority table */
OPAL_PIN = 0x03,
/* locking tokens */
Expand Down
39 changes: 39 additions & 0 deletions block/sed-opal.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ static const u8 opaluid[][OPAL_UID_LENGTH] = {

/* tables */

[OPAL_TABLE_TABLE]
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
[OPAL_LOCKINGRANGE_GLOBAL] =
{ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
[OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
Expand Down Expand Up @@ -1131,6 +1133,29 @@ static int generic_get_column(struct opal_dev *dev, const u8 *table,
return finalize_and_send(dev, parse_and_check_status);
}

/*
* see TCG SAS 5.3.2.3 for a description of the available columns
*
* the result is provided in dev->resp->tok[4]
*/
static int generic_get_table_info(struct opal_dev *dev, enum opal_uid table,
u64 column)
{
u8 uid[OPAL_UID_LENGTH];
const unsigned int half = OPAL_UID_LENGTH/2;

/* sed-opal UIDs can be split in two halves:
* first: actual table index
* second: relative index in the table
* so we have to get the first half of the OPAL_TABLE_TABLE and use the
* first part of the target table as relative index into that table
*/
memcpy(uid, opaluid[OPAL_TABLE_TABLE], half);
memcpy(uid+half, opaluid[table], half);

return generic_get_column(dev, uid, column);
}

static int gen_key(struct opal_dev *dev, void *data)
{
u8 uid[OPAL_UID_LENGTH];
Expand Down Expand Up @@ -1557,6 +1582,20 @@ static int write_shadow_mbr(struct opal_dev *dev, void *data)
u64 len;
int err = 0;

/* do we fit in the available shadow mbr space? */
err = generic_get_table_info(dev, OPAL_MBR, OPAL_TABLE_ROWS);
if (err) {
pr_debug("MBR: could not get shadow size\n");
return err;
}

len = response_get_u64(&dev->parsed, 4);
if (shadow->size > len || shadow->offset > len - shadow->size) {
pr_debug("MBR: does not fit in shadow (%llu vs. %llu)\n",
shadow->offset + shadow->size, len);
return -ENOSPC;
}

/* do the actual transmission(s) */
src = (u8 __user *)(uintptr_t)shadow->data;
while (off < shadow->size) {
Expand Down

0 comments on commit ff91064

Please sign in to comment.