]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 May 2022 17:16:55 +0000 (19:16 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 May 2022 17:16:55 +0000 (19:16 +0200)
added patches:
hex2bin-fix-access-beyond-string-end.patch
hex2bin-make-the-function-hex_to_bin-constant-time.patch

queue-4.14/hex2bin-fix-access-beyond-string-end.patch [new file with mode: 0644]
queue-4.14/hex2bin-make-the-function-hex_to_bin-constant-time.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/hex2bin-fix-access-beyond-string-end.patch b/queue-4.14/hex2bin-fix-access-beyond-string-end.patch
new file mode 100644 (file)
index 0000000..e41fcd2
--- /dev/null
@@ -0,0 +1,48 @@
+From e4d8a29997731b3bb14059024b24df9f784288d0 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 27 Apr 2022 11:26:40 -0400
+Subject: hex2bin: fix access beyond string end
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit e4d8a29997731b3bb14059024b24df9f784288d0 upstream.
+
+If we pass too short string to "hex2bin" (and the string size without
+the terminating NUL character is even), "hex2bin" reads one byte after
+the terminating NUL character.  This patch fixes it.
+
+Note that hex_to_bin returns -1 on error and hex2bin return -EINVAL on
+error - so we can't just return the variable "hi" or "lo" on error.
+This inconsistency may be fixed in the next merge window, but for the
+purpose of fixing this bug, we just preserve the existing behavior and
+return -1 and -EINVAL.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Fixes: b78049831ffe ("lib: add error checking to hex2bin")
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/hexdump.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/lib/hexdump.c
++++ b/lib/hexdump.c
+@@ -66,10 +66,13 @@ EXPORT_SYMBOL(hex_to_bin);
+ int hex2bin(u8 *dst, const char *src, size_t count)
+ {
+       while (count--) {
+-              int hi = hex_to_bin(*src++);
+-              int lo = hex_to_bin(*src++);
++              int hi, lo;
+-              if ((hi < 0) || (lo < 0))
++              hi = hex_to_bin(*src++);
++              if (unlikely(hi < 0))
++                      return -EINVAL;
++              lo = hex_to_bin(*src++);
++              if (unlikely(lo < 0))
+                       return -EINVAL;
+               *dst++ = (hi << 4) | lo;
diff --git a/queue-4.14/hex2bin-make-the-function-hex_to_bin-constant-time.patch b/queue-4.14/hex2bin-make-the-function-hex_to_bin-constant-time.patch
new file mode 100644 (file)
index 0000000..78124b2
--- /dev/null
@@ -0,0 +1,91 @@
+From e5be15767e7e284351853cbaba80cde8620341fb Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Mon, 25 Apr 2022 08:07:48 -0400
+Subject: hex2bin: make the function hex_to_bin constant-time
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit e5be15767e7e284351853cbaba80cde8620341fb upstream.
+
+The function hex2bin is used to load cryptographic keys into device
+mapper targets dm-crypt and dm-integrity.  It should take constant time
+independent on the processed data, so that concurrently running
+unprivileged code can't infer any information about the keys via
+microarchitectural convert channels.
+
+This patch changes the function hex_to_bin so that it contains no
+branches and no memory accesses.
+
+Note that this shouldn't cause performance degradation because the size
+of the new function is the same as the size of the old function (on
+x86-64) - and the new function causes no branch misprediction penalties.
+
+I compile-tested this function with gcc on aarch64 alpha arm hppa hppa64
+i386 ia64 m68k mips32 mips64 powerpc powerpc64 riscv sh4 s390x sparc32
+sparc64 x86_64 and with clang on aarch64 arm hexagon i386 mips32 mips64
+powerpc powerpc64 s390x sparc32 sparc64 x86_64 to verify that there are
+no branches in the generated code.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/kernel.h |    2 +-
+ lib/hexdump.c          |   32 +++++++++++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 8 deletions(-)
+
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -582,7 +582,7 @@ static inline char *hex_byte_pack_upper(
+       return buf;
+ }
+-extern int hex_to_bin(char ch);
++extern int hex_to_bin(unsigned char ch);
+ extern int __must_check hex2bin(u8 *dst, const char *src, size_t count);
+ extern char *bin2hex(char *dst, const void *src, size_t count);
+--- a/lib/hexdump.c
++++ b/lib/hexdump.c
+@@ -25,15 +25,33 @@ EXPORT_SYMBOL(hex_asc_upper);
+  *
+  * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
+  * input.
++ *
++ * This function is used to load cryptographic keys, so it is coded in such a
++ * way that there are no conditions or memory accesses that depend on data.
++ *
++ * Explanation of the logic:
++ * (ch - '9' - 1) is negative if ch <= '9'
++ * ('0' - 1 - ch) is negative if ch >= '0'
++ * we "and" these two values, so the result is negative if ch is in the range
++ *    '0' ... '9'
++ * we are only interested in the sign, so we do a shift ">> 8"; note that right
++ *    shift of a negative value is implementation-defined, so we cast the
++ *    value to (unsigned) before the shift --- we have 0xffffff if ch is in
++ *    the range '0' ... '9', 0 otherwise
++ * we "and" this value with (ch - '0' + 1) --- we have a value 1 ... 10 if ch is
++ *    in the range '0' ... '9', 0 otherwise
++ * we add this value to -1 --- we have a value 0 ... 9 if ch is in the range '0'
++ *    ... '9', -1 otherwise
++ * the next line is similar to the previous one, but we need to decode both
++ *    uppercase and lowercase letters, so we use (ch & 0xdf), which converts
++ *    lowercase to uppercase
+  */
+-int hex_to_bin(char ch)
++int hex_to_bin(unsigned char ch)
+ {
+-      if ((ch >= '0') && (ch <= '9'))
+-              return ch - '0';
+-      ch = tolower(ch);
+-      if ((ch >= 'a') && (ch <= 'f'))
+-              return ch - 'a' + 10;
+-      return -1;
++      unsigned char cu = ch & 0xdf;
++      return -1 +
++              ((ch - '0' +  1) & (unsigned)((ch - '9' - 1) & ('0' - 1 - ch)) >> 8) +
++              ((cu - 'A' + 11) & (unsigned)((cu - 'F' - 1) & ('A' - 1 - cu)) >> 8);
+ }
+ EXPORT_SYMBOL(hex_to_bin);
index ed5f47fee844159c984c97760901d81527ddae78..59192eee1e20224770a82b013c79212d49c42cc7 100644 (file)
@@ -20,3 +20,5 @@ usb-gadget-uvc-fix-crash-when-encoding-data-for-usb-request.patch
 usb-gadget-configfs-clear-deactivation-flag-in-configfs_composite_unbind.patch
 serial-8250-also-set-sticky-mcr-bits-in-console-restoration.patch
 serial-8250-correct-the-clock-for-endrun-ptp-1588-pcie-device.patch
+hex2bin-make-the-function-hex_to_bin-constant-time.patch
+hex2bin-fix-access-beyond-string-end.patch