From patchwork Mon Jan 21 11:43:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 156197 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp6282272jaa; Mon, 21 Jan 2019 03:45:00 -0800 (PST) X-Google-Smtp-Source: ALg8bN7PitkMVIg6u2fXp5ldNy4g3xzZE8VtpLNbaCGVTyaorezDDY88TOcfNMWgXK32F5fmpsr+ X-Received: by 2002:a50:bb2c:: with SMTP id y41mr26349697ede.147.1548071100332; Mon, 21 Jan 2019 03:45:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548071100; cv=none; d=google.com; s=arc-20160816; b=bGgqR8CclyyficG31zIdlZB5QKVNK+X2ZB5H4OLflfKOx8ca6mtiaL2pPlSONIGhKu +ydj1qnJtYdWcHDInqoZF9MgxM1RtGPSluz19ttvJUfTOg8wB20EMsHegeTjclvtyq57 5bDgB0o0zMpfNJ8/trdrkOCPke1dsY45e4EKmRfk0YrySDwF1q5BiY1mkQuDdJa50Kek yTJA6ghv89gIhYt/aPVywWNUr3L7PDs3tClWZQLTkZnDhm850QfEOR7bzn9BA+0DHRPZ aGaOGj4g1knuZzOin6agKa+3AunU+vkxlnNBfJ01H6Sl6CwGtk5zXTp8UNvQNDVFyd3W iFhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :cc:mime-version:references:in-reply-to:message-id:date:to:from; bh=ado9gt9zbs2JyMFtWUXXcBNzRHpmwWQMClyjNZkIr+o=; b=rXWuLg39CQDuQhIJZULrQ+FVwMU38gPnLXBQCj23FmkOjmuPBoWR3bFH/HvSsXRLTc +OM8+9pEmE1Oa8dpEsQcpmHyV4kYEdmIX5Vw5yrjdjp/6/L1Xjz7m6b+pXMe70DGGQH1 jrmB/S8KmvKz8xO9uQvlFbU9GjgFkbtTYQSnLi3kt4K/lSaeOD9drC+gyCRwM/2LFwra mrzTcschRjYR7YasYjODCmkWDLSKh/pNVyP3cuxC5nXsaqPfEXqFs6HUQJGjbTO4frye haXnx8Z/2+hoXan5NwKvfclZNjjKPDDjDLoUGoGuFq5gdco4P4OpbbgPmpR1Is5De2Vf i/4Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id y7si1881288edl.148.2019.01.21.03.45.00; Mon, 21 Jan 2019 03:45:00 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by lists.denx.de (Postfix, from userid 105) id E83B5C21EC2; Mon, 21 Jan 2019 11:44:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.7 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_LOW autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 9BF4EC21DD9; Mon, 21 Jan 2019 11:43:41 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9C801C21C6A; Mon, 21 Jan 2019 11:43:37 +0000 (UTC) Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) by lists.denx.de (Postfix) with ESMTPS id E234DC21C27 for ; Mon, 21 Jan 2019 11:43:36 +0000 (UTC) Received: from LT02.fritz.box ([84.118.159.3]) by mail.gmx.com (mrgmx102 [212.227.17.174]) with ESMTPSA (Nemesis) id 0MDW9x-1gzX9H0ghh-00GqFQ; Mon, 21 Jan 2019 12:43:34 +0100 From: Heinrich Schuchardt To: Alexander Graf Date: Mon, 21 Jan 2019 12:43:13 +0100 Message-Id: <20190121114314.15741-2-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190121114314.15741-1-xypron.glpk@gmx.de> References: <20190121114314.15741-1-xypron.glpk@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:P7DNIITmZQGSCvWJaOdPW4eyJ2IIAzurGdYiychmTH4quzPPGfK zEnOJGpS8Aqzv7RQRUnbPn2hodqFQSpzH+J5vmOZe3DMqXf6uspNag0PtYNt7Yzgzbq4i/Y x6d9TRfJiBBQd/MY7iIMKvG+L90rS28c5JaE53HihFfnKUZtC3qi7x+zd/SOrl1txChgkA4 /KUfZlrP4iGpcT2JoYQwQ== X-UI-Out-Filterresults: notjunk:1; V03:K0:xPt7HHeC3ME=:L6MlPU5olGPUAum59lM0rO vNepjSN6gRVjKJqmED6/y5lzIyydKve0/nCcmBZgZZ/fPLo+T86lFHTGLDAtMLbUvSm+hswEo CuJlXKS4nuDVG1yfNg62n9UXb/TOc0FVDpHkzziIqscUMKLtmGY8gTSaYSsfjRuPlm9GzQXRm U8vUmlYnA7awh3FX0H0FO8yS9EoORRRXBbBvqHcB+kkgc8IOpcJtAhvr/YElyuOUyHkOo0Y0R oFrnIeU2bs+R81NUa3OmQ/FKfykjkhVLi+wu5ExpGJyHyq9o9xzfAvbKN1Og4xofND98dxPrO GHyy1oEe42cp9eCYZVzadPjCtH364r/tlnAVBUvVMmVpr1ENJ6sYFMrsa+fF9hisBMZsHZM45 zSf2E2VFSLmy2GW7Glq4eQQONZiYVONuh3I/i7nMtpsMfY/jBLqXk8FAo238ukGSaSIqK3aXV Tn9HxiA7tJuAv4Ri6V7f4gbgdRD10HORv0UC/Uw7F3kKBP2koHDEV5vSWHo4L4uOkVK6M7gI3 4VdCDjLXJyZRuQGpAXTdY+e8F890vG82D9XtNERZx5++tKzYEh7wkaoe4BpYr/k1gVPQ0X4I4 BKIwcjmt/iGuwmLl3R4HRLOywamYvRE1OW4TXBpxrAH7RXXtk6rN3H3qtA6w8UCrWBaQg6lrT MvV+DMvofRoMYh1Qbs99NQnZR/jlvZLwwmIphAZZk8PBvbFtPoB2XpGb02WJCzDfAhxi2ogKd 066NW1wYIVJE2e/8jXYOBjA6yLPh7/jd6BwcosFb/k38qpXO5Xm3EA5SuIaYO2+Z23K7Bq8Uu pZRU+70Wo+jjBWcGfNi4TarD/nNCDdV1ZrXbHzpxvXZJ1y6zmTa2/kOesW111cHws/tMovRcb Cbpk1yiM05xeQEbsEgL0iZNp1pEA2jyNzfqI/9tXSrOf5jl3YoEOlfsgeoZuzY Cc: u-boot@lists.denx.de, Heinrich Schuchardt , trini@konsulko.com Subject: [U-Boot] [PATCH v3 1/2] efi_loader: implement GetNextVariableName() X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: AKASHI Takahiro The current GetNextVariableName() is a placeholder. With this patch, it works well as expected. Signed-off-by: AKASHI Takahiro rebased on efi-next Reviewed-by: Heinrich Schuchardt --- v3: rebase on efi-next v2: update variable_name_size in GetNextVariableName add more comments change some internal variable names --- lib/efi_loader/efi_variable.c | 154 +++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index eea7f68b85..993bf3ce90 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #define READ_ONLY BIT(31) @@ -203,14 +206,161 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, return EFI_EXIT(EFI_SUCCESS); } -/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 */ +static char *efi_variables_list; +static char *efi_cur_variable; + +/** + * parse_uboot_variable() - parse a u-boot variable and get uefi-related + * information + * @variable: whole data of u-boot variable (ie. name=value) + * @variable_name_size: size of variable_name buffer in byte + * @variable_name: name of uefi variable in u16, null-terminated + * @vendor: vendor's guid + * @attributes: attributes + * + * A uefi variable is encoded into a u-boot variable as described above. + * This function parses such a u-boot variable and retrieve uefi-related + * information into respective parameters. In return, variable_name_size + * is the size of variable name including NULL. + * + * Return: EFI_SUCCESS if parsing is OK, EFI_NOT_FOUND when + the entire variable list has been returned, + otherwise non-zero status code + */ +static efi_status_t parse_uboot_variable(char *variable, + efi_uintn_t *variable_name_size, + u16 *variable_name, + const efi_guid_t *vendor, + u32 *attributes) +{ + char *guid, *name, *end, c; + unsigned long name_len; + u16 *p; + + guid = strchr(variable, '_'); + if (!guid) + return EFI_INVALID_PARAMETER; + guid++; + name = strchr(guid, '_'); + if (!name) + return EFI_INVALID_PARAMETER; + name++; + end = strchr(name, '='); + if (!end) + return EFI_INVALID_PARAMETER; + + name_len = end - name; + if (*variable_name_size < (name_len + 1)) { + *variable_name_size = name_len + 1; + return EFI_BUFFER_TOO_SMALL; + } + end++; /* point to value */ + + /* variable name */ + p = variable_name; + utf8_utf16_strncpy(&p, name, name_len); + variable_name[name_len] = 0; + *variable_name_size = name_len + 1; + + /* guid */ + c = *(name - 1); + *(name - 1) = '\0'; /* guid need be null-terminated here */ + uuid_str_to_bin(guid, (unsigned char *)vendor, UUID_STR_FORMAT_GUID); + *(name - 1) = c; + + /* attributes */ + parse_attr(end, attributes); + + return EFI_SUCCESS; +} + +/** + * efi_get_next_variable_name() - enumerate the current variable names + * @variable_name_size: size of variable_name buffer in byte + * @variable_name: name of uefi variable's name in u16 + * @vendor: vendor's guid + * + * This function implements the GetNextVariableName service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details: http://wiki.phoenix.com/wiki/index.php/ + * EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 + * + * Return: status code + */ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, u16 *variable_name, const efi_guid_t *vendor) { + char *native_name, *variable; + ssize_t name_len, list_len; + char regex[256]; + char * const regexlist[] = {regex}; + u32 attributes; + int i; + efi_status_t ret; + EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor); - return EFI_EXIT(EFI_DEVICE_ERROR); + if (!variable_name_size || !variable_name || !vendor) + EFI_EXIT(EFI_INVALID_PARAMETER); + + if (variable_name[0]) { + /* check null-terminated string */ + for (i = 0; i < *variable_name_size; i++) + if (!variable_name[i]) + break; + if (i >= *variable_name_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + /* search for the last-returned variable */ + ret = efi_to_native(&native_name, variable_name, vendor); + if (ret) + return EFI_EXIT(ret); + + name_len = strlen(native_name); + for (variable = efi_variables_list; variable && *variable;) { + if (!strncmp(variable, native_name, name_len) && + variable[name_len] == '=') + break; + + variable = strchr(variable, '\n'); + if (variable) + variable++; + } + + free(native_name); + if (!(variable && *variable)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + /* next variable */ + variable = strchr(variable, '\n'); + if (variable) + variable++; + if (!(variable && *variable)) + return EFI_EXIT(EFI_NOT_FOUND); + } else { + /* + *new search: free a list used in the previous search + */ + free(efi_variables_list); + efi_variables_list = NULL; + efi_cur_variable = NULL; + + snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_.*"); + list_len = hexport_r(&env_htab, '\n', + H_MATCH_REGEX | H_MATCH_KEY, + &efi_variables_list, 0, 1, regexlist); + if (list_len <= 0) + return EFI_EXIT(EFI_NOT_FOUND); + + variable = efi_variables_list; + } + + ret = parse_uboot_variable(variable, variable_name_size, variable_name, + vendor, &attributes); + + return EFI_EXIT(ret); } /* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.29 */