diff --git a/include/boot/linux_layout.h b/include/boot/linux_layout.h index 5ed2e476..f8b6563c 100644 --- a/include/boot/linux_layout.h +++ b/include/boot/linux_layout.h @@ -23,6 +23,7 @@ #define INITRD_SIZE _AC(0x10410, UL) #define OLDMEM_BASE _AC(0x10418, UL) #define OLDMEM_SIZE _AC(0x10420, UL) +#define MAX_COMMAND_LINE_SIZE _AC(0x10430, UL) #define COMMAND_LINE _AC(0x10480, UL) /* Parameter sizes */ diff --git a/zipl/boot/stage3.c b/zipl/boot/stage3.c index 7372fd64..428cc28c 100644 --- a/zipl/boot/stage3.c +++ b/zipl/boot/stage3.c @@ -232,7 +232,8 @@ static void parse_envblk(struct env_hash_entry *items, * CMDL_LEN: length of the command line to be processed * BUCKETS: hash table of pairs (NAME, VALUE) */ -void process_parm_line(struct env_hash_entry **buckets, unsigned int cmdl_len) +void process_parm_line(struct env_hash_entry **buckets, unsigned int cmdl_len, + unsigned int max_len) { struct env_hash_entry *item; char empty_str = 0; @@ -282,7 +283,7 @@ void process_parm_line(struct env_hash_entry **buckets, unsigned int cmdl_len) */ len = strlen(val); - if (cmdl_len + len - (end - start + 1) >= LEGACY_COMMAND_LINE_SIZE) + if (cmdl_len + len - (end - start + 1) >= max_len) /* VALUE doesn't fit */ break; /* @@ -306,7 +307,7 @@ void process_parm_line(struct env_hash_entry **buckets, unsigned int cmdl_len) /** * LEN: length of the command line to be processed */ -static void handle_environment(unsigned int len) +static void handle_environment(unsigned int len, unsigned int max_len) { struct env_hash_entry *buckets[STR_HASH_SIZE]; struct env_hash_entry *items; @@ -326,7 +327,7 @@ static void handle_environment(unsigned int len) * find environment variables in the command line and * replace them with their values as found in the hash table */ - process_parm_line(buckets, len); + process_parm_line(buckets, len, max_len); free_page((unsigned long)items); } @@ -350,14 +351,18 @@ static void setup_cmdline(void) char *cextra = (char *)COMMAND_LINE_EXTRA; char *cmdline = (char *)COMMAND_LINE; unsigned int cmdline_len = 0; + unsigned int max_cmdline_len = *(unsigned long *)MAX_COMMAND_LINE_SIZE; + + if (!max_cmdline_len) + max_cmdline_len = LEGACY_COMMAND_LINE_SIZE; /* if valid command line is given, copy it into new kernel space */ if (_stage3_parms.parm_addr != UNSPECIFIED_ADDRESS) { strlcpy(cmdline, (void *)(unsigned long *)_stage3_parms.parm_addr, - LEGACY_COMMAND_LINE_SIZE); + max_cmdline_len); } /* determine length of original parm line */ - cmdline_len = MIN(strlen(cmdline), LEGACY_COMMAND_LINE_SIZE - 1); + cmdline_len = MIN((unsigned int)strlen(cmdline), max_cmdline_len - 1); /* convert extra parameter to ascii */ if (!_stage3_parms.extra_parm || !*cextra) @@ -374,15 +379,15 @@ static void setup_cmdline(void) * else append */ if (*cextra == 0x3d) { - strlcpy(cmdline, cextra+1, LEGACY_COMMAND_LINE_SIZE); - } else if (*cextra && cmdline_len + 1 <= LEGACY_COMMAND_LINE_SIZE - 1) { + strlcpy(cmdline, cextra+1, max_cmdline_len); + } else if (*cextra && cmdline_len + 1 <= max_cmdline_len - 1) { /* add blank */ cmdline[cmdline_len++] = 0x20; - strlcpy(cmdline + cmdline_len, cextra, LEGACY_COMMAND_LINE_SIZE - cmdline_len); + strlcpy(cmdline + cmdline_len, cextra, max_cmdline_len - cmdline_len); } noextra: - handle_environment(strlen(cmdline)); + handle_environment(strlen(cmdline), max_cmdline_len); } void start(void) diff --git a/zipl/boot/tape0.S b/zipl/boot/tape0.S index e4f04a39..c42d3b91 100644 --- a/zipl/boot/tape0.S +++ b/zipl/boot/tape0.S @@ -249,31 +249,35 @@ iplstart: clc 0(3,%r4),.L_eof # if it is EOFx bz .Lagain1 # skip dateset trailer - chi %r2,LEGACY_COMMAND_LINE_SIZE-1 # truncate if line too long + lt %r3,MAX_COMMAND_LINE_SIZE-PARMAREA+4(%r12) + jnz 0f + lhi %r3,LEGACY_COMMAND_LINE_SIZE +0: cr %r2,%r3 # truncate if line too long bnh .Lnotrunc - la %r2,LEGACY_COMMAND_LINE_SIZE-1 + lr %r2,%r3 .Lnotrunc: - la %r5,0(%r4,%r2) # search for EBCDIC chars - lr %r3,%r2 + ahi %r5,-1 + lr %r6,%r2 .Lidebc: tm 0(%r5),0x80 # high order bit set ? bo .Ldocv # yes -> convert from EBCDIC ahi %r5,-1 - bct %r3,.Lidebc + bct %r6,.Lidebc b .Lnocv .Ldocv: - la %r3,_ebcasc - tr 0(256,%r4),0(%r3) # convert parameters to ascii - tr 256(256,%r4),0(%r3) - tr 512(256,%r4),0(%r3) - tr 768(127,%r4),0(%r3) + lr %r6,%r2 + la %r5,_ebcasc +0: tr 0(1,%r4),0(%r5) + ahi %r4,1 + brct %r6,0b + l %r4,_parm_addr+4 .Lnocv: - la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line - mvc 0(256,%r3),0(%r4) - mvc 256(256,%r3),256(%r4) - mvc 512(256,%r3),512(%r4) - mvc 768(127,%r3),768(%r4) + lr %r5,%r2 + ahi %r5,-1 + la %r6,COMMAND_LINE-PARMAREA(%r12) + lr %r7,%r2 + mvcl %r6,%r4 slr %r0,%r0 b .Lcntlp .Ldelspc: