From ccfe8d99717c45cad090cfcc67d70bc50d838d65 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 1 May 2022 19:17:14 +0200 Subject: [PATCH] 4.19-stable patches added patches: hex2bin-fix-access-beyond-string-end.patch hex2bin-make-the-function-hex_to_bin-constant-time.patch --- ...hex2bin-fix-access-beyond-string-end.patch | 48 ++++++++++ ...he-function-hex_to_bin-constant-time.patch | 91 +++++++++++++++++++ queue-4.19/series | 2 + 3 files changed, 141 insertions(+) create mode 100644 queue-4.19/hex2bin-fix-access-beyond-string-end.patch create mode 100644 queue-4.19/hex2bin-make-the-function-hex_to_bin-constant-time.patch diff --git a/queue-4.19/hex2bin-fix-access-beyond-string-end.patch b/queue-4.19/hex2bin-fix-access-beyond-string-end.patch new file mode 100644 index 00000000000..e41fcd22254 --- /dev/null +++ b/queue-4.19/hex2bin-fix-access-beyond-string-end.patch @@ -0,0 +1,48 @@ +From e4d8a29997731b3bb14059024b24df9f784288d0 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 27 Apr 2022 11:26:40 -0400 +Subject: hex2bin: fix access beyond string end + +From: Mikulas Patocka + +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 +Reviewed-by: Andy Shevchenko +Fixes: b78049831ffe ("lib: add error checking to hex2bin") +Cc: stable@vger.kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + 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.19/hex2bin-make-the-function-hex_to_bin-constant-time.patch b/queue-4.19/hex2bin-make-the-function-hex_to_bin-constant-time.patch new file mode 100644 index 00000000000..1b57f84a486 --- /dev/null +++ b/queue-4.19/hex2bin-make-the-function-hex_to_bin-constant-time.patch @@ -0,0 +1,91 @@ +From e5be15767e7e284351853cbaba80cde8620341fb Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 25 Apr 2022 08:07:48 -0400 +Subject: hex2bin: make the function hex_to_bin constant-time + +From: Mikulas Patocka + +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 +Cc: stable@vger.kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -631,7 +631,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); + diff --git a/queue-4.19/series b/queue-4.19/series index 50cfadbdcc6..f33ceefc536 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -17,3 +17,5 @@ usb-dwc3-gadget-return-proper-request-status.patch serial-imx-fix-overrun-interrupts-in-dma-mode.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 -- 2.47.3