stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Peter Jones <pjones@redhat.com>,
	Matthew Garrett <mjg59@coreos.com>,
	"Lee, Chun-Yi" <jlee@suse.com>,
	Matt Fleming <matt@codeblueprint.co.uk>
Subject: [PATCH 3.10 12/18] efi: Do variable name validation tests in utf8
Date: Mon, 14 Mar 2016 10:53:10 -0700	[thread overview]
Message-ID: <20160314175041.823708576@linuxfoundation.org> (raw)
In-Reply-To: <20160314175041.432810454@linuxfoundation.org>

3.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peter Jones <pjones@redhat.com>

commit 3dcb1f55dfc7631695e69df4a0d589ce5274bd07 upstream.

Actually translate from ucs2 to utf8 before doing the test, and then
test against our other utf8 data, instead of fudging it.

Signed-off-by: Peter Jones <pjones@redhat.com>
Acked-by: Matthew Garrett <mjg59@coreos.com>
Tested-by: Lee, Chun-Yi <jlee@suse.com>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/firmware/efi/efivars.c |    4 +-
 drivers/firmware/efi/vars.c    |   58 ++++++++++++++++++++++++-----------------
 include/linux/efi.h            |    6 ++--
 3 files changed, 40 insertions(+), 28 deletions(-)

--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -219,7 +219,7 @@ efivar_store_raw(struct efivar_entry *en
 	}
 
 	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
-	    efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) {
+	    efivar_validate(new_var->VariableName, new_var->Data, new_var->DataSize) == false) {
 		printk(KERN_ERR "efivars: Malformed variable content\n");
 		return -EINVAL;
 	}
@@ -334,7 +334,7 @@ static ssize_t efivar_create(struct file
 		return -EACCES;
 
 	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
-	    efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) {
+	    efivar_validate(new_var->VariableName, new_var->Data, new_var->DataSize) == false) {
 		printk(KERN_ERR "efivars: Malformed variable content\n");
 		return -EINVAL;
 	}
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -42,7 +42,7 @@ DECLARE_WORK(efivar_work, NULL);
 EXPORT_SYMBOL_GPL(efivar_work);
 
 static bool
-validate_device_path(struct efi_variable *var, int match, u8 *buffer,
+validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
 		     unsigned long len)
 {
 	struct efi_generic_dev_path *node;
@@ -75,7 +75,7 @@ validate_device_path(struct efi_variable
 }
 
 static bool
-validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
+validate_boot_order(efi_char16_t *var_name, int match, u8 *buffer,
 		    unsigned long len)
 {
 	/* An array of 16-bit integers */
@@ -86,18 +86,18 @@ validate_boot_order(struct efi_variable
 }
 
 static bool
-validate_load_option(struct efi_variable *var, int match, u8 *buffer,
+validate_load_option(efi_char16_t *var_name, int match, u8 *buffer,
 		     unsigned long len)
 {
 	u16 filepathlength;
 	int i, desclength = 0, namelen;
 
-	namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName));
+	namelen = ucs2_strnlen(var_name, EFI_VAR_NAME_LEN);
 
 	/* Either "Boot" or "Driver" followed by four digits of hex */
 	for (i = match; i < match+4; i++) {
-		if (var->VariableName[i] > 127 ||
-		    hex_to_bin(var->VariableName[i] & 0xff) < 0)
+		if (var_name[i] > 127 ||
+		    hex_to_bin(var_name[i] & 0xff) < 0)
 			return true;
 	}
 
@@ -132,12 +132,12 @@ validate_load_option(struct efi_variable
 	/*
 	 * And, finally, check the filepath
 	 */
-	return validate_device_path(var, match, buffer + desclength + 6,
+	return validate_device_path(var_name, match, buffer + desclength + 6,
 				    filepathlength);
 }
 
 static bool
-validate_uint16(struct efi_variable *var, int match, u8 *buffer,
+validate_uint16(efi_char16_t *var_name, int match, u8 *buffer,
 		unsigned long len)
 {
 	/* A single 16-bit integer */
@@ -148,7 +148,7 @@ validate_uint16(struct efi_variable *var
 }
 
 static bool
-validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
+validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
 		      unsigned long len)
 {
 	int i;
@@ -166,7 +166,7 @@ validate_ascii_string(struct efi_variabl
 
 struct variable_validate {
 	char *name;
-	bool (*validate)(struct efi_variable *var, int match, u8 *data,
+	bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
 			 unsigned long len);
 };
 
@@ -189,10 +189,19 @@ static const struct variable_validate va
 };
 
 bool
-efivar_validate(struct efi_variable *var, u8 *data, unsigned long len)
+efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long data_size)
 {
 	int i;
-	u16 *unicode_name = var->VariableName;
+	unsigned long utf8_size;
+	u8 *utf8_name;
+
+	utf8_size = ucs2_utf8size(var_name);
+	utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
+	if (!utf8_name)
+		return false;
+
+	ucs2_as_utf8(utf8_name, var_name, utf8_size);
+	utf8_name[utf8_size] = '\0';
 
 	for (i = 0; variable_validate[i].validate != NULL; i++) {
 		const char *name = variable_validate[i].name;
@@ -200,28 +209,29 @@ efivar_validate(struct efi_variable *var
 
 		for (match = 0; ; match++) {
 			char c = name[match];
-			u16 u = unicode_name[match];
-
-			/* All special variables are plain ascii */
-			if (u > 127)
-				return true;
+			char u = utf8_name[match];
 
 			/* Wildcard in the matching name means we've matched */
-			if (c == '*')
-				return variable_validate[i].validate(var,
-							     match, data, len);
+			if (c == '*') {
+				kfree(utf8_name);
+				return variable_validate[i].validate(var_name,
+							match, data, data_size);
+			}
 
 			/* Case sensitive match */
 			if (c != u)
 				break;
 
 			/* Reached the end of the string while matching */
-			if (!c)
-				return variable_validate[i].validate(var,
-							     match, data, len);
+			if (!c) {
+				kfree(utf8_name);
+				return variable_validate[i].validate(var_name,
+							match, data, data_size);
+			}
 		}
 	}
 
+	kfree(utf8_name);
 	return true;
 }
 EXPORT_SYMBOL_GPL(efivar_validate);
@@ -797,7 +807,7 @@ int efivar_entry_set_get_size(struct efi
 
 	*set = false;
 
-	if (efivar_validate(&entry->var, data, *size) == false)
+	if (efivar_validate(name, data, *size) == false)
 		return -EINVAL;
 
 	/*
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -769,8 +769,10 @@ struct efivars {
  * and we use a page for reading/writing.
  */
 
+#define EFI_VAR_NAME_LEN	1024
+
 struct efi_variable {
-	efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
+	efi_char16_t  VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
 	efi_guid_t    VendorGuid;
 	unsigned long DataSize;
 	__u8          Data[1024];
@@ -832,7 +834,7 @@ int efivar_entry_iter(int (*func)(struct
 struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
 				       struct list_head *head, bool remove);
 
-bool efivar_validate(struct efi_variable *var, u8 *data, unsigned long len);
+bool efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len);
 
 extern struct work_struct efivar_work;
 void efivar_run_worker(void);

  parent reply	other threads:[~2016-03-14 17:53 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-14 17:52 [PATCH 3.10 00/18] 3.10.101-stable review Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 02/18] tracing: Fix check for cpu online when event is disabled Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 03/18] ASoC: wm8994: Fix enum ctl accesses in a wrong type Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 04/18] ASoC: wm8958: " Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 05/18] wext: fix message delay/ordering Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 06/18] mac80211: fix use of uninitialised values in RX aggregation Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 07/18] mac80211: minstrel_ht: set default tx aggregation timeout to 0 Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 08/18] powerpc: Fix dedotify for binutils >= 2.26 Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 09/18] KVM: x86: move steal time initialization to vcpu entry time Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 10/18] lib/ucs2_string: Add ucs2 -> utf8 helper functions Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 11/18] efi: Use ucs2_as_utf8 in efivarfs instead of open coding a bad version Greg Kroah-Hartman
2016-03-14 17:53 ` Greg Kroah-Hartman [this message]
2016-03-14 17:53 ` [PATCH 3.10 13/18] efi: Make our variable validation list include the guid Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 14/18] efi: Make efivarfs entries immutable by default Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 15/18] efi: Add pstore variables to the deletion whitelist Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 16/18] lib/ucs2_string: Correct ucs2 -> utf8 conversion Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 17/18] modules: fix longstanding /proc/kallsyms vs module insertion race Greg Kroah-Hartman
2016-03-14 17:53 ` [PATCH 3.10 18/18] Revert: "crypto: af_alg - Disallow bind/setkey/... after accept(2)" Greg Kroah-Hartman
2016-03-14 23:14 ` [PATCH 3.10 00/18] 3.10.101-stable review Shuah Khan
2016-03-15  2:37 ` Guenter Roeck
2016-03-16  3:08 ` Guenter Roeck
2016-03-16  4:09   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160314175041.823708576@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jlee@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matt@codeblueprint.co.uk \
    --cc=mjg59@coreos.com \
    --cc=pjones@redhat.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).