From patchwork Mon Jan 21 03:10:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 156137 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp5898441jaa; Sun, 20 Jan 2019 19:11:42 -0800 (PST) X-Google-Smtp-Source: ALg8bN4UXn89koC2RmhKzY6xr4O4iboLhFnAACkkHnBqDxtAd/l6ghpzYH4OXq80pVj1+RNPF9Jc X-Received: by 2002:a17:906:7a18:: with SMTP id d24-v6mr23148256ejo.16.1548040302149; Sun, 20 Jan 2019 19:11:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548040302; cv=none; d=google.com; s=arc-20160816; b=O0E1XyheYjit7lewdSQrqkRwadSfSEBeQ+JhxlcWB/1P44W2qtiQTYj9DDoFDqfM8T ZUSCwok0CmMO3GFj5TN986btSJwOFFKentNduM3QrRD++tP9+iGq6p+3GAGEJCgwSZyC qSWKOr6j61FYCOBdzCPoQQrmjF1AnwfnVgMAuhtVvQTkqVTeekLqzVMWckQff7tPaV1o S3zyNG7noKg0NY4b5GqtnuufVCZviqaU3/Z2BCLUjAzlNPuhsYfY0V1/wQLpOtYVZF6h OzwmOIDet2W41OK+KQ4DqpIdvZph9hfJH5V8pnmhFhgUUn2LCVx9EC77h5LK4+oTMF27 SAew== 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 :dkim-signature; bh=Dhr7+LWqf5eM8ikT84c2da9alaGfsUZdYxgzbsidkhA=; b=g6zB+mFKiQH5LEiBFtA5hkPu9po+/ty0bqVBxL0vk2XbYiy/RL2Y1rGq1R5ezl60cS fvC1ryD76MUBlIQlSFSJVatAz1bEB6CEXbBNY74LEbSLuQX902LJk8Q2/1Il6/+RWtNc l3ZUR0aQIaj8z9+pCV0mohBgh3ZYKFacUHPIhj0uM7Nhn3RwsksD8mm5cA8jQJVZePFn UABo2dHLk6sdzaYcmmJtit0ZHb+xBmLcQ+DMO1onSUwxqokh//qUODl8CzT70TdUtx10 xItapi3YD8xJwNJpTO5KBTMHKnaUqxpd2gUcwWfWOd4y2bwXTSwlpxrWBUj3WGhQ2GDa j9vw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DTtBdeU5; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id y7si1465653edl.148.2019.01.20.19.11.41; Sun, 20 Jan 2019 19:11:42 -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; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DTtBdeU5; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by lists.denx.de (Postfix, from userid 105) id AB035C21E42; Mon, 21 Jan 2019 03:10:52 +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.0 required=5.0 tests=RCVD_IN_DNSWL_NONE, T_DKIM_INVALID 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 C53EEC21E96; Mon, 21 Jan 2019 03:10:49 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9EDD3C21E73; Mon, 21 Jan 2019 03:10:41 +0000 (UTC) Received: from mail-yb1-f195.google.com (mail-yb1-f195.google.com [209.85.219.195]) by lists.denx.de (Postfix) with ESMTPS id 7AC9FC21DB3 for ; Mon, 21 Jan 2019 03:10:34 +0000 (UTC) Received: by mail-yb1-f195.google.com with SMTP id s17so6626440ybp.6 for ; Sun, 20 Jan 2019 19:10:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/LEDlkmsSY7RtWjOtxpjn/c87fAnJGDXu4Dj+v1H4RA=; b=DTtBdeU5xGLwbpPVyM0UYb8jsUqoJQzB0vH5tt4Epx9mDlDxNXkt/2pRCaP1KwkffL toU1FXGZg1KNWyyN5XiIyXITHqY3DrZCIg7kXZOowmAgJX1Zr7RQ8qkibTxm4hMFFAiN nMDfz9IWoPh5vwgK+lObIhqDq+PNaakXxItJQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/LEDlkmsSY7RtWjOtxpjn/c87fAnJGDXu4Dj+v1H4RA=; b=OYG7Mo5NFH3HZ1SNHNlLIigy1ZDGl1ZdconJZCuP4cds1Njp0GX6X5ry3uw2HPCW4U bK2IXBiQKhzQv3NhS2tdBo3yh4DSsKVlyS9PCy8K/ufcNRxK74OwuzLgtbGbiXUyttfU pZ/wlZhp/zzw+VeRKXHoAfGVtztgoTApZAOR0bw03aaPcqS/TahberPsbFtIj3HAIesR 1D3JRn9GS215hYctuTA1Thl8hHmLEqih6YeQMBf2NJgtlZv0fSrYSC2bmaSSvzCIlVhR B2PYbn1NM3kntx9TcljRgLCDAezVbJL2or92smMh0artV5v6jJUM8FIHyrZ9p+7xVK/1 UvXA== X-Gm-Message-State: AJcUukdeelVAJXPQ+W6gHjAaIFhKlxzrXDnKZlOhCH82e+PSBRE0GUGV ZOSuJSOBCyeBWGRB+Mkf9uO5AA== X-Received: by 2002:a5b:1ce:: with SMTP id f14mr15074880ybp.74.1548040233483; Sun, 20 Jan 2019 19:10:33 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id p11sm4505349ywm.60.2019.01.20.19.10.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 19:10:32 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de, xypron.glpk@gmx.de Date: Mon, 21 Jan 2019 12:10:39 +0900 Message-Id: <20190121031040.1621-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190121031040.1621-1-takahiro.akashi@linaro.org> References: <20190121031040.1621-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 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" The current GetNextVariableName() is a placeholder. With this patch, it works well as expected. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- 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 19d9cb865f25..398680289df0 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #define READ_ONLY BIT(31) @@ -241,14 +244,161 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, 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, + 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, 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 */