Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

ZSH 2.5.03 BUS ERROR



Zsh team,

I have encountered two segmentation fault/bus error bugs using zsh 2.5.03.
Below I have given complete descriptions of the bugs, as well as the
hacks used to overcome them.

If it matters to you, I'm using a Silicon Graphics Indigo2 and IRIX 5.3.

*** NUMBER 1: EXTREMELY HEINOUS BUG ***

I am uncertain about the specifics involved with reproducing this one.
I have a very straightforward function, "jsetup", that worked fine in
zsh 2.3.1:

jsetup() { jot -f ~/.zshrc; rehash; source ~/.zshrc; }

However, it would bus error in 2.5.03. It turns out that in the function
execcmd() in the file "exec.c", oldlocallist is used to save the contents
of locallist while doing something (I'm not familiar with the code).
However, oldlocallist is a global, and execcmd is called recursively.
Hence, under some circumstances, the value in oldlocallist will get
obliterated, and when doshfunc() tries to zfree locallist, it's
an old pointer. Ideally, oldlocallist should not exist. However, it's
for some reason being used by "builtin.c". What I did to fix this one,
was to define a local variable in execcmd() as "Lklist olist", and used
this instead of oldlocallist. But I still set oldlocallist in case
anything else depended on it. In summary, the hack looks like this:

void execcmd(cmd, input, output, bkg, last1)	/**/
...
    Lklist olist; /*CHB*/
...
		olist = oldlocallist = locallist; /*CHB*/
		locallist = newlist();
...
		locallist = olist; /*CHB*/

Though I don't fully understand what's happening in this general area
of the code, I hope this problem isn't indicative of a more subtle,
underlying conceptual error. If not, then the hack is probably a
sufficient fix.

*** NUMBER 2: MODERATELY HEINOUS BUG ***

To reproduce this one, here are the required steps:

1) set your prompt so that it includes the path (such as prompt='%n@%m:%~> ')
2) cd /tmp
3) mkdir xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4) cd  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
5) go to step 3 and repeat until crash

You may know about this already. The problem is in the file zle_misc.c,
the function putprompt. buf0, buf1, and buf2, which apparently store
the prompt string, are hardcoded to a length of 256. If your prompt
happens to contain more than 256 characters, it will attempt to write
into strange areas of memory. Ideally, the buffers should be
dynamically allocated, or at least stradd and tstradd should check to
make sure they're not going too far.

The quick fix is to up the maximum prompt length, say to MAXPATHLEN*2,
which should be more than sufficient. However, if you perform the same
steps outlined above, it still crashes, apparently due to the path
string having a length greater than MAXPATHLEN. I did not explore
this problem in as much detail. All I can note is that sh handles
this properly (at least on my system):

$ pwd
UX:pwd: ERROR: Pwd too long

In other words, you can have a current directory whose path is
longer than MAXPATHLEN, but you can't do too much beyond that.
(You can't reference that path, but you can work with files in
that current working directory, etc.) Possibly zsh could put
something like "partialpath/..." in the prompt for this situation.

*** NUMBER 3: SMALL MINOR ANNOYANCE ***

When I used buildzsh, everything compiled wonderfully fine, except
that one file complained of there being no prototype for the function
bzero(). Other than that, a sparkling clean, warning-free build, and
you can add IRIX 5.3 to your list of systems where zsh compiles and
works properly. Although, I highly recommend the -O2 option when
compiling & linking, and the -mips2 option if you have an R4000 or
better.

Please respond and let me know if you already know of these, and
what the explanation is on the first one.

Thanks very much,
Chuck Batson
cbatson@xxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author