From: Muhammad Bilal <meatuni001@gmail.com>
To: "Jorge Lopez" <jorge.lopez2@hp.com>,
"Hans de Goede" <hdegoede@redhat.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Muhammad Bilal <meatuni001@gmail.com>
Subject: [PATCH v2 2/3] platform/x86: hp-bioscfg: fix non-ASCII truncation in hp_get_string_from_buffer()
Date: Tue, 29 Sep 2026 01:03:17 +0500 [thread overview]
Message-ID: <20260928200318.63383-3-meatuni001@gmail.com> (raw)
In-Reply-To: <20260928200318.63383-1-meatuni001@gmail.com>
utf16s_to_utf8s() writes into dst, but the manual loop that follows
re-walks src from the start and overwrites dst with truncating casts
(dst[i] = *src), discarding the UTF-8 output. Any code point above
U+007F produces garbage.
Replace both with a two-stage conversion: utf16s_to_utf8s() into a
scratch buffer, then string_escape_mem(ESCAPE_SPACE | ESCAPE_SPECIAL,
"\\\r\n\t") into dst. Passing the four characters to @only avoids
escaping quotes, leaving them for the existing strreplace() call.
Tested on HP EliteBook 840 G2 (Fedora 44, Linux 7.2.7).
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
---
Changes in v2:
- Split from the combined string buffer fix into its own patch, as
reviewed by Ilpo Järvinen.
- Drop lib/string_helpers patch: pass "\\\r\n\t" to string_escape_mem()
with existing flags (ESCAPE_SPACE | ESCAPE_SPECIAL) to escape the four
characters without modifying quotes, as reviewed by Andy Shevchenko.
drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 61 +++++---------------
1 file changed, 14 insertions(+), 47 deletions(-)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
index ab1eff1deca1..fd3d54ee3a94 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/string.h>
+#include <linux/string_helpers.h>
#include <linux/wmi.h>
#include "bioscfg.h"
#include "../../firmware_attributes_class.h"
@@ -60,10 +61,10 @@ int hp_get_string_from_buffer(u8 **buffer, u32 *buffer_size, char *dst, u32 dst_
u16 *src = (u16 *)*buffer;
u16 src_size;
+ char utf8_buf[MAX_BUFF_SIZE];
u16 orig_size;
- u16 size;
- int i;
- int conv_dst_size;
+ int utf8_len;
+ int escaped_len;
if (*buffer_size < sizeof(u16))
return -EINVAL;
@@ -79,56 +80,22 @@ int hp_get_string_from_buffer(u8 **buffer, u32 *buffer_size, char *dst, u32 dst_
src++;
/* size value in u16 chars */
orig_size = src_size / sizeof(u16);
- size = orig_size;
-
- for (i = 0; i < orig_size; i++)
- if (src[i] == '\\' ||
- src[i] == '\r' ||
- src[i] == '\n' ||
- src[i] == '\t')
- size++;
- /*
- * Conversion is limited to destination string max number of
- * bytes.
- */
- conv_dst_size = size;
- if (size >= dst_size)
- conv_dst_size = dst_size - 1;
+ utf8_len = utf16s_to_utf8s(src, orig_size, UTF16_HOST_ENDIAN,
+ utf8_buf, sizeof(utf8_buf));
- /*
- * convert from UTF-16 unicode to ASCII
- */
- utf16s_to_utf8s(src, orig_size, UTF16_HOST_ENDIAN, dst, conv_dst_size);
- dst[conv_dst_size] = 0;
-
- for (i = 0; i < conv_dst_size; i++) {
- if (*src == '\\' ||
- *src == '\r' ||
- *src == '\n' ||
- *src == '\t') {
- dst[i++] = '\\';
- if (i == conv_dst_size)
- break;
- }
-
- if (*src == '\r')
- dst[i] = 'r';
- else if (*src == '\n')
- dst[i] = 'n';
- else if (*src == '\t')
- dst[i] = 't';
- else if (*src == '"')
- dst[i] = '\'';
- else
- dst[i] = *src;
- src++;
- }
+ escaped_len = string_escape_mem(utf8_buf, utf8_len, dst, dst_size - 1,
+ ESCAPE_SPACE | ESCAPE_SPECIAL,
+ "\\\r\n\t");
+ if (escaped_len > dst_size - 1)
+ escaped_len = dst_size - 1;
+ dst[escaped_len] = '\0';
+ strreplace(dst, '"', '\'');
*buffer += sizeof(u16) + src_size;
*buffer_size -= sizeof(u16) + src_size;
- return size;
+ return escaped_len;
}
int hp_get_common_data_from_buffer(u8 **buffer_ptr, u32 *buffer_size,
--
2.55.0
next prev parent reply other threads:[~2026-09-28 20:03 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 20:03 [PATCH v2 0/3] platform/x86: hp-bioscfg: string buffer and password fixes Muhammad Bilal
2026-09-28 20:03 ` [PATCH v2 1/3] platform/x86: hp-bioscfg: fix OOB reads in hp_get_string_from_buffer() Muhammad Bilal
2026-09-28 21:26 ` Andy Shevchenko
2026-09-28 20:03 ` Muhammad Bilal [this message]
2026-09-28 21:32 ` [PATCH v2 2/3] platform/x86: hp-bioscfg: fix non-ASCII truncation " Andy Shevchenko
2026-09-28 20:03 ` [PATCH v2 3/3] platform/x86: hp-bioscfg: return -ERANGE from validate_password_input() Muhammad Bilal
2026-09-28 21:34 ` Andy Shevchenko
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=20260928200318.63383-3-meatuni001@gmail.com \
--to=meatuni001@gmail.com \
--cc=andy.shevchenko@gmail.com \
--cc=hdegoede@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jorge.lopez2@hp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.