* [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
@ 2026-08-25 15:08 Ilya Leoshkevich
2026-08-25 15:20 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Ilya Leoshkevich @ 2026-08-25 15:08 UTC (permalink / raw)
To: Heiko Carstens, Vasily Gorbik, Alexander Gordeev
Cc: linux-s390, linux-kernel, Ilya Leoshkevich
Users may accidentally add multi-byte UTF-8 characters to zipl.conf
parmline, for example, by copying snippets containing non-breaking
spaces (\xC2\xA0) from web pages.
The kernel will then interpret the entire command line as EBCDIC,
making it unusable. Distinguish this situation from the legitimate
EBCDIC conversion by looking for non-printable characters and issue
a warning.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
arch/s390/boot/ipl_parm.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 6bc950b92be76..71c0c26d56bba 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -173,12 +173,29 @@ static inline int has_ebcdic_char(const char *str)
return 0;
}
+static inline int has_nonprintable_char(const char *str)
+{
+ int i;
+
+ for (i = 0; str[i]; i++) {
+ unsigned char c = (unsigned char)str[i];
+
+ /* isprint() is Latin-1, and we need ASCII here */
+ if (c < 0x20 || c > 0x7e)
+ return 1;
+ }
+ return 0;
+}
+
void setup_boot_command_line(void)
{
parmarea.command_line[COMMAND_LINE_SIZE - 1] = 0;
/* convert arch command line to ascii if necessary */
- if (has_ebcdic_char(parmarea.command_line))
+ if (has_ebcdic_char(parmarea.command_line)) {
EBCASC(parmarea.command_line, COMMAND_LINE_SIZE);
+ if (has_nonprintable_char(parmarea.command_line))
+ boot_warn("Kernel command line was treated as EBCDIC, but contains non-printable characters\n");
+ }
/* copy arch command line */
strscpy(early_command_line, strim(parmarea.command_line));
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-25 15:08 [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters Ilya Leoshkevich
@ 2026-08-25 15:20 ` sashiko-bot
2026-08-26 9:29 ` Heiko Carstens
2026-08-26 13:51 ` David Laight
2 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-25 15:20 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Heiko Carstens, Vasily Gorbik, linux-s390, Alexander Gordeev,
Christian Borntraeger
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Integer underflow in size calculation leads to out-of-bounds write when appending IPL block parameters to a maximum-length kernel command line.
--
--- Patch [1]: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters ---
commit 0d3635825635bf3ebe41f7b2b8024aab279b4f38
Author: Ilya Leoshkevich <iii@linux.ibm.com>
s390: Warn if kernel command line contains non-printable EBCDIC characters
This commit adds a warning if the kernel command line contains non-printable
characters after being converted from EBCDIC to ASCII. This helps detect
accidentally pasted multi-byte UTF-8 sequences in zipl.conf that would
otherwise render the entire command line unusable.
> diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
> index 6bc950b92be76..71c0c26d56bba 100644
> --- a/arch/s390/boot/ipl_parm.c
> +++ b/arch/s390/boot/ipl_parm.c
[ ... ]
> @@ -173,12 +173,29 @@ static inline int has_ebcdic_char(const char *str)
> void setup_boot_command_line(void)
> {
> parmarea.command_line[COMMAND_LINE_SIZE - 1] = 0;
> /* convert arch command line to ascii if necessary */
> - if (has_ebcdic_char(parmarea.command_line))
> + if (has_ebcdic_char(parmarea.command_line)) {
> EBCASC(parmarea.command_line, COMMAND_LINE_SIZE);
> + if (has_nonprintable_char(parmarea.command_line))
> + boot_warn("Kernel command line was treated as EBCDIC, but contains non-printable characters\n");
> + }
> /* copy arch command line */
> strscpy(early_command_line, strim(parmarea.command_line));
>
[Severity: High]
This is a pre-existing issue, but since we are dealing with the bounds of
the command line buffer here, could a maximally long command line trigger
a buffer overflow shortly after this point?
Right after the quoted code, setup_boot_command_line() calls
append_ipl_block_parm(), which calculates the remaining space in the buffer:
arch/s390/boot/ipl_parm.c:append_ipl_block_parm() {
...
len = strlen(early_command_line);
delim = early_command_line + len; /* '\0' character position */
parm = early_command_line + len + 1; /* append right after '\0' */
...
rc = ipl_block_get_ascii_vmparm(
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
...
}
If early_command_line is filled to its maximum capacity (COMMAND_LINE_SIZE - 1),
the remaining size passed to ipl_block_get_ascii_vmparm() evaluates to 0.
Inside ipl_block_get_ascii_vmparm(), the size calculation underflows:
arch/s390/kernel/ipl_vmparm.c:ipl_block_get_ascii_vmparm() {
...
len = min_t(size_t, size - 1, ipb->ccw.vm_parm_len);
memcpy(dest, ipb->ccw.vm_parm, len);
}
Because size is 0 and size_t is unsigned, size - 1 underflows to SIZE_MAX.
This bypasses the bounds check and allows the memcpy() to write out of bounds.
The same underflow pattern appears in ipl_block_get_ascii_scpdata():
arch/s390/boot/ipl_parm.c:ipl_block_get_ascii_scpdata() {
...
count = min(size - 1, scpdata_length(scp_data, scp_data_len));
...
memcpy(dest, scp_data, count);
}
Should there be a check ensuring size > 0 before calling these functions,
or a safeguard within the get_ascii functions to prevent the underflow?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260825150840.537653-1-iii@linux.ibm.com?part=1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-25 15:08 [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters Ilya Leoshkevich
2026-08-25 15:20 ` sashiko-bot
@ 2026-08-26 9:29 ` Heiko Carstens
2026-08-26 14:17 ` Ilya Leoshkevich
2026-08-26 13:51 ` David Laight
2 siblings, 1 reply; 8+ messages in thread
From: Heiko Carstens @ 2026-08-26 9:29 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Vasily Gorbik, Alexander Gordeev, linux-s390, linux-kernel
On Tue, Aug 25, 2026 at 05:08:08PM +0200, Ilya Leoshkevich wrote:
> Users may accidentally add multi-byte UTF-8 characters to zipl.conf
> parmline, for example, by copying snippets containing non-breaking
> spaces (\xC2\xA0) from web pages.
>
> The kernel will then interpret the entire command line as EBCDIC,
> making it unusable. Distinguish this situation from the legitimate
> EBCDIC conversion by looking for non-printable characters and issue
> a warning.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
> arch/s390/boot/ipl_parm.c | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
> index 6bc950b92be76..71c0c26d56bba 100644
> --- a/arch/s390/boot/ipl_parm.c
> +++ b/arch/s390/boot/ipl_parm.c
> @@ -173,12 +173,29 @@ static inline int has_ebcdic_char(const char *str)
> return 0;
> }
>
> +static inline int has_nonprintable_char(const char *str)
> +{
> + int i;
> +
> + for (i = 0; str[i]; i++) {
> + unsigned char c = (unsigned char)str[i];
> +
> + /* isprint() is Latin-1, and we need ASCII here */
> + if (c < 0x20 || c > 0x7e)
> + return 1;
Hm, I guess the comment refers to a different implementation than the
kernel internal one? Since isprint() (see include/linux/ctype.h) is
true for exactly the range you open-coded, as far as I can tell.
Furthermore kernel command line parsing also allows for all sorts of
spaces, tabs, and line feeds (see e.g. next_arg()). So I guess the
above should be changed (and shortened :) ) to something like:
static inline int has_nonprintable_char(const char *str)
{
for (int i = 0; str[i]; i++) {
if (isprint(str[i]) || isspace(str[i]))
return 1;
}
return 0;
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-25 15:08 [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters Ilya Leoshkevich
2026-08-25 15:20 ` sashiko-bot
2026-08-26 9:29 ` Heiko Carstens
@ 2026-08-26 13:51 ` David Laight
2026-08-26 14:08 ` Ilya Leoshkevich
2 siblings, 1 reply; 8+ messages in thread
From: David Laight @ 2026-08-26 13:51 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, linux-s390,
linux-kernel
On Tue, 25 Aug 2026 17:08:08 +0200
Ilya Leoshkevich <iii@linux.ibm.com> wrote:
> Users may accidentally add multi-byte UTF-8 characters to zipl.conf
> parmline, for example, by copying snippets containing non-breaking
> spaces (\xC2\xA0) from web pages.
>
> The kernel will then interpret the entire command line as EBCDIC,
> making it unusable. Distinguish this situation from the legitimate
> EBCDIC conversion by looking for non-printable characters and issue
> a warning.
Would it be better to check for the entire line being printable ebcdic?
All of EBCDIC a-zA-Z0-9 have the 0x80 bit set and most of 0x20..0x7f
are invalid or control characters (or punctuation).
David
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
> arch/s390/boot/ipl_parm.c | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
> index 6bc950b92be76..71c0c26d56bba 100644
> --- a/arch/s390/boot/ipl_parm.c
> +++ b/arch/s390/boot/ipl_parm.c
> @@ -173,12 +173,29 @@ static inline int has_ebcdic_char(const char *str)
> return 0;
> }
>
> +static inline int has_nonprintable_char(const char *str)
> +{
> + int i;
> +
> + for (i = 0; str[i]; i++) {
> + unsigned char c = (unsigned char)str[i];
> +
> + /* isprint() is Latin-1, and we need ASCII here */
> + if (c < 0x20 || c > 0x7e)
> + return 1;
> + }
> + return 0;
> +}
> +
> void setup_boot_command_line(void)
> {
> parmarea.command_line[COMMAND_LINE_SIZE - 1] = 0;
> /* convert arch command line to ascii if necessary */
> - if (has_ebcdic_char(parmarea.command_line))
> + if (has_ebcdic_char(parmarea.command_line)) {
> EBCASC(parmarea.command_line, COMMAND_LINE_SIZE);
> + if (has_nonprintable_char(parmarea.command_line))
> + boot_warn("Kernel command line was treated as EBCDIC, but contains non-printable characters\n");
> + }
> /* copy arch command line */
> strscpy(early_command_line, strim(parmarea.command_line));
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-26 13:51 ` David Laight
@ 2026-08-26 14:08 ` Ilya Leoshkevich
2026-08-27 8:32 ` David Laight
0 siblings, 1 reply; 8+ messages in thread
From: Ilya Leoshkevich @ 2026-08-26 14:08 UTC (permalink / raw)
To: David Laight
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, linux-s390,
linux-kernel
On 8/26/26 15:51, David Laight wrote:
> On Tue, 25 Aug 2026 17:08:08 +0200
> Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
>> Users may accidentally add multi-byte UTF-8 characters to zipl.conf
>> parmline, for example, by copying snippets containing non-breaking
>> spaces (\xC2\xA0) from web pages.
>>
>> The kernel will then interpret the entire command line as EBCDIC,
>> making it unusable. Distinguish this situation from the legitimate
>> EBCDIC conversion by looking for non-printable characters and issue
>> a warning.
>
> Would it be better to check for the entire line being printable ebcdic?
> All of EBCDIC a-zA-Z0-9 have the 0x80 bit set and most of 0x20..0x7f
> are invalid or control characters (or punctuation).
>
> David
I actually started with that, but this required introducing a new
_ctype-like table (unfortunately it's not as simple as checking a
couple ranges), so I decided against that and took a shortcut via
ASCII.
[...]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-26 9:29 ` Heiko Carstens
@ 2026-08-26 14:17 ` Ilya Leoshkevich
0 siblings, 0 replies; 8+ messages in thread
From: Ilya Leoshkevich @ 2026-08-26 14:17 UTC (permalink / raw)
To: Heiko Carstens; +Cc: Vasily Gorbik, Alexander Gordeev, linux-s390, linux-kernel
On 8/26/26 11:29, Heiko Carstens wrote:
> On Tue, Aug 25, 2026 at 05:08:08PM +0200, Ilya Leoshkevich wrote:
>> Users may accidentally add multi-byte UTF-8 characters to zipl.conf
>> parmline, for example, by copying snippets containing non-breaking
>> spaces (\xC2\xA0) from web pages.
>>
>> The kernel will then interpret the entire command line as EBCDIC,
>> making it unusable. Distinguish this situation from the legitimate
>> EBCDIC conversion by looking for non-printable characters and issue
>> a warning.
>>
>> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
>> ---
>> arch/s390/boot/ipl_parm.c | 19 ++++++++++++++++++-
>> 1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
>> index 6bc950b92be76..71c0c26d56bba 100644
>> --- a/arch/s390/boot/ipl_parm.c
>> +++ b/arch/s390/boot/ipl_parm.c
>> @@ -173,12 +173,29 @@ static inline int has_ebcdic_char(const char *str)
>> return 0;
>> }
>>
>> +static inline int has_nonprintable_char(const char *str)
>> +{
>> + int i;
>> +
>> + for (i = 0; str[i]; i++) {
>> + unsigned char c = (unsigned char)str[i];
>> +
>> + /* isprint() is Latin-1, and we need ASCII here */
>> + if (c < 0x20 || c > 0x7e)
>> + return 1;
>
> Hm, I guess the comment refers to a different implementation than the
> kernel internal one? Since isprint() (see include/linux/ctype.h) is
> true for exactly the range you open-coded, as far as I can tell.
Unfortunately isprint() matches some extra ASCII upper-half characters,
e.g.:
const unsigned char _ctype[] = {
[...]
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
> Furthermore kernel command line parsing also allows for all sorts of
> spaces, tabs, and line feeds (see e.g. next_arg()). So I guess the
> above should be changed (and shortened :) ) to something like:
I completely forgot about newlines, thanks!
> static inline int has_nonprintable_char(const char *str)
> {
> for (int i = 0; str[i]; i++) {
> if (isprint(str[i]) || isspace(str[i]))
> return 1;
> }
> return 0;
> }
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-26 14:08 ` Ilya Leoshkevich
@ 2026-08-27 8:32 ` David Laight
2026-08-27 11:15 ` Ilya Leoshkevich
0 siblings, 1 reply; 8+ messages in thread
From: David Laight @ 2026-08-27 8:32 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, linux-s390,
linux-kernel
On Wed, 26 Aug 2026 16:08:50 +0200
Ilya Leoshkevich <iii@linux.ibm.com> wrote:
> On 8/26/26 15:51, David Laight wrote:
> > On Tue, 25 Aug 2026 17:08:08 +0200
> > Ilya Leoshkevich <iii@linux.ibm.com> wrote:
> >
> >> Users may accidentally add multi-byte UTF-8 characters to zipl.conf
> >> parmline, for example, by copying snippets containing non-breaking
> >> spaces (\xC2\xA0) from web pages.
> >>
> >> The kernel will then interpret the entire command line as EBCDIC,
> >> making it unusable. Distinguish this situation from the legitimate
> >> EBCDIC conversion by looking for non-printable characters and issue
> >> a warning.
> >
> > Would it be better to check for the entire line being printable ebcdic?
> > All of EBCDIC a-zA-Z0-9 have the 0x80 bit set and most of 0x20..0x7f
> > are invalid or control characters (or punctuation).
> >
> > David
>
> I actually started with that, but this required introducing a new
> _ctype-like table (unfortunately it's not as simple as checking a
> couple ranges), so I decided against that and took a shortcut via
> ASCII.
Could you get the conversion function to return an error if it found
invalid EBCDIC characters?
If there is a single UTF8 character (eg non-breaking space) you really
want to treat the line as ASCII.
Actually you could count the number of characters with the 0x80 bit set.
If more than 1/2 assume EBCDIC (all of 0-9a-zA-Z have the bit set).
(I didn't realise anyone still used EBCDIC.
I guess the unix implementation(s) use ASCII (otherwise too much code
is broken) but the old IBM OS uses EBCDIC.
I worked for ICL for a while, their old 1900 series (from the early
1970s) used 6bit characters (4 in a 24bit word) that were ACSII codes
32-95. The replacement 2900 series (very late 1970s) used EBCDIC internally
(I guess because IBM used it...) but all the peripherals were ASCII.)
David
>
> [...]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters
2026-08-27 8:32 ` David Laight
@ 2026-08-27 11:15 ` Ilya Leoshkevich
0 siblings, 0 replies; 8+ messages in thread
From: Ilya Leoshkevich @ 2026-08-27 11:15 UTC (permalink / raw)
To: David Laight
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, linux-s390,
linux-kernel
On 8/27/26 10:32, David Laight wrote:
> On Wed, 26 Aug 2026 16:08:50 +0200
> Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
>> On 8/26/26 15:51, David Laight wrote:
>>> On Tue, 25 Aug 2026 17:08:08 +0200
>>> Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>>>
>>>> Users may accidentally add multi-byte UTF-8 characters to zipl.conf
>>>> parmline, for example, by copying snippets containing non-breaking
>>>> spaces (\xC2\xA0) from web pages.
>>>>
>>>> The kernel will then interpret the entire command line as EBCDIC,
>>>> making it unusable. Distinguish this situation from the legitimate
>>>> EBCDIC conversion by looking for non-printable characters and issue
>>>> a warning.
>>>
>>> Would it be better to check for the entire line being printable ebcdic?
>>> All of EBCDIC a-zA-Z0-9 have the 0x80 bit set and most of 0x20..0x7f
>>> are invalid or control characters (or punctuation).
>>>
>>> David
>>
>> I actually started with that, but this required introducing a new
>> _ctype-like table (unfortunately it's not as simple as checking a
>> couple ranges), so I decided against that and took a shortcut via
>> ASCII.
>
> Could you get the conversion function to return an error if it found
> invalid EBCDIC characters?
> If there is a single UTF8 character (eg non-breaking space) you really
> want to treat the line as ASCII.
> Actually you could count the number of characters with the 0x80 bit set.
> If more than 1/2 assume EBCDIC (all of 0-9a-zA-Z have the bit set).
I also considered that, but setting any threshold feels arbitrary and
will probably fail for punctuation-heavy command lines.
I also didn't want to make it a hard fail, because I'm not certain that
I know all uses cases. Perhaps there are people who wants umlauts and
what not? It would be bad to break whatever they are doing.
But at the same time it was very painful to debug the issue, so
I settled for the compromise: add a warning that will be helpful to
99.9% users and will only mildly annoy the 0.1% umlaut users.
I just had an off-list discussion with Heiko and we think about going
with your first proposal for v3: a new _ctype table for EBCDIC for
determining whether characters are printable. The overhead from this is
not bad as I thought it would be.
> (I didn't realise anyone still used EBCDIC.
> I guess the unix implementation(s) use ASCII (otherwise too much code
> is broken) but the old IBM OS uses EBCDIC.
> I worked for ICL for a while, their old 1900 series (from the early
> 1970s) used 6bit characters (4 in a 24bit word) that were ACSII codes
> 32-95. The replacement 2900 series (very late 1970s) used EBCDIC internally
> (I guess because IBM used it...) but all the peripherals were ASCII.)
Linux on s390 still uses it for interfacing with traditional IBM
hypervisors (z/VM and PR/SM), which are very much alive and used today.
> David
>
>>
>> [...]
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-27 11:15 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25 15:08 [PATCH] s390: Warn if kernel command line contains non-printable EBCDIC characters Ilya Leoshkevich
2026-08-25 15:20 ` sashiko-bot
2026-08-26 9:29 ` Heiko Carstens
2026-08-26 14:17 ` Ilya Leoshkevich
2026-08-26 13:51 ` David Laight
2026-08-26 14:08 ` Ilya Leoshkevich
2026-08-27 8:32 ` David Laight
2026-08-27 11:15 ` Ilya Leoshkevich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox