ksh: Memory/Segmentation fault for Justified Strings (-L/R/Z)
On Intel 64bit Linux/macOS, I encounter memory or segmentation faults when attempting to create or apply justification to strings with field width of large sizes. These faults also occur even if the justification is applied successfully upon variable assignment. However on an ARM 32bit Ubuntu machine, I can successfully create a string with an assignment up to its maximum allowable field width of 32767 aka (1<<15)-1 and these faults do not occur in my limited testing. But attempting to create the same assignment on a Ubuntu/macOS 64bit platform fails with a memory/segmentation faults. The Ubuntu almost always crashes out using (1<<15)-1 field width but the macOS may allow me to create up to (1<<24). All fail using (1<<30)–be warned that is requesting roughly 1GB of memory. To my knowledge, the maximum allowed fidth width on 64bit OSes should be (1<<31)-1 as 1<<31 makes the int32 size variable become negative in which case the negative field size error occurs.
ARM 32bit Ubuntu
$ typeset -L $((1<<15)) s=h
arch/linux.arm/bin/ksh: typeset: option argument cannot be greater than 32767
$ typeset -L $(((1<<15)-1)) s=h
$ typeset +p s
typeset -L 32767 s
$
Ubuntu 64bit
$ arch/linux.i386-64/bin/ksh
$ typeset -L $(((1<<15)-1)) s=h
Segmentation fault (core dumped)
macOS
$ typeset -L $(((1<<15)-1)) s=h
$ typeset +p s
typeset -L 32767 s
$ typeset -L $(((1<<16)-1)) s=h
$ typeset +p s
typeset -L 65535 s
$ typeset -L $(((1<<17)-1)) s=h
$ typeset +p s
typeset -L 131071 s
$ typeset -L $(((1<<18)-1)) s=h
Memory fault
I found the following lines to be suspect as the length of size requested may be more then 7 greater than the original length of the value of the variable. https://github.com/ksh93/ksh/blob/6697edba1c302c4bdd0796945158decc825b5bd5/src/cmd/ksh93/sh/name.c#L2995-L3000
So, I altered the 1 line malloc code to the following with better results but memory crashes still happen when attempting to alter the variable’s value with a subsequent statement.
n=strlen(sp);
cp = (char*)malloc((n >= (unsigned)size ? n : (unsigned)size) + 1);
Not really sure why the authors added 8 instead of 1 to the length but during my testing it did not matter when the length was large enough to fit the request. I can only guess that is was some small attempt to provide a little buffer or room for something. As I see it, it is a waste of memory. And as such, so is selecting the larger of the two lenghs (n or size) as we could be shrinking the variable’s length. See below for my updated code to hopefully properly handle the initial memory allocation for field size.
n=strlen(sp);
if (size==0 || (newatts&(NV_INTEGER|NV_BINARY)))
{ // allocate to match existing value for numerics and auto length assignment for -L/R/Z
cp = (char*)malloc(n + 1);
strcpy(cp, sp);
}
else if(size>=n)
{ // growing string
cp = (char*)malloc((unsigned)size + 1);
strcpy(cp, sp);
}
else
{ // shrinking string
cp = (char*)malloc((unsigned)size + 1);
if(newatts&NV_RJUST)
strncpy(cp, (n-size+sp), size);
else
{ //NV_LJUST and the rest
if(newatts&NV_ZFILL) // Skip over leading 0s
while(*sp=='0') sp++;
strncpy(cp, sp, size);
}
}
By using the above sizing code, I can fully create and reassign variables at will using the full typeset command with variable value assignment. Still, if I attempt to just do a plain value assignment to the variable afterwards, ksh crashes. If however, I use a typeset statement to alter the justification attributes to a small number (typeset -L 4 s
) then make a s=abc
statement; it works.
There be more gremlins.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 31
Commits related to this issue
- Revert 0e4c4d61 ("Fix minor typeset attribute regressions") This commit introduced the following bug, which is worse than the one that commit fixed: it became impossible to alter the size of an exist... — committed to ksh93/ksh by McDutchie 3 years ago
- Fix multiple buffer overflows with justified strings (-L/-R/-Z) ksh crashed in various different and operating system-dependent ways when attempting to create or apply justification strings using typ... — committed to ksh93/ksh by McDutchie 3 years ago
- Fix multiple buffer overflows with justified strings (-L/-R/-Z) ksh crashed in various different and operating system-dependent ways when attempting to create or apply justification strings using typ... — committed to ksh93/ksh by McDutchie 3 years ago
- Fix segmentation fault for justified strings #142, part 2 Additional adjustments to previous commit bdb9974 to correct crashes when the max size of a justified string is requested. This commit correct... — committed to hyenias/ksh by hyenias 3 years ago
- Fix incorrect typeset -L/-R/-Z on input with spaces (re: bdb99741) The typeset output for -L/-R/-Z seems to be wrong when the input has leading/trailing spaces. This started occurring after the dynam... — committed to ksh93/ksh by McDutchie 2 years ago
- Fix incorrect typeset -L/-R/-Z on input with spaces (re: bdb99741) The typeset output for -L/-R/-Z seems to be wrong when the input has leading/trailing spaces. This started occurring after the dynam... — committed to ksh93/ksh by McDutchie 2 years ago
I can’t figure out a fix that works, so I’ll just revert 0e4c4d6 for now, as the bug it introduced is much worse than the one it fixed. I’ll add your reproducer as a regression test. I hope we’ll manage to find a fix for the TODOs reintroduced by the revert sometime, but it’s not a high priority.
Yes, I am now able to make an assignment without it crashing by using that diff above.