Thread (64 messages) 64 messages, 5 authors, 2019-02-11

Re: [PATCH v4 13/16] block: sed-opal: check size of shadow mbr

From: Derrick, Jonathan <hidden>
Date: 2019-02-11 21:27:11
Also in: lkml

On Sun, 2019-02-10 at 21:05 +0100, David Kozub wrote:
On Fri, 8 Feb 2019, Derrick, Jonathan wrote:
quoted
On Fri, 2019-02-01 at 21:50 +0100, David Kozub wrote:
quoted
From: Jonas Rabenstein <redacted>

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 <jonas.rabenstein@studium.uni-erl
angen.de>
Reviewed-by: Scott Bauer <redacted>
---
 block/opal_proto.h | 16 ++++++++++++++++
 block/sed-opal.c   | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
diff --git a/block/opal_proto.h b/block/opal_proto.h
index b6e352cfe982..5e8df3245eb0 100644
--- a/block/opal_proto.h
+++ b/block/opal_proto.h
@@ -106,6 +106,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,
@@ -160,6 +161,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 */
diff --git a/block/sed-opal.c b/block/sed-opal.c
index 2459ac4d523b..3493bb979978 100644
--- a/block/sed-opal.c
+++ b/block/sed-opal.c
@@ -139,6 +139,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] =
@@ -1120,6 +1122,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];
@@ -1535,6 +1560,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);
Wouldn't you need to multiply this by result from
OPAL_TABLE_ROWBYTES?
What does ROWBYTES return for you?
Hi Jon,

reading the spec[1], I think it defines the MBR table to be a "byte
table" 
(see 5.7.2.6 MBR (Byte Table)). For byte tables, it says (see
3.2.5.1 
Kinds of Tables) "A byte table has one unnamed column of type
bytes_1." I 
think this implies that each row is 1 byte and so number of rows =
size of 
table in rows.

When I actually try to get OPAL_TABLE_ROWS abd OPAL_TABLE_ROWBYTES of
the 
MBR table from a Samsung 840 EVO, I get:
* OPAL_TABLE_ROWS 134217728 which is 128 MiB
* OPAL_TABLE_ROWBYTES 0

I'm not sure if I'm doing something wrong here. I just added:

 	err = generic_get_table_info(dev, OPAL_MBR,
OPAL_TABLE_ROW_BYTES);
 	if (err) {
 		pr_debug("MBR: could not get shadow row bytes
size\n");
 		return err;
 	}

 	row_bytes = response_get_u64(&dev->parsed, 4);

Best regards,
David

[1] https://trustedcomputinggroup.org/wp-content/uploads/TCG_Storage_
Architecture_Core_Spec_v2.01_r1.00.pdf
I also see ROWS=0x8000000 and ROWBYTES=0 on an Intel drive, so my
interpretation of rowbytes was probably incorrect.

Reviewed-by: Jon Derrick <redacted>

Attachments

  • smime.p7s [application/x-pkcs7-signature] 3278 bytes
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help