summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHawrylewicz Czarnowski, Przemyslaw <przemyslaw.hawrylewicz.czarnowski@intel.com>2011-03-28 10:42:07 +1100
committerNeilBrown <neilb@suse.de>2011-03-28 10:42:07 +1100
commitaae4c1116639633ad7e48f0fd603f6d6cd39a653 (patch)
tree986ca43b46d40119c0c247b420398682b98c5cb4
parent96687b797fe65dbac75a1c5b3a00ae9a4e921efb (diff)
downloadmdadm-aae4c1116639633ad7e48f0fd603f6d6cd39a653.tar.gz
imsm: reading of UEFI variables needs an update
Content of EFI variable is stored in "data" file. Moreover size of data provided by given variable can be initially validated by reading value of "size" file. Function read_efi_variable() has been introduced to simplify the code. Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--platform-intel.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/platform-intel.c b/platform-intel.c
index fe6785c..cb6c7dc 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -357,13 +357,52 @@ int populated_efi[SYS_DEV_MAX] = { 0, 0 };
static struct imsm_orom imsm_efi[SYS_DEV_MAX];
-const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id)
+int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name, struct efi_guid guid)
{
- int dfd=-1;
char path[PATH_MAX];
char buf[GUID_STR_MAX];
- int n;
+ int dfd;
+ ssize_t n, var_data_len;
+
+ snprintf(path, PATH_MAX, "%s/%s-%s/size", SYS_EFI_VAR_PATH, variable_name, guid_str(buf, guid));
+
+ dprintf("EFI VAR: path=%s\n", path);
+ /* get size of variable data */
+ dfd = open(path, O_RDONLY);
+ if (dfd < 0)
+ return 1;
+
+ n = read(dfd, &buf, sizeof(buf));
+ close(dfd);
+ if (n < 0)
+ return 1;
+ buf[n] = '\0';
+
+ errno = 0;
+ var_data_len = strtoul(buf, NULL, 16);
+ if ((errno == ERANGE && (var_data_len == LONG_MAX))
+ || (errno != 0 && var_data_len == 0))
+ return 1;
+ /* get data */
+ snprintf(path, PATH_MAX, "%s/%s-%s/data", SYS_EFI_VAR_PATH, variable_name, guid_str(buf, guid));
+
+ dprintf("EFI VAR: path=%s\n", path);
+ dfd = open(path, O_RDONLY);
+ if (dfd < 0)
+ return 1;
+
+ n = read(dfd, buffer, buf_size);
+ close(dfd);
+ if (n != var_data_len || n < buf_size) {
+ return 1;
+ }
+
+ return 0;
+}
+
+const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id)
+{
if (hba_id >= SYS_DEV_MAX)
return NULL;
@@ -383,25 +422,14 @@ const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id)
return imsm_platform_test(hba_id, &populated_efi[hba_id], &imsm_efi[hba_id]);
}
/* OROM test is set, return that there is no EFI capabilities */
- if (check_env("IMSM_TEST_OROM")) {
+ if (check_env("IMSM_TEST_OROM"))
return NULL;
- }
- if (hba_id == SYS_DEV_SAS)
- snprintf(path, PATH_MAX, "%s/%s-%s", SYS_EFI_VAR_PATH, SCU_PROP, guid_str(buf, VENDOR_GUID));
- else
- snprintf(path, PATH_MAX, "%s/%s-%s", SYS_EFI_VAR_PATH, AHCI_PROP, guid_str(buf, VENDOR_GUID));
- dprintf("EFI VAR: path=%s\n", path);
- dfd = open(path, O_RDONLY);
- if (dfd < 0) {
+ if (read_efi_variable(&imsm_efi[hba_id], sizeof(imsm_efi[0]), hba_id == SYS_DEV_SAS ? SCU_PROP : AHCI_PROP, VENDOR_GUID)) {
populated_efi[hba_id] = 0;
return NULL;
}
- n = read(dfd, &imsm_efi[hba_id], sizeof(imsm_efi[0]));
- close(dfd);
- if (n < (int) (sizeof(imsm_efi[0]))) {
- return NULL;
- }
+
populated_efi[hba_id] = 1;
return &imsm_efi[hba_id];
}