Work around bug with using "\x20" in linux command line.

Related: rhbz#855849

Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
Peter Jones 2012-10-01 13:34:30 -04:00
parent 4ae6c6e738
commit c8494619a4
2 changed files with 194 additions and 1 deletions

View File

@ -0,0 +1,187 @@
From d08e2511db353b2db9c5785d3f22079674abd708 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 Oct 2012 13:24:37 -0400
Subject: [PATCH] Pass "\x[[:hex:]][[:hex:]]" straight through unmolested.
---
grub-core/commands/wildcard.c | 16 +++++++++++++++-
grub-core/lib/cmdline.c | 34 +++++++++++++++++++++++++++++++--
grub-core/script/execute.c | 44 +++++++++++++++++++++++++++++++++++++------
3 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
index 2b73d9a..d1235dc 100644
--- a/grub-core/commands/wildcard.c
+++ b/grub-core/commands/wildcard.c
@@ -420,6 +420,12 @@ check_file (const char *dir, const char *basename)
return found;
}
+static int
+is_hex(char c)
+{
+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+}
+
static void
unescape (char *out, const char *in, const char *end)
{
@@ -428,7 +434,15 @@ unescape (char *out, const char *in, const char *end)
for (optr = out, iptr = in; iptr < end;)
{
- if (*iptr == '\\' && iptr + 1 < end)
+ if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3]))
+ {
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ *optr++ = *iptr++;
+ continue;
+ }
+ else if (*iptr == '\\' && iptr + 1 < end)
{
*optr++ = iptr[1];
iptr += 2;
diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
index a702e64..c8605a7 100644
--- a/grub-core/lib/cmdline.c
+++ b/grub-core/lib/cmdline.c
@@ -20,6 +20,12 @@
#include <grub/lib/cmdline.h>
#include <grub/misc.h>
+static int
+is_hex(char c)
+{
+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+}
+
static unsigned int check_arg (char *c, int *has_space)
{
int space = 0;
@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space)
while (*c)
{
- if (*c == '\\' || *c == '\'' || *c == '"')
+ if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3)))
+ {
+ size += 4;
+ c += 4;
+ continue;
+ }
+ else if (*c == '\\' || *c == '\'' || *c == '"')
size++;
else if (*c == ' ')
space = 1;
@@ -82,7 +94,25 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
while (*c)
{
- if (*c == '\\' || *c == '\'' || *c == '"')
+ if (*c == ' ')
+ {
+ *buf++ = '\\';
+ *buf++ = 'x';
+ *buf++ = '2';
+ *buf++ = '0';
+ c++;
+ continue;
+ }
+ else if (*c == '\\' && *(c+1) == 'x' &&
+ is_hex(*(c+2)) && is_hex(*(c+3)))
+ {
+ *buf++ = *c++;
+ *buf++ = *c++;
+ *buf++ = *c++;
+ *buf++ = *c++;
+ continue;
+ }
+ else if (*c == '\\' || *c == '\'' || *c == '"')
*buf++ = '\\';
*buf++ = *c;
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index b5e6eb0..c44eced 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -52,6 +52,12 @@ static struct grub_script_scope *scope = 0;
/* Wildcard translator for GRUB script. */
struct grub_script_wildcard_translator *grub_wildcard_translator;
+static int
+is_hex(char c)
+{
+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+}
+
static char*
wildcard_escape (const char *s)
{
@@ -68,7 +74,15 @@ wildcard_escape (const char *s)
i = 0;
while ((ch = *s++))
{
- if (ch == '*' || ch == '\\' || ch == '?')
+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2]))
+ {
+ p[i++] = ch;
+ p[i++] = *s++;
+ p[i++] = *s++;
+ p[i++] = *s++;
+ continue;
+ }
+ else if (ch == '*' || ch == '\\' || ch == '?')
p[i++] = '\\';
p[i++] = ch;
}
@@ -92,7 +106,14 @@ wildcard_unescape (const char *s)
i = 0;
while ((ch = *s++))
{
- if (ch == '\\')
+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2]))
+ {
+ p[i++] = '\\';
+ p[i++] = *s++;
+ p[i++] = *s++;
+ p[i++] = *s++;
+ }
+ else if (ch == '\\')
p[i++] = *s++;
else
p[i++] = ch;
@@ -381,14 +402,25 @@ parse_string (const char *str,
int escaped = 0;
const char *optr;
+ grub_printf("str: \"%s\"\n", str);
for (ptr = str; ptr && *ptr; )
switch (*ptr)
{
case '\\':
- escaped = !escaped;
- if (!escaped && put)
- *((*put)++) = '\\';
- ptr++;
+ if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3)))
+ {
+ *((*put)++) = *ptr++;
+ *((*put)++) = *ptr++;
+ *((*put)++) = *ptr++;
+ *((*put)++) = *ptr++;
+ }
+ else
+ {
+ escaped = !escaped;
+ if (!escaped && put)
+ *((*put)++) = '\\';
+ ptr++;
+ }
break;
case '$':
if (escaped)
--
1.7.12.1

View File

@ -41,7 +41,7 @@
Name: grub2
Epoch: 1
Version: 2.00
Release: 8%{?dist}
Release: 9%{?dist}
Summary: Bootloader with support for Linux, Multiboot and more
Group: System Environment/Base
@ -67,6 +67,7 @@ Patch23: grub-2.00-dont-decrease-mmap-size.patch
Patch24: grub-2.00-no-insmod-on-sb.patch
Patch25: grub-2.00-efidisk-ahci-workaround.patch
Patch26: grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch
Patch27: grub-2.00-Handle-escapes-in-labels.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@ -234,6 +235,7 @@ rm -fr $RPM_BUILD_ROOT
%ifarch %{efiarchs}
cd grub-efi-%{tarversion}
make DESTDIR=$RPM_BUILD_ROOT install
find $RPM_BUILD_ROOT -iname "*.module" -exec chmod a-x {} \;
# Ghost config file
install -m 755 -d $RPM_BUILD_ROOT/boot/efi/EFI/%{efidir}/
@ -419,6 +421,10 @@ fi
%doc grub-%{tarversion}/themes/starfield/COPYING.CC-BY-SA-3.0
%changelog
* Mon Oct 01 2012 Peter Jones <pjones@redhat.com> - 1:2.00-9
- Work around bug with using "\x20" in linux command line.
Related: rhbz#855849
* Thu Sep 20 2012 Peter Jones <pjones@redhat.com> - 2.00-8
- Don't error on insmod on UEFI/SB, but also don't do any insmodding.
- Increase device path size for ieee1275